JSplitPane resetting divider positions

624 views Asked by At

I've got two JSplitPanes like so

splitPaneRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, console, tabPager);
splitPaneLeft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, infoPanel, splitPaneRight);

splitPaneRight.setResizeWeight(1);

and a method that goes as following and is normally called by a click on a JMenuItem somewhere else:

public void resetLayout()
{
    setSize(1280, 720);
    splitPaneLeft.setDividerLocation(165);
    splitPaneRight.setDividerLocation(830);
}

The interface looks like this (clickable thumbnail):

Main user interface http://bit-stab.com/pictures/dump/MinecraftRemoteAdmin_thumb.jpg

my problem is, whenever I move the position of both divider I have to press that menu item twice before both dividers are back in place. The left one always goes on the first time, and the right on the second.

I have tried changing the order in which the dividers are set (right first, then left). I've tried invalidating, the splitpane of the changed divider, both splitpanes, and both splitpanes plus the UI (extends JFrame)

I've also tried running the method twice when the menu item is pressed. Or checking if getDividerLocation() returns the value that I've just set (which it does for some weird reason).

And last but not least, I've tried combinations of all of the above.

I'm running out of ideas, does there exist a working fix for this?

EDIT: I've created a runnable example (source: http://pastebin.com/VKtN6zJZ), download.jar

1

There are 1 answers

1
camickr On BEST ANSWER
setSize(1280, 720);

Never hardcode sizes like that. Not everybody will be using the same resolution monitor. Maybe use:

frame.setExtendedState(JFrame.MAXIMIZED_BOTH);

or use the Toolkit class to get the window bounds.

The setDividerLocation( double ) method only works on a "realized" frame, which means after you have invoked pack() or setVisible(true) on the frame.

Or, you need to wrap code in a SwingUtilities.invokeLater() to make sure the code executes in the proper order. Something like

SwingUtilities.invokeLater(new Runnable()
{
    public void run()
    {
        splitPaneLeft.setDividerLocation(165);
        splitPaneRight.setDividerLocation(830);
    }
});

If that doesn't work then maybe each statement will need to be done in a separate invokeLater().

Same comment about the divider locations. Don't hard code the values. Maybe you can use the setDividerLocation(.25f) method with allocates size by percentage instead of absolute value.