Search code examples
javaswinglayout-managergridbaglayout

Changing the constraints of a component in a GridBagLayout after they've been added to the frame


I've seen two other posts on stackoverflow about this and in both, the solutions use setConstraints(myComponent, anotherConstraint) which doesn't even come up as an available method when I try to use it in java.

want to change an Inset in a gridbag layout dynamically

Change the component weight dynamically in GridBagLayout

How else could I change the weightx of a component after a button press?

The actual problem is that I have two components at the bottom of the screen and I need to set one of the components to be the max width of the screen after a button press.

enter image description here


Solution

  • I couldn't get setConstraints() to work..

    Then it seems the code was wrong. From the fact the RHS of the red panel neatly aligns with the LHS of the Articuno label I suspect that the grid bag cell containing the red panel does not span more than one column, and currently entirely fills that column.

    There could be other reasons, but short a minimal reproducible example I won't speculate further.

    enter image description here enter image description here

    Here is a simplified example showing how to do it. Note that it was necessary to call revalidate() before the changes could be seen.

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.border.*;
    import java.awt.image.BufferedImage;
    
    public class FullWidthToggle {
    
        private JComponent ui = null;
    
        FullWidthToggle() {
            initUI();
        }
    
        public final void initUI() {
            if (ui != null) {
                return;
            }
    
            GridBagConstraints gbc = new GridBagConstraints();
            GridBagLayout gbl = new GridBagLayout();
            ui = new JPanel(gbl);
            ui.setBorder(new EmptyBorder(4, 4, 4, 4));
    
            BufferedImage image = new BufferedImage(
                    160, 20, BufferedImage.TYPE_INT_RGB);
            gbc.insets = new Insets(5, 5, 5, 5);
            ui.add(new JLabel(new ImageIcon(image)), gbc);
    
            final JCheckBox checkBox = new JCheckBox("Full Width");
            gbc.gridx = 1;
            gbc.anchor = GridBagConstraints.LINE_START;
            ui.add(checkBox, gbc);
    
            final JLabel label = new JLabel("Am I full width?");
            label.setBorder(new LineBorder(Color.RED, 2));
            gbc.gridx = 0;
            gbc.gridy = 1;
            gbc.gridwidth = 2;
            ui.add(label, gbc);
    
            ActionListener actionListener = (ActionEvent e) -> {
                if (checkBox.isSelected()) {
                    gbc.fill = GridBagConstraints.HORIZONTAL;
                } else {
                    gbc.fill = GridBagConstraints.NONE;
                }
                gbl.setConstraints(label, gbc);
                ui.revalidate(); // <- important! 
            };
            checkBox.addActionListener(actionListener);
        }
    
        public JComponent getUI() {
            return ui;
        }
    
        public static void main(String[] args) {
            Runnable r = () -> {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                FullWidthToggle o = new FullWidthToggle();
    
                JFrame f = new JFrame(o.getClass().getSimpleName());
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setLocationByPlatform(true);
    
                f.setContentPane(o.getUI());
                f.pack();
                f.setMinimumSize(f.getSize());
    
                f.setVisible(true);
            };
            SwingUtilities.invokeLater(r);
        }
    }