How to hide a popup window after some seconds if the cursor exits
I have a JDialog
as a Popup which shows up for 3 seconds and dispose.
If the cursor entered the Popup the timer stops and start again on exit.
But my first idea with a dispose-Timer
that starts and stops via MouseListener
doesn't work with some JComponent
s, which causes a mouseExited()
.
My second idea will never start the Timer
public void mouseExited( MouseEvent e ) {
if(!Popup.this.getBounds().contains( e.getLocationOnScreen() )){
timer.start();
}
}
I don't want to add the Listener to every component in the popup.
Is there an easy way to do that.Example:
public class Po开发者_运维百科pup extends JDialog {
private static final long serialVersionUID = 1337L;
private final Timer timer = new Timer( 3000, new ActionListener() {
@Override
public void actionPerformed( ActionEvent e ) {
Popup.this.dispose();
System.exit( 0 );
}
});
public Popup() {
setBounds( 100, 100, 300, 300 );
addMouseListener( new PopupBehavior() );
getContentPane().setLayout( new BorderLayout() );
getContentPane().add( new JTextArea(), BorderLayout.NORTH );
getContentPane().add( new JSplitPane(0,new JPanel(), new JLabel("2")), BorderLayout.CENTER );
getContentPane().add( new JProgressBar(), BorderLayout.SOUTH );
getContentPane().add( new JLabel("west"), BorderLayout.WEST );
getContentPane().add( new JSpinner(), BorderLayout.EAST );
}
public static void main( String[] args ) {
SwingUtilities.invokeLater( new Runnable() {
@Override
public void run() {
new Popup().setVisible( true );
}
});
}
private class PopupBehavior extends MouseAdapter {
@Override
public void mouseEntered( MouseEvent e ) {
System.out.println("mouseEntered");
timer.stop();
}
@Override
public void mouseExited( MouseEvent e ) {
System.out.println("mouseExited");
timer.start();
}
}
}
As of jdk7 you can decorate your container with a JLayer and stop/start the timer in its processMouseEvent
class DisposingLayerUI extends LayerUI {
@Override
public void installUI(JComponent c) {
super.installUI(c);
JLayer jlayer = (JLayer)c;
jlayer.setLayerEventMask(
AWTEvent.MOUSE_EVENT_MASK
);
}
@Override
public void uninstallUI(JComponent c) {
JLayer jlayer = (JLayer)c;
jlayer.setLayerEventMask(0);
super.uninstallUI(c);
}
@Override
protected void processMouseEvent(MouseEvent e, JLayer l) {
if (e.getID() == MouseEvent.MOUSE_ENTERED) {
timer.stop();
} else if (e.getID() == MouseEvent.MOUSE_EXITED){
timer.start();
}
}
}
// to use in your code, do all init and then decorate the contentPane
...
setContentPane(new JLayer(getContentPane(), new DisposingLayerUI()));
For older versions, you can use the layer from the JXLayer project (it's were the current was developed) or go for a manually implements global listener, as f.i. shown in Global Event Listeners
just for example JButton (and as I know majorities of JComponents
) has Model
if you'll start javax.swing.Timer
from Model or from mousemoved out from pre-defined Rectangle
if mouse returns back to the pre-defined Rectangle
then just restart javax.swing.Timer
excelent sugestion since about JToolTip here
精彩评论