如果光标退出几秒钟,如何隐藏弹出窗口

发布于 2024-12-02 08:28:23 字数 2046 浏览 1 评论 0 原文

我有一个 JDialog 作为弹出窗口,它显示 3 秒并丢弃。
它出现在光标位置,并且仅当光标退出弹出窗口时才必须进行处理。

如果光标进入弹出窗口,计时器将停止并在退出时重新启动。

但我的第一个想法是通过 MouseListener 启动和停止的 dispose-Timer 不适用于某些 JComponent s,这会导致 mouseExited()

我的第二个想法永远不会启动计时器,

public void mouseExited( MouseEvent e ) {
    if(!Popup.this.getBounds().contains( e.getLocationOnScreen() )){
        timer.start();
    }
}

我不想将侦听器添加到弹出窗口中的每个组件。
有没有一种简单的方法可以做到这一点。

例子:

public class Popup 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();
        }
    }
}

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 Popup 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();
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

辞旧 2024-12-09 08:28:23

从 jdk7 开始,您可以使用 JLayer 装饰容器,并在其 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()));

对于旧版本,您可以使用 JXLayer 项目(这是当前开发的)或手动实现全局监听器,如 全局事件监听器

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

晚雾 2024-12-09 08:28:23

仅举个例子 JButton (据我所知,大多数 JComponents) 具有 Model

如果您从 Model 或从预定义中移出的鼠标启动 javax.swing.Timer 矩形

如果鼠标返回到预定义的矩形,则只需重新启动javax.swing.Timer

自从关于JToolTip 这里

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文