14

I'm trying to set the divider location of a JSplitPane but it seems not to work.

Here's an SSCCE:

import java.awt.Color;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;


public class JSplitProblem extends JFrame {

    public JSplitProblem(){
        JPanel upperPanel = new JPanel();
        upperPanel.setLayout(new BoxLayout(upperPanel, BoxLayout.X_AXIS));

        JPanel leftPanel = new JPanel();

        leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS));
        JPanel red = new JPanel();
        red.setBackground(Color.red);
        leftPanel.add(red);

        JPanel rightPanel = new JPanel();
        rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.Y_AXIS));
        JPanel blue = new JPanel();
        blue.setBackground(Color.blue);
        rightPanel.add(blue);

        upperPanel.add(leftPanel);
        upperPanel.add(rightPanel);
        JPanel bottomPanel = new JPanel();
        bottomPanel.setBackground(Color.black);

        JSplitPane mainSplittedPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, upperPanel,bottomPanel);
        mainSplittedPane.setOneTouchExpandable(true);
        mainSplittedPane.setDividerLocation(0.5);

        this.add(mainSplittedPane);
        this.setSize(800,600);
        this.setResizable(true);
        this.setVisible(true);
    }

    public static void main(String[] args) {
        new JSplitProblem();
    }

}

I would like the black bottom panel to lay on a 50% of the whole area by default. What am I doing wrong?

Heisenbug
  • 38,762
  • 28
  • 132
  • 190
  • 1
    IIRC setDividerLocation with a ratio works only AFTER the splitpane has been made visible in a containment hierarchy. That's probably because the method immediately calculates the actual location in pixels, based on the current size. – jfpoilpret Oct 03 '11 at 09:10
  • @jfpoilpret: yes. I understood that from mKorbel's answer. Otherwise using invoke later won't effect it. Thanks for pointing out anyway. – Heisenbug Oct 03 '11 at 09:12

4 Answers4

16

If you want both halves of the split pane to share in the split pane's extra or removed space, set the resize weight to 0.5: (Tutorial)

JSplitPane mainSplittedPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, upperPanel,bottomPanel);
mainSplittedPane.setOneTouchExpandable(true);
mainSplittedPane.setResizeWeight(0.5);                            
KV Prajapati
  • 93,659
  • 19
  • 148
  • 186
10

nothing complicated in this case, with rules

1) PrefferedSize must returns Childs not as I wrong to set in my case too :-), then my answer isn't @kleopatra resist too

2) put everything about rezize, size, whatever for JSplitPane into invokeLater() .

enter image description here .

import java.awt.*;
import javax.swing.*;

public class JSplitProblem extends JFrame {

    private static final long serialVersionUID = 1L;
    private JSplitPane mainSplittedPane;

    public JSplitProblem() {
        JPanel upperPanel = new JPanel();
        upperPanel.setLayout(new BoxLayout(upperPanel, BoxLayout.X_AXIS));
        JPanel leftPanel = new JPanel();
        leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS));
        JPanel red = new JPanel();
        red.setBackground(Color.red);
        leftPanel.add(red);
        JPanel rightPanel = new JPanel();
        rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.Y_AXIS));
        JPanel blue = new JPanel();
        blue.setBackground(Color.blue);
        rightPanel.add(blue);
        upperPanel.add(leftPanel);
        upperPanel.add(rightPanel);
        JPanel bottomPanel = new JPanel();
        bottomPanel.setBackground(Color.black);

        mainSplittedPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, upperPanel, bottomPanel);
        mainSplittedPane.setOneTouchExpandable(true);
        mainSplittedPane.setDividerLocation(0.5);

        add(mainSplittedPane);
        setPreferredSize(new Dimension(400, 300));
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setResizable(true);
        setVisible(true);
        pack();
        restoreDefaults();
    }

    private void restoreDefaults() {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                mainSplittedPane.setDividerLocation(mainSplittedPane.getSize().height /2);
                //mainSplittedPane.setDividerLocation(mainSplittedPane.getSize().width /2);
            }
        });
    }

    public static void main(String[] args) {
        JSplitProblem jSplitProblem = new JSplitProblem();
    }
}
Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • oh..thanks for the answer but I still got some problem (and I have been a bit imprecise while asking the question). The point is, your solution works only if I don't resize the frame. If I manually resize the frame proportion isn't mantained. Is there a way to keep the diveder location always at a certain value? +1 anyway – Heisenbug Oct 02 '11 at 13:36
  • yes very simple, you have to add WindowListener, override proper ResizeEvent(s), but notice calling the `restoreDefaults()` to delay that with `java.swing.Timer`, because you never ever don't know is resize ends, becasue if resize continue, then just to restart the `Timer` :-) – mKorbel Oct 02 '11 at 13:40
  • +1 the key is that the setDividerLocation(double) only works on a visible GUI since it can't calculate the size ratio until the split pane actually has a size. In the simple example there is no need to use invokeLater. Just invoke the setDividerLocation(...) method after the pack(), setVisible(true). If you want to use the restoreDefaults() method then you should invoke it when you create the splitpane. – camickr Oct 02 '11 at 15:26
  • Could you please clarify what this means: "PrefferedSize must returns Childs not as I wrong to set in my case too :-), then my answer isn't @kleopatra resist too" – Matthias Braun Oct 02 '18 at 10:06
3

I'm not sure, but I think you should try to pack() your frame. And if that doesn't work, try to reset the divider location after you packed the frame.

Martijn Courteaux
  • 67,591
  • 47
  • 198
  • 287
1

Just add the code below, and that will be fairly enough.

mainSplittedPane.setResizeWeight(0.5);
StarCrafter
  • 451
  • 5
  • 12