Bumpy
Bumpy

Reputation: 97

jSplitPane Showing and Hiding Left Pane when Mouse over

I'm working on an application that allows me to show and hide split planes. I've read some articles on how to get this but its not what I'm looking for.

here's the code Ive written:

Im currently using netbeans.

private void jSplitPane1MouseEntered(java.awt.event.MouseEvent evt) {                                         
        if(MouseInfo.getPointerInfo().getLocation() == jSplitPane1.getLeftComponent().getLocation()){
           jSplitPane1.setDividerLocation(100);
           System.out.println("Mouse Entered");
       }else{
           jSplitPane1.setDividerLocation(20);
           System.out.println("Mouse Exited");
       }
    } 

I have referred to these posts:

How to make JSplitPane auto expand on mouse hover?

Get Mouse Position

What I want to happen is when I mouse over the left side of the jSplitPane, I would get the divider to extend to 100 as per my first if statement, and when it exists the left side, it contracts back to divider location 20.

Upvotes: 0

Views: 461

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347332

This is really, really tricky.

You could use a MouseListener on the "left" component and monitor the mouseEntered and mouseExited events, but these will also get triggered when when you move into and out of a child component which has a MouseListener of it's own (like a JButton).

Okay, you could use a MouseMotionListener on the JSplitPane and monitor for the mouseMoved event and check where the mouse cursor is, but this goes to hell the moment the components (left/right) get their own MouseListener, as the MouseEvents are no longer delivered to the JSplitPane

So, one of the last options you have is to attach a global AWTListener to the event queue and monitor for events which occur on the JSplitPane itself, for example...

SplitPane

import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Main {

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

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new BorderLayout());

            JSplitPane pane = new JSplitPane();
            pane.setLeftComponent(makePane(Color.RED));
            pane.setRightComponent(makePane(Color.BLUE));

            Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
                @Override
                public void eventDispatched(AWTEvent event) {
                    if (event instanceof MouseEvent) {
                        MouseEvent me = (MouseEvent) event;
                        if (pane.getBounds().contains(me.getPoint())) {
                            System.out.println("Global Motion in the pane...");
                            me = SwingUtilities.convertMouseEvent(me.getComponent(), me, pane);
                            Component left = pane.getLeftComponent();
                            if (left.getBounds().contains(me.getPoint())) {
                                pane.setDividerLocation(100);
                            } else {
                                pane.setDividerLocation(20);
                            }
                        }
                    }
                }
            }, MouseEvent.MOUSE_MOTION_EVENT_MASK);

            // You don't need this, this is to demonstrate
            // that mouse events aren't hitting your component
            // via the listener
            pane.addMouseMotionListener(new MouseAdapter() {
                @Override
                public void mouseMoved(MouseEvent e) {
                    System.out.println("Motion in the pane...");
                    Component left = pane.getLeftComponent();
                    if (left.getBounds().contains(e.getPoint())) {
                        pane.setDividerLocation(100);
                    } else {
                        pane.setDividerLocation(20);
                    }
                }

            });
            pane.setDividerLocation(20);

            add(pane);
        }

        protected JPanel makePane(Color background) {
            JPanel pane = new JPanel() {
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(100, 100);
                }
            };
            pane.setLayout(new GridBagLayout());
            pane.add(new JButton("..."));
            pane.setBackground(background);
            pane.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    System.out.println("...");
                }
            });
            return pane;
        }

    }

}

Upvotes: 2

Related Questions