我正在用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”之后立即执行,而不花时间做其他事情,然后应用程序显示在系统托盘中。
答案 0 :(得分:1)
正如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();
}
}