Kishan Bheemajiyani
Kishan Bheemajiyani

Reputation: 3439

Stopping Thread on Mouse Hover Event in Swing

I have a desktop application in which I am showing one Frame as notification but I want to stop that thread when mouse hover to the notification frame. Then how could I can do that?

Here current code:

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);

It's showing and Exit in 6 sec.

The code that I am trying.

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);

In this code Notification frame is showing till 6 sec but if user hover that frame then it should be Show till user mouse exit from that Frame.

Upvotes: 1

Views: 316

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347194

Whenever you deal with anything that might affect the UI in some way, you need to be careful and ensure that everything is done within the context of the EDT.

javax.swing.Timer allows you to setup a callback at some time in the future that when triggered, will be called within the context of the 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);
        }

    }

}

Have a look at How to Use Swing Timers for more details

Upvotes: 1

Related Questions