繁体   English   中英

Java Swing,从系统托盘恢复在 Linux 中不起作用

[英]Java Swing, restore from system tray not working in Linux

我正在 Java 中创建一个应用程序,我希望当您最小化为一个图标时,该应用程序必须“隐藏”在系统托盘中。 我使用的代码是这样的:(代码的重要部分)

myFrame = new JFrame();
myFrame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowIconified(WindowEvent e) {                
                PutTray();
            }

            @Override
            public void windowDeiconified(WindowEvent e) {
                System.out.println("Deiconified");

            }

        });

这是一个“PutTray” function:

private void PutTray()
    {
            try 
            {
                tray.add(trayIcon); // Initialized elsewhere
                myFrame.setVisible(false);

            } catch (AWTException e) {
                System.err.println(e);
            }
    }

要恢复(通过按下图标最小化时弹出菜单中的选项):

MenuItem show = new MenuItem("Show");
            show.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {


                    myFrame.setVisible(true); 
                    myFrame.setState(JFrame.NORMAL);
                    tray.remove(trayIcon);

                }
            });

该代码在 Windows 8 上完美运行,但在 Linux(Kali Linux 甚至 Ubuntu)上不起作用。 为什么 Windows 是而 Linux 不是?

编辑:

在 Linux 上,按下命令显示应用程序后,它会出现一小会儿,然后再次最小化。 基本上是触发事件“windowDeiconified”,并在事件“windowIconified”之后立即触发,无需花时间做其他事情,然后应用程序显示在系统托盘中。

正如Dan Getz所建议的那样,我还认为setVisible和setState的顺序应该颠倒,因为setState的javadoc说:

如果该框在*屏幕上不可见 ,则可能会*或可能不会*生成事件。

但这没有帮助。

确实有所帮助的一件事是用dispose()替换了setVisible(false)。 它们的相似之处在于您可以使用setVisible(true)重新打开已处置的窗口。 您可以在这里阅读有关它的更多信息: JDialog setVisible(false)vs dispose()我将尝试查找一个解释并返回它:)

SSCCE模拟OP问题:

public class Test {
    private JFrame myFrame;
    public Test() {
        myFrame = new JFrame();
        myFrame.setVisible(true);
        myFrame.setSize(300, 300);
        myFrame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowIconified(WindowEvent e) {
                PutTray();
            }
        });
    }
    private void PutTray() {
        myFrame.setVisible(false); //replace with dispose(); and it's ok
        Timer t = new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                myFrame.setVisible(true);
            }
        });
        t.setRepeats(false);
        t.start();
    }
    public static void main(String[] args) {
        new Test();
    }
}

我认为你弄错了!

也许您对去图标化和可见性感到困惑

当我们点击最小化按钮时windowIconified()将被调用

windowDeiconified()

当我们从任务栏而不是系统托盘恢复它时被调用!

为了从系统托盘恢复你需要使用这个

trayIcon.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            window.setVisible(true);
        }
    });

基本上我不认为dispose()setVisible()之间的区别会在这个特定问题上打扰你

不过,我的建议是在这里使用setVisible()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM