如何相对于另一个组件布局组件?

Posted

技术标签:

【中文标题】如何相对于另一个组件布局组件?【英文标题】:How to layout component relative to another component? 【发布时间】:2012-02-10 13:39:41 【问题描述】:

我想要以下布局:

(即jbutton和jlabel放在jpanel上,jbutton居中,jlabel紧随其后。布局应该能够调整大小。编辑:在调整大小期间jbutton和jlabel的大小是恒定的。)

我想到了以下几点:

    使用适当的布局管理器。我一个都不认识。我可以将 jbutton 和 jlabel 添加到另一个 jpanel 并将这个新 jpanel 添加到大 jpanel 的中心,但在这种情况下 jbutton 不会居中。

    编辑:我尝试使用this proposal:(提案已编辑,现在代码正确)

    公共类 MainFrame 扩展 JFrame 
        公共静态无效主要(字符串[]参数)
            新的 MainFrame();
        
    
    
    public MainFrame() 
        setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.weightx = 1;
        add(new JPanel(), c);
        c.gridx = 1;
        c.weightx = 0;
        c.anchor = GridBagConstraints.CENTER;
        add(new JButton("Button"), c);
        c.gridx = 2;
        c.weightx = 1;
        c.anchor = GridBagConstraints.WEST;
        add(new JLabel("Label"), c);
        pack();
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    

    但它会在按钮不居中的地方产生以下输出:

    将 jbutton 和 jlabel 添加到 jpanel。将 ComponentListener 添加到 jpanel 并覆盖 componentResized 那里。被覆盖的方法看起来像:

    public void componentResized(ComponentEvent e) 
        int x = button.getX() + button.getWidth() + 3;
        int y = button.getY();
        label.setLocation(new Point(x, y));
      
    

    布局管理器自动调整大小时将选择JButton的位置,并通过此方法选择jlabel的位置。但是 componentResized 只有在调整大小完成后才会被调用。因此,在调整 jlabel 大小的过程中,布局管理器将定义不需要的位置。

    将 jbutton 添加到内容窗格并将 jlabel 添加到玻璃窗格。但是我在调​​整大小时会遇到与前一种情况相同的问题。

我怎样才能实现这种布局?

【问题讨论】:

【参考方案1】:

看起来您可以使用 3 列的网格袋布局。第一列和第三列的权重必须相同,因此宽度相同。中间的柱子没有重量,所以会坐在中间。我会为你试一试,但我在 iPhone 上打字!高温

查看 cmets,这是我对您的示例代码所做的修改:

public class MainFrame extends JFrame 
    public static void main(String[] args) 
        new MainFrame();
    

    public MainFrame() 
        setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.weightx = 1;
        Component panel = new JPanel();
        panel.setBackground(Color.blue);
        add(panel, c);
        c.gridx = 1;
        c.weightx = 0;
        c.anchor = GridBagConstraints.CENTER;
        add(new JButton("Button"), c);
        c.gridx = 2;
        c.weightx = 1;
        c.anchor = GridBagConstraints.WEST;
        JLabel label = new JLabel("Label");
        add(label, c);

        panel.setPreferredSize(label.getPreferredSize());

        pack();
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    

【讨论】:

不幸的是,它似乎不起作用。第 3 列将比第 1 列宽。查看有问题的编辑 嗯,是的,这很痛苦——也许你可以将你的虚拟面板的preferredSize设置为标签的大小?小技巧,但我相信它有效 - 将编辑我的答案并粘贴一些修改后的代码 意思是说,如果您不想这样做,kleopatra 提到的其他布局管理器之一听起来值得一试。【参考方案2】:

使用支持您需要的 LayoutManager 是可行的方法。高级管理器允许定义大小始终等于宽度/高度的组(列/行)。如果核心管理器不允许这样的语义规范,请找第三方管理器,f.i. BigThree 中的任何一个:MigLayout、FormLayout 或 DesignGridLayout。花在学习上的时间会得到很好的利用:-)

在 MigLayout(目前我个人最喜欢的)中,约束是“sizegroup groupName”或“sg groupName”(如果只有 group,则 groupName 可以为空),f.i.

    JButton button = new JButton("somesize");
    JLabel label = new JLabel("--outer--");
    MigLayout layout = new MigLayout("debug, wrap 3", 
           "[sizegroup, grow][center][sizegroup, grow]");
    JComponent comp = new JPanel(layout);
    // start adding component in second column 
    comp.add(button, "cell 1 0");
    comp.add(label);
    // add something spanning all column in second row for comparison
    comp.add(new JButton("somesize"), "span 3, center");

【讨论】:

以上是关于如何相对于另一个组件布局组件?的主要内容,如果未能解决你的问题,请参考以下文章

android 文本输入框里面如何添加别的组件???

android 相对布局中怎样让组件水平平分父容器 比如2个按钮在一行 怎样让其各占父容器的一半?

Android学习

Android精通:View与ViewGroup,LinearLayout线性布局,RelativeLayout相对布局,ListView列表组件

Android开发重点难点:RelativeLayout(相对布局)详解

android开发中常见布局的注意点