3

I use two JSplitPanes to display some information. One is oriented with a horizontal divider, the other with a vertical divider. The following issue applies to both JSplitPanes.

When I resize my application's main JFrame, the JSplitPanes also resize as they have to occupy a certain percentage of the screen (all JPanels adjust to JFrame resize, behavior set by MigLayout's width and height parameters).

The divider location is important and needs to be constant with the JSplitPane's size. I use setResizeWeight() and setDividerLocation() to achieve this.

The main issue is that on JFrame resize, the divider does not remain at 0.0/ 0% but instead moves to ~5-10%:

Pre-resize -----> Post-resize

I thought this is due to the resizeWeight but I played around with it and there was no change in behavior at all.

Can anybody help me out with this problem? I implemented a ComponentAdapter but short of saving the divider's location in a variable or Preferences XML-key I cannot restore the divider's location on componentResized().

Example code:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;

import net.miginfocom.swing.MigLayout;


public class JSplitPaneTest {

    public static void main(String[] args) {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setMinimumSize(new Dimension(500, 500));

        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new MigLayout());

        JPanel panel1 = new JPanel();
        panel1.setBackground(Color.RED);

        JPanel panel2 = new JPanel();
        panel1.setBackground(Color.GREEN);

        final JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
                panel1, panel2);
        splitPane.setResizeWeight(0.5);
        splitPane.setOpaque(false);
        splitPane.setOneTouchExpandable(true); // does not work on Linux :(
        splitPane.setBorder(null);

        mainPanel.add(splitPane, "w 100%, h 90%, wrap");

        JButton button = new JButton("Set to 0");
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                splitPane.setDividerLocation(0.0);
            }
        });

        mainPanel.add(button, "span");

        frame.add(mainPanel);
        frame.setVisible(true);
    }
}
Robert Martin
  • 1,585
  • 1
  • 13
  • 20
ChrisK
  • 158
  • 1
  • 13

1 Answers1

1

I work on the same project as @ChrisK and took a look at this today. I believe I have fixed this issue, though I have not confirmed the specific symptom triggered by a window resize (since we moved to a statically sized jSplitPane and resizing the window doesn't change the divider position anymore). However, we were having another issue which I believe was caused by the same underlying issue: after moving the divider from position 0, one could no longer manually drag the divider back to position 0. This turned out to be due to the jPanel's minimum size, which was never explicitly set. It turned out that leftComponent.getMinimumSize() was returning (randomly/arbitrarily?) 32, which happened to be the the left-most pixel position that the divider could not be dragged past.

Therefore, what I did was to call:

panel1.setMinimumSize(new Dimension(0,0));

to allow the divider to be dragged all the way to the left/top and:

panel2.setMinimumSize(new Dimension(0,0));

to allow the divider to be dragged all the way to the right/bottom.

I believe that these values were interfering with the divider position upon component resize. I was unable to figure out why the seemingly arbitrary minimum values (32x47) for the panel size were set. Those values are returned by getMinimumSize immediately after constructing the panels. If anyone knows how those are calculated, it might serve to supply a more complete picture of what was happening. If it helps, the width/height of the splitpanes in the dimension of the divider-drag is set statically at 180.

hepcat72
  • 890
  • 4
  • 22
  • Back over a year ago when I did some research on this, I saw [this post](https://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumsize-methods-in-java-swi). It might be an interesting read. – ChrisK Mar 05 '16 at 13:03
  • You should message @kleopatra about this issue since my work around currently is the only solution we know of at the moment. I'll concede it may not be advisable, though I'm not as familiar with Swing as you, but I thought you thought this behavior of the split pane divider was a bug, and if that's the case, then until it's fixed, it seems all you can do is work around it. – hepcat72 Mar 06 '16 at 15:36
  • Do you think we should override getminimumsize instead of call set minimum size as in the second answer? – hepcat72 Mar 06 '16 at 15:51
  • Yes I think overriding it is preferable. I thought it is a bug because it also happens in the short independent example I posted. Or maybe I am missing something about MigLayout. – ChrisK Mar 07 '16 at 15:46