开发者

How to hide a popup window after some seconds if the cursor exits

开发者 https://www.devze.com 2023-04-01 15:23 出处:网络
I have a JDialog as a Popup which shows up for 3 seconds and dispose. It comes up at cursor position and has to dispose only if the cursor exits the popup.

I have a JDialog as a Popup which shows up for 3 seconds and dispose.

It comes up at cursor position and has to dispose only if the cursor exits the popup.

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 JComponents, 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

0

精彩评论

暂无评论...
验证码 换一张
取 消