Java:PopupMenu暂停了计时器

时间:2017-09-14 18:56:50

标签: java swing timer

嗨, 我正在研究Java中的一个小程序,它有两件事:

  • 一个永远在线 JWindow ,刷新计时器(可以有多个JWindow)
  • TrayIcon ,左键点击 PopupMenu

使用 MouseEventListener 打开PopupMenu,并使用虚拟 Frame 作为父级(需要)。

可运行的例子:

import java.awt.AWTException;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JWindow;
import javax.swing.Timer;

public class TestWindow extends JWindow {

    private int color;

    public static Image createImage(String path) {
        URL imageURL = TestWindow.class.getResource(path);

        if (imageURL == null) {
            System.err.println("Resource not found: " + path);
            return null;
        } else {
            return (new ImageIcon(imageURL)).getImage();
        }
    }

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

    public static void addTrayIcon(){
        if (!SystemTray.isSupported()) {
            System.out.println("SystemTray is not supported");
            System.exit(0);
        }
        TrayIcon trayIcon = new TrayIcon(createImage("/icon.png"));
        trayIcon.setImageAutoSize(true);

        PopupMenu popup = new PopupMenu();
        popup.add(new MenuItem("test"));
        popup.add(new MenuItem("test"));
        popup.add(new MenuItem("test"));

        Frame frame = new Frame("MiniMario");
        frame.setResizable(false);
        frame.setUndecorated(true);
        frame.setType(Frame.Type.UTILITY);
        frame.setAlwaysOnTop(true);
        frame.setAutoRequestFocus(true);
        frame.add(popup);
        frame.setVisible(false);
        frame.addFocusListener(new FocusListener(){
            @Override
            public void focusGained(FocusEvent e) {
                frame.setVisible(false);
            }

            @Override
            public void focusLost(FocusEvent e) {
                frame.setVisible(false);
            }
        });

        trayIcon.addMouseListener(new MouseListener(){

            @Override
            public void mouseClicked(MouseEvent e) {
                if(e.getButton() == MouseEvent.BUTTON3){
                    EventQueue.invokeLater(new Runnable(){
                        @Override
                        public void run() {
                            frame.setVisible(true);
                            popup.show(frame, e.getXOnScreen(), e.getYOnScreen());
                        }
                    });
                }
            }

            @Override
            public void mousePressed(MouseEvent e) {}

            @Override
            public void mouseReleased(MouseEvent e) {}

            @Override
            public void mouseEntered(MouseEvent e) {}

            @Override
            public void mouseExited(MouseEvent e) {}
        });

        final SystemTray tray = SystemTray.getSystemTray();
        try {
            tray.add(trayIcon);
        } catch (AWTException e) {
            System.out.println("TrayIcon could not be added.");
            System.exit(0);
        }
    }

    public TestWindow(){
        this.setBackground(new Color(0,0,0));
        this.setLocationRelativeTo(null);
        this.setSize(100, 100);
        color = 0;
        Timer refresh = new Timer(10,new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                color+=10;
                setAlwaysOnTop(true);
                getContentPane().setBackground(new Color(color%256,color%256,color%256));
            }

        });
        this.setVisible(true);
        refresh.start();
    }

}

这就是:当我打开PopupMenu时,它会冻结JWindow。我发现刷新计时器不再运行了。我已经尝试了以下内容:

  • 放弃永远在线
  • 在runnable中显示PopupMenu(新线程(...)。start / SwingUtilities.invokeLater / EventQueue.invokeLater)
  • 用具有无限循环和Thread.sleep的线程替换JWindow Swing Timer
  • 使用原生TrayIcon.setPopup(最初是这种情况)
  • 使用JWindow或Frame setModalExclusionType(见下文)

在搜索到这种问题后,很少有人与swing模式相关联,但是我没有得到如何在这个设置上使用模态,因为Frame和PopupMenu都没有我在另一篇文章中看到的setModal。我是否必须使用JDialog制作自己的PopupMenu?

(抱歉我的英语不好)

感谢您的时间

编辑:可运行的示例

0 个答案:

没有答案