How do I avoid (or consume) mouse events while a JSplitPane divider is being dragged?

175 Views Asked by At

I have a JSplitPane with continuous layout turned on. How do I prevent other components from receiving mouse events while the divider is being dragged?

enter image description here

public class Test {
  public static void main(String[] args) throws Exception {
    JButton top = new JButton("top");
    top.setRolloverEnabled(true);
    top.setMinimumSize(new Dimension(100, 100));
    top.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseEntered(MouseEvent e) {
        top.setBackground(Color.green);
      }

      @Override
      public void mouseExited(MouseEvent e) {
        top.setBackground(null);
      }
    });

    JButton bottom = new JButton("bottom");
    bottom.setRolloverEnabled(true);
    bottom.setMinimumSize(new Dimension(100, 100));
    bottom.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseEntered(MouseEvent e) {
        bottom.setBackground(Color.green);
      }

      @Override
      public void mouseExited(MouseEvent e) {
        bottom.setBackground(null);
      }
    });

    JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
    split.setResizeWeight(0.5);
    split.setContinuousLayout(true);
    split.setTopComponent(top);
    split.setBottomComponent(bottom);

    JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setSize(600, 400);
    f.setLocationRelativeTo(null);
    f.getContentPane().setLayout(new BorderLayout());
    f.getContentPane().add(split, BorderLayout.CENTER);
    f.setVisible(true);
  }
}
1

There are 1 best solutions below

2
camickr On

How do I prevent other components from receiving mouse events while the divider is being dragged?

Don't know of a way to turn off all events.

But I'm guessing your real concern is that you don't want the background to change.

If so, then you can add exception logic to the MouseListener to ignore the mouseEntered event when the mouse button is pressed:

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

public class Test {
  public static void main(String[] args) throws Exception {
    JButton top = new JButton("top");
    top.setRolloverEnabled(true);
    top.setMinimumSize(new Dimension(100, 100));
    top.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseEntered(MouseEvent e) {
        if (SwingUtilities.isLeftMouseButton(e)) return;

        top.setBackground(Color.green);
      }

      @Override
      public void mouseExited(MouseEvent e) {
        top.setBackground(null);
      }
    });

    JButton bottom = new JButton("bottom");
    bottom.setRolloverEnabled(true);
    bottom.setMinimumSize(new Dimension(100, 100));
    bottom.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseEntered(MouseEvent e) {
        if (SwingUtilities.isLeftMouseButton(e)) return;

        bottom.setBackground(Color.green);
      }

      @Override
      public void mouseExited(MouseEvent e) {
        bottom.setBackground(null);
      }
    });

    JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
    split.setResizeWeight(0.5);
    split.setContinuousLayout(true);
    split.setTopComponent(top);
    split.setBottomComponent(bottom);

    JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setSize(600, 400);
    f.setLocationRelativeTo(null);
    f.getContentPane().setLayout(new BorderLayout());
    f.getContentPane().add(split, BorderLayout.CENTER);
    f.setVisible(true);
  }
}

Edit:

Maybe you can use your own EventQueue. The EventQueue is responsible for dispatching events to the components. So maybe you can:

  1. Add a MouseListener to the divider
  2. on mousePressed you replace the default EventQueue with your custom EventQueue that will ignore MouseEvents for all components other than the divider.
  3. on mouseRelease you restore the original EventQueue.

Check out Global Event Dispatching for a basic example to get you started.