在Swing中停止鼠标悬停事件上的线程

时间:2014-06-30 07:03:16

标签: java multithreading swing mouseevent event-dispatch-thread

我有一个桌面应用程序,我在其中显示一个Frame作为通知但我想在鼠标悬停到通知帧时停止该线程。那怎么能这样做呢?

目前的代码:

final Notification not = new Notification();
Notification.notification_name.setText(msg[1]);

final ScheduledExecutorService s = Executors.newSingleThreadScheduledExecutor();
s.schedule(new Runnable() {

    public void run() {
        not.setVisible(false); //should be invoked on the EDT
        not.dispose();
    }
}, 6, TimeUnit.SECONDS);

它在6秒内显示并退出。

我正在尝试的代码。

final Notification not = new Notification();
not.addMouseListener(new MouseAdapter() {

    @Override
    public void mouseEntered(MouseEvent e) {
        try {
            super.mouseEntered(e);
            System.out.println("Mouse Entered");
            //s.wait();
            new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        Thread.sleep(10000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();

        } catch (Exception x) {
            x.printStackTrace();
        }
    }

    @Override
    public void mouseExited(MouseEvent e) {
        try {
            super.mouseExited(e);

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
});


final ScheduledExecutorService s = Executors.newSingleThreadScheduledExecutor();
s.schedule(new Runnable() {

    public void run() {
        not.setVisible(false); //should be invoked on the EDT
        not.dispose();
    }
}, 6, TimeUnit.SECONDS);

在此代码中,通知帧显示为6秒,但如果用户将鼠标悬停在该帧上,则应该显示,直到用户鼠标从该帧退出。

1 个答案:

答案 0 :(得分:1)

每当你以某种方式处理可能影响UI的任何事情时,你需要小心并确保一切都在EDT的上下文中完成。

javax.swing.Timer允许您在将来的某个时间设置回调,触发后将在EDT的上下文中调用

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;

public class TimeExample {

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

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

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridBagLayout());
                frame.add(new TestPane());
                frame.setSize(200, 200);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private Timer timer;

        public TestPane() {
            setBorder(new LineBorder(Color.BLACK));

            timer = new Timer(6000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    setBackground(Color.RED);
                }
            });
            timer.setRepeats(false);

            MouseAdapter ma = new MouseAdapter() {

                @Override
                public void mouseEntered(MouseEvent e) {
                    if (timer.isRunning()) {
                        timer.stop();
                        setBackground(Color.BLUE);
                    }
                }

                @Override
                public void mouseExited(MouseEvent e) {
                    if (!timer.isRunning()) {
                        timer.restart();
                        setBackground(UIManager.getColor("Panel.background"));
                    }
                }

                /**
                 * Testing purposes only!!
                 *
                 * @param e
                 */
                @Override
                public void mouseClicked(MouseEvent e) {
                    setBackground(UIManager.getColor("Panel.background"));
                    timer.restart();
                }

            };
            addMouseListener(ma);

            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(100, 100);
        }

    }

}

有关详细信息,请查看How to Use Swing Timers