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

标签 java linux swing

我正在用 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”函数:

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 说:

如果框架在 * screen,事件可能是也可能不是 * 生成。

但这没有帮助。

但确实有帮助的一件事是用 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();
    }
}

关于Java Swing,从系统托盘恢复在 Linux 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24315952/

相关文章:

java - RethinkDB 中的映射会针对相同的值多次计算相同的事物吗?

java - 同时显示标签和形状

java - 零如何影响除法的结果

ruby - 使用 Ruby 和 ioctl 以编程方式获取 wifi BSSID

java - JTextArea - 如何在指定偏移处设置文本?

java - JFrame 大小不一致

java - 鼠标悬停 - libgdx

linux - 管道文件的 Bash 内联版本到 bluetoothctl

linux - 将 openssl 0.9.8g 升级到 1.0.1e

java - 正确使用 GridBagLayout 设计面板