Reputation: 21096
I want to have the following layout:
(i.e. jbutton and jlabel are placed at jpanel, jbutton is centered and jlabel goes just after it. Layout should be able to resize. Edit: Size of jbutton and jlabel is constant during resizing.)
I thought about the following:
Use appropriate layout manager. I don't know one. I can add jbutton and jlabel to another jpanel and add this new jpanel to center of large jpanel but in that case jbutton won't be centered.
Edit: I tried to use this proposal: (proposal was edited and code is correct now there)
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; 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);
But it produces the following output where button isn't centered:
Add jbutton and jlabel to jpanel. Add ComponentListener
to jpanel and override componentResized
there. Overriden method will look like:
public void componentResized(ComponentEvent e) {
int x = button.getX() + button.getWidth() + 3;
int y = button.getY();
label.setLocation(new Point(x, y));
}
JButton's position will be chosen when resizing automatically by layout manager and jlabel's position by this method. But componentResized
will be invoked only after resizing will complete. So in process of resizing jlabel's position will be defined by layout manager which isn't desired.
How can I achieve this layout?
Upvotes: 0
Views: 1640
Reputation: 3849
Looks like you could use a grid bag layout with 3 columns. The first and third column must have equal weight and therefore will be the same width. The middle column would have no weight so would sit in the middle. I would try it for you but I'm typing on an iPhone! HTH
See comments, here's my edit to your sample code:
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);
}
}
Upvotes: 1
Reputation: 51524
Use a LayoutManager which supports your need is the way to go. Advanced managers allow to define groups (of columns/rows) which are sized to equal width/height always. If core managers don't allow such semantic specifications, go for a third party manager, f.i. any of the BigThree: MigLayout, FormLayout or DesignGridLayout. The time invested in learning will be well spent :-)
In MigLayout (my personal favourite currently), the contraint is "sizegroup groupName" or "sg groupName" (where groupName can be empty if there's only on group), 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");
Upvotes: 1