Kujoen
Kujoen

Reputation: 173

GridBagLayout ignoring weight distribution due to fixed-size JPanel

My UI is split into two panels, lets call them NormalPanel and SpecialPanel. NormalPanel is supposed to take up 25% of horizontal space and SpecialPanel the other 75%. To achieve this i have used

gridBagLayout.columnWeights = new double[] { 1, 3 };

The Result :

Correct Display

The problem i am running into is due to the properties of the specialPanel. It is a JScrollPane containing a fixed-size Panel. This means that whenever the JFrame gets large enough to display the entire fixed-sized Panel it ignores the weight distribution and just displays displays the entire Panel.

The Problem :

Wrong display

How can i stop this from happening ?

The code i used to create the examples :

public MyWindow() {

    GridBagLayout gbLayout = new GridBagLayout();
    // This makes the first row take 100% of the space (We only have one row)
    gbLayout.rowWeights = new double[] { 1 };
    // This makes the second column take up 3 times as much space as the first
    gbLayout.columnWeights = new double[] { 1, 3 };

    GridBagConstraints gbc = new GridBagConstraints();
    gbc.fill = gbc.BOTH;
    gbc.weightx = 1;
    gbc.weighty = 1;

    // Initialize the panels
    normalPanel = new JPanel();
    normalPanel.setBackground(Color.red);
    specialPanel = new SpecialPanel();
    contentPanel = new JPanel(gbLayout);

    gbc.gridx = 0;
    gbc.gridy = 0;
    contentPanel.add(normalPanel, gbc);

    gbc.gridx = 1;
    gbc.gridy = 0;
    contentPanel.add(specialPanel, gbc);

    setContentPane(contentPanel);
    setSize(1280, 720);
    setMinimumSize(new Dimension(1280, 720));
    setVisible(true);
}

public static void main(String[] args) {
    MyWindow window = new MyWindow();
}

/**
 * 
 * This panel has a ScrollPan which is displaying a fixed sized panel.
 *
 */
public class SpecialPanel extends JPanel {

    private JScrollPane scrollPane;
    private JPanel scrollPaneView;
    private JPanel fixedSizePanel;

    public SpecialPanel() {
        fixedSizePanel = new JPanel();
        fixedSizePanel.setPreferredSize(new Dimension(1280,720));
        fixedSizePanel.setMaximumSize(new Dimension(1280,720));
        fixedSizePanel.setMinimumSize(new Dimension(1280,720));
        fixedSizePanel.setBackground(Color.blue);

        scrollPaneView = new JPanel(new FlowLayout());
        scrollPaneView.add(fixedSizePanel);

        scrollPane = new JScrollPane(scrollPaneView);
        scrollPane.setHorizontalScrollBarPolicy(scrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setVerticalScrollBarPolicy(scrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 

        this.setLayout(new GridLayout(1,1));
        this.add(scrollPane);
    }
}

}

Upvotes: 2

Views: 418

Answers (1)

MatheM
MatheM

Reputation: 811

GridBagLayout is... counterintuitive with the way it distributes space. It first "asks" the components what size they want to be and gives them that space, only after that is the remaining space distributed based on the weights.

To work around this extend the panels you are adding to the GridBagLayout and override their getPrefferedSize() method like this.

@Override
public Dimension getPreferredSize() {
    return new Dimension();
}

Now the panels will "tell" the layout that they don't want any space and the layout will therefore distribute all the space based on the weights.

Upvotes: 4

Related Questions