【发布时间】:2026-01-11 07:50:02
【问题描述】:
我查看了ApplicationListener,但那里没有。在 Mac 上,这是该应用程序具有等效焦点的时候。它的菜单在顶部菜单栏中。
另外,如果你知道这一点,你能告诉我我的应用程序如何请求自己散焦吗?
【问题讨论】:
我查看了ApplicationListener,但那里没有。在 Mac 上,这是该应用程序具有等效焦点的时候。它的菜单在顶部菜单栏中。
另外,如果你知道这一点,你能告诉我我的应用程序如何请求自己散焦吗?
【问题讨论】:
WindowListener 或 WindowAdapter 中的 windowActivated() 和 windowDeactivated() 的实现会告诉您何时激活或停用窗口。你不需要ApplicationListener。
附录:虽然在这种情况下不需要,但ApplicationListener 中指定的附加功能的透明实现可以在此example 中找到。
附录:另见How to Write Window Listeners。
附录:我想我明白你的意思了。在使用-Dapple.laf.useScreenMenuBar=true 的示例OSXAdapter 中,菜单会在最后一个窗口(默认为HIDE_ON_CLOSE)关闭时消失。它不是最佳的,但About… 和Preferences 菜单仍保留在应用程序菜单中;选择任一恢复屏幕菜单。另一种可能是修改com.apple.eawt.Application中的停靠菜单。
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.awt.event.WindowListener;
import java.awt.event.WindowStateListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class WindowTest extends JFrame implements ActionListener,
WindowListener, WindowFocusListener, WindowStateListener {
public static final void main(String args[]) throws Exception {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new WindowTest("One");
new WindowTest("Two");
}
});
}
public WindowTest(String name) {
super(name);
this.setName(name);
this.setLayout(new GridLayout(0, 1));
createButton("Back");
createButton("Front");
createButton("Hide");
this.addWindowListener(this);
this.addWindowFocusListener(this);
this.addWindowStateListener(this);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.pack();
this.setVisible(true);
}
private void createButton(String name) {
JButton b = new JButton(name);
this.add(b);
b.addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
String s = e.getActionCommand();
if ("Back".equals(s)) {
this.toBack();
} else if ("Front".equals(s)) {
this.toFront();
} else {
this.setExtendedState(JFrame.ICONIFIED);
}
}
@Override
public void windowOpened(WindowEvent e) {
System.out.println(e);
}
@Override
public void windowClosing(WindowEvent e) {
System.out.println(e);
}
@Override
public void windowClosed(WindowEvent e) {
System.out.println(e);
}
@Override
public void windowIconified(WindowEvent e) {
System.out.println(e);
}
@Override
public void windowDeiconified(WindowEvent e) {
System.out.println(e);
}
@Override
public void windowActivated(WindowEvent e) {
System.out.println(e);
}
@Override
public void windowDeactivated(WindowEvent e) {
System.out.println(e);
}
@Override
public void windowGainedFocus(WindowEvent e) {
System.out.println(e);
}
@Override
public void windowLostFocus(WindowEvent e) {
System.out.println(e);
}
@Override
public void windowStateChanged(WindowEvent e) {
System.out.println(e);
}
}
【讨论】:
frame.setVisible(false) 隐藏了我的窗口,它隐藏了窗口,但不像 Mac 的“隐藏”选项那样起作用。它隐藏了框架,但应用程序保留了焦点。使用frame.toBack() 也不起作用;应用程序保留了焦点,只是窗口被移到了后面。在 Mac 上,当您隐藏应用程序时,该应用程序会隐藏其所有窗口并散焦,并在您为应用程序提供焦点时将它们全部取消隐藏。但是,使用frame.setVisible(),即使您将应用程序散焦并重新获得焦点,它也不会重新出现。
setVisible() 和 Mac 的隐藏功能。问题是,我已经使用了 WindowListener,但是当我给它焦点时窗口不会重新出现,所以它不起作用。你看到我的大问题了吗?这些我都试过了。你有什么其他的建议?我知道您可能没有使用 Mac 的经验,但您过去一直很有帮助。
toBack() 不承诺专注。 AFAIK,切换应用程序是用户的权限。上面的示例显示了两个窗口的 Window 事件,但您也可以浏览本教程。
OSXAdapter 似乎与这个问题无关,示例并没有使用它。我在最前面的窗口中看到 WINDOW_LOST_FOCUS 和 WINDOW_GAINED_FOCUS 事件,因为我在应用程序之间按 alt-tab 或在示例窗口之间按 alt-~。
你能告诉我我的申请如何 可以请求散焦吗?
你可以试试:
frame.toBack();
如果这不起作用,那么您可以图标化您的应用程序,在这种情况下,焦点应该转到前一个应用程序。
frame.setExtendedState(...);
【讨论】:
Java 编程语言独立于平台。与其阅读 Apple 的参考文档,不如使用官方的Java API Reference Documentation。在那里您可以找到JFrame、WindowListener 和WindowAdapter 的文档。您可以使用addWindowListener 函数在JFrame 上注册一个WindowListener。窗口侦听器可用于拦截和处理各种与窗口相关的事件,包括激活/停用(哪个窗口位于顶部)或获得焦点/失去焦点(哪个窗口将接收键盘事件)。如果您提供自己的 WindowListener 并且不想实现每个函数,则 WindowAdapter 对此很有用,因为它实现了 WindowListener 但为每个函数提供了空定义。至于散焦(你的意思),toBack 可以用于此,而toFront 则相反。
编辑
大部分信息已在以前的帖子中提供;但是,我添加了这个来强调:
【讨论】:
ApplicationListener 旨在补充而不是取代核心 UI。有关我的答案中引用的 OSXAdapter 示例,请参阅 README.txt。