Search code examples
javaswingjsplitpanepropertychangelistener

JSplitPane propertyChange event in Swing


I am creating a JSplitPane in Java Swing. I am adding PropertyChangeListener with split pane. Property change method is being called when I start to drag the divider but I want to call the method when I drop the divider after dragging , how is it possible?

I am using the following code:

 splitpane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, 
     new PropertyChangeListener() {
      @Override
       public void propertyChange(PropertyChangeEvent pce) {
          JOptionPane.showMessageDialog(null,"Change " +panel.getSize().width);
    }
  });

The above method shows the width of panel before dragging but I want the width after dragging.


Solution

  • The problem is that the divider location is set before the contained components are laid out by the splitpane LayoutManager.

    The solution is quite easy, you can simply wrap your call in a SwingUtilities.invokeLater. An alternative would be to add a ComponentListener to each component contained in the splitpane.

    Small example of code:

    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    import java.util.List;
    
    import javax.swing.JFrame;
    import javax.swing.JProgressBar;
    import javax.swing.JSplitPane;
    import javax.swing.JTextArea;
    import javax.swing.SwingUtilities;
    import javax.swing.SwingWorker;
    import javax.swing.SwingWorker.StateValue;
    import javax.swing.UIManager;
    
    public class TestSplitPaneDragging {
    
        protected void initUI() {
            final JFrame frame = new JFrame();
            frame.setTitle(TestSplitPaneDragging.class.getSimpleName());
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            final JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
            splitPane.setLeftComponent(new JTextArea(24, 48));
            splitPane.setRightComponent(new JTextArea(24, 48));
            splitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
    
                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            System.err.println(splitPane.getLeftComponent().getWidth());
                        }
                    });
                }
            });
            frame.add(splitPane);
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception e) {
                e.printStackTrace();
            }
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new TestSplitPaneDragging().initUI();
                }
            });
        }
    }