如何相对于另一个组件布局组件?
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 大小的过程中,布局管理器将定义不需要的位置。
我怎样才能实现这种布局?
【问题讨论】:
【参考方案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 相对布局中怎样让组件水平平分父容器 比如2个按钮在一行 怎样让其各占父容器的一半?
Android精通:View与ViewGroup,LinearLayout线性布局,RelativeLayout相对布局,ListView列表组件