【问题标题】:Java Swing, restore from system tray not working in LinuxJava Swing,从系统托盘还原在 Linux 中不起作用
【发布时间】:2014-06-19 20:48:24
【问题描述】:

我正在用 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”之后立即触发,无需花时间做其他事情,然后应用程序显示在系统托盘中。

【问题讨论】:

  • 能否请您告诉我们究竟哪一部分在 Linux 上不起作用?
  • 对不起...我忘了包括它。现在我已经添加了更改
  • 这只是一个猜测,但是您是否尝试在取消图标化窗口时执行setState() 之前 setVisible
  • 没有setState语句你试过了吗?
  • 没有它也一样。

标签: java linux swing


【解决方案1】:

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

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

但这没有帮助。

确实有帮助的一件事是将 setVisible(false) 替换为 dispose()。它们的相似之处在于您可以使用 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();
    }
}

【讨论】:

  • 非常感谢!通过使用 dispose() 而不是 setVisible(false),问题已解决
【解决方案2】:

我觉得你搞错了!

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

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

windowDeiconified()

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2020-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多