Mouse Leaves Container

In a Vertical JSplitPane, with the left component initially collapsed, I want to expand the left component whenever the user moves the mouse over the divider, then leave the left component showing and allow the user to interact with its components as long as the mouse remains within the rectangle of the left component. Then, when the mouse leaves the confines of the left component, I want to collapse the left component again. I've gotten the first part working, which expands the left component. But I can't figure out how to determine when the mouse leaves the confines of the left component. If you run the attached code, move the mouse over the divider, and the left component will expand. Then move the mouse over the "This is a Label" label, then move the mouse out of the label and onto the window's title bar. The left component collapses, just as I want. But if you move the mouse over the Tree instead, then out of the tree and into the right component, no mouseExited event is fired. Worse, if you move the mouse over the "This is a Label" and then move it over the Tree, the component collapses. So how can I tell when the mouse actually leaves the confines of the left component. I hope I don't have to add a mouselistener to every child component.

Thanks.

Bill Dennis

package tfg;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.tree.*;

import javax.swing.plaf.basic.BasicSplitPaneUI;

publicclass TestFrameextends JFrame

{

int dividerLocation;

JSplitPane contentSplitPane;

public TestFrame()

{

setSize(640, 480);

setVisible(true);

JPanel movablePanel =new JPanel(new BorderLayout());

final JTabbedPane westPanel =new JTabbedPane(SwingConstants.BOTTOM);

westPanel.add("Root",new JTree());

westPanel.add("Tree",new JTree());

JLabel topLabel =new JLabel("This is a Label");

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

movablePanel.add(westPanel, BorderLayout.CENTER);

movablePanel.add(topLabel, BorderLayout.NORTH);

contentSplitPane =new JSplitPane(SwingConstants.VERTICAL, movablePanel,new JPanel());

contentSplitPane.setOneTouchExpandable(true);

contentSplitPane.setDividerSize(12);

getContentPane().add(contentSplitPane, BorderLayout.CENTER);

dividerLocation = westPanel.getPreferredSize().width + 4;

(((BasicSplitPaneUI)contentSplitPane.getUI()).getDivider()).addMouseListener(new MouseAdapter()

{

publicvoid mouseEntered(MouseEvent me)

{

showNavTree();

}

});

movablePanel.addMouseListener(new MouseAdapter()

{

publicvoid mouseExited(MouseEvent me)

{

System.out.println("Exited: " + me.getX() +"," + me.getY());

hideNavTree();

//-I want to call hideNavTree() whenever the mouse leaves the confines of moveablePanel

}

});

SwingUtilities.invokeLater(new Runnable()

{

publicvoid run()

{

try

{

setVisible(true);

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

contentSplitPane.setDividerLocation(westPanel.getPreferredSize().width + 4);

hideNavTree();

}

catch (Exception e)

{

}

}

});

}

void hideNavTree()

{

int saveDividerLocation = dividerLocation;

contentSplitPane.setDividerLocation(contentSplitPane.getMinimumDividerLocation());

contentSplitPane.setLastDividerLocation(saveDividerLocation);

}

void showNavTree()

{

contentSplitPane.setDividerLocation(dividerLocation);

}

publicstaticvoid main(String args[])

{

try

{

UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel");

}

catch(Exception e)

{

}

new TestFrame();

}

}

[6411 byte] By [wjamesdennisa] at [2007-11-27 7:44:01]
# 1

Determine whether the mouse entered the divider from the left or the right:

(((BasicSplitPaneUI)contentSplitPane.getUI()).getDivider()).addMouseListener(new MouseAdapter()

{

public void mouseEntered(MouseEvent me)

{

int middle = me.getComponent().getSize().width / 2;

if (me.getX() < middle)

hideNavTree();

else

showNavTree();

}

});

Oops, misread the question. The code probably doesn't do what you want.

Message was edited by:

camickr

camickra at 2007-7-12 19:24:38 > top of Java-index,Desktop,Core GUI APIs...
# 2

> So how can I tell when the mouse actually leaves the confines of the

> left component. I hope I don't have to add a mouselistener to every child component.

Well, the problem would be that JTree must use a MouseListener so it intercepts the event, whereas JLabel doesn't use a MouseListener so the event is forwarded to the parent.

You can use an AWTEventListener to listen for MouseEvents generated by any component in the GUI. Then you can compare the source component of the MouseEvent to see if it is a child component of your panel (SwingUtilities.isDescendingFrom(...) should do the trick).

camickra at 2007-7-12 19:24:38 > top of Java-index,Desktop,Core GUI APIs...
# 3

Thanks, I've coded your suggested solution, and it works quite well. I've set it up to watch for Mouse Motion Events, then see if source of the event is a child of the left component or divider. The only thing it doesn't capture is when the mouse pointer leaves the actual JFrame or moves over the window's title bar. I tried playing around with other events to detect those instances, but with no luck. So if the mouse pointer goes out of the window, the left component doesn't collapse. But I think I can life with that.

Thanks again.

wjamesdennisa at 2007-7-12 19:24:38 > top of Java-index,Desktop,Core GUI APIs...