java检测何时创建或关闭任何窗口

时间:2015-12-23 17:55:35

标签: java swing awt

是否可以在创建或关闭应用程序中的任何窗口时收到通知?

目前我正在轮询Window.getWindows(),但我更愿意收到通知。

我有什么:

List<Window> previousWindows = new ArrayList<>();
while (true) {
    List<Window> currentWindows = Arrays.asList(Window.getWindows());

    for (Window window : currentWindows) {
        if (!previousWindows.contains(window)) {
            //window was created
        }
    }

    for (Window window : previousWindows) {
        if (!currentWindows.contains(window)) {
            //window was closed
        }
    }

    previousWindows = currentWindows;
    Thread.sleep(1000);
}

我想要的是什么:

jvm.addWindowListener(this);

@Override
public void windowWasDisplayed(Window w) {
    //window was created
}

@Override
public void windowWasClosed(Window w) {
    //window was closed
}

2 个答案:

答案 0 :(得分:7)

您可以通过窗口Toolkit注册接收任何类型的AWT事件子集的侦听器。从那些你可以选择和处理WindowEvent s窗口打开和关闭,如下所示:

class WindowMonitor implements AWTEventListener {
    public void eventDispatched(AWTEvent event) {
        switch (event.getID()){
            case WindowEvent.WINDOW_OPENED:
                doSomething();
                break;
            case WindowEvent.WINDOW_CLOSED:
                doSomethingElse();
                break;
        }
    }

    // ...
}

class MyClass {

    // alternative 1
    public void registerListener() {
        Toolkit.getDefaultToolkit().addAWTEventListener(new WindowMonitor(),
                AWTEvent.WINDOW_EVENT_MASK);
    }

    // alternative 2
    public void registerListener(Component component) {
        component.getToolkit().addAWTEventListener(new WindowMonitor(),
                AWTEvent.WINDOW_EVENT_MASK);
    }
}

我建议使用替代方案2,其中Component获取Toolkit是您应用程序的主框架(应该只有一个),但替代方案1应该适用于您您必须在不参考任何特定组件的情况下执行此操作(例如,在创建任何组件之前)。

请注意,注册AWTEventListener需要进行安全检查。

答案 1 :(得分:0)

如果您自己创建其他窗口(我假设JFrame s),您可以使用addWindowListener方法。 WindowAdapter抽象类允许您覆盖您感兴趣的事件的方法:

import java.awt.event.*;
import javax.swing.*;

public class MultipleWindows {
    public static void main(String[] arguments) {
        SwingUtilities.invokeLater(() -> new MultipleWindows().createAndShowGui());
    }

    private void createAndShowGui() {
        JFrame frame = new JFrame("Stack Overflow");
        frame.setBounds(100, 100, 800, 600);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        JPanel panel = new JPanel();
        panel.add(new JLabel("Testing multiple windows..."));
        frame.getContentPane().add(panel);

        WindowAdapter windowAdapter = new WindowAdapter() {
            @Override
            public void windowOpened(WindowEvent windowEvent) {
                System.out.println("Window opened: "
                                   + windowEvent.getWindow().getName());
            }

            @Override
            public void windowClosed(WindowEvent windowEvent) {
                System.out.println("Window closed: "
                                   + windowEvent.getWindow().getName());
            }
        };

        for (int windowIndex = 2; windowIndex < 6; windowIndex++) {
            String title = "Window " + windowIndex;
            JFrame extraFrame = new JFrame(title);
            extraFrame.setName(title);
            extraFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            extraFrame.addWindowListener(windowAdapter);
            extraFrame.setVisible(true);
        }

        frame.setVisible(true);
    }
}