简体   繁体   中英

How to layout component relative to another component?

I want to have the following layout:

(ie 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:

  1. 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 { \n    public static void main(String[] args) { \n        new MainFrame(); \n    } \n\n
     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); 
    \n\n } \n} \n

    But it produces the following output where button isn't centered:

  2. 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.

  3. Add jbutton to content pane and jlabel to glass pane. But I'll have the same problem with resizing as in previous case.

How can I achieve this layout?

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);
    }
}

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, fi 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), fi

    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");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM