Java on a Mac: How do I detect when my application receives focus?
I looked through ApplicationListen开发者_StackOverflow中文版er, and they don't have it in there. On a Mac, it's when that application has the equivalent of focus; its menu is in the top menu bar.
Also, if you know this, could you tell me how my application can request to de-focus itself?
Implementations of windowActivated()
and windowDeactivated()
in WindowListener
or WindowAdapter
will tell you when a window is activated or deactivated. You don't need ApplicationListener
for that.
Addendum: Although not required in this case, a transparent implementation of the additional functionality specified in ApplicationListener
may be found in this example.
Addendum: See also How to Write Window Listeners.
Addendum: I think I see what you mean. In the example OSXAdapter
, which uses -Dapple.laf.useScreenMenuBar=true
, the menus disappear when the last window (HIDE_ON_CLOSE
by default) closes. It's less than optimal, but the About…
and Preferences
menus remain in the application menu; choosing either restores the screen menu. Another possibility is to modify the dock menu in 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);
}
}
could you tell me how my application can request to de-focus itself?
You can try:
frame.toBack();
If that doesn't work then you can iconify your application in which case focus should go to the previous application.
frame.setExtendedState(...);
The Java programming language is platform-independent. Rather than reading Apple's reference documentation, you should be using the official Java API Reference Documentation. There you will find documentation for JFrame, WindowListener, and WindowAdapter. You can register a WindowListener on a JFrame, using the addWindowListener function. The window listener may be used to intercept and handle a variety of window-related events including activated/deactived (which window is on top) or gained focus/ lost focus (which window will receive keyboard events). If you are supplying your own WindowListener and don't want to implement every single function, WindowAdapter is useful for that purpose as it implements WindowListener but provides empty definitions for each function. As for defocusing (in the sense that you mean), toBack may be used for that, while toFront does the opposite.
Edit
Most of this information was already given in previous posts; however, I added this to emphasize:
- Java is a platform-independent language.
- Java is a product of Sun Microsystems (now Oracle).
- Consquently, using the official Java API Reference Documentation from Sun makes way more sense than relying on any reference documentation provided by Apple, because anything contained within the official API reference documentation will work on all platforms; whereas, anything from Apple's reference documentation may very well to be specific to Apple's implementation.
- The reference documentation for JFrame from the official, authoritative reference documentation gives all the information necessary for answering the question (hence yet another reason to consult the official API reference documentation, rather than relying on Apple's documentation).
精彩评论