开发者

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).
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜