java - 什么时候开窗?如何在不监听窗口事件的情况下知道窗口已打开?

标签 java swing

下面的示例允许显示、隐藏、处理和关闭窗口(通过发送事件)。

示例显示,该窗口只打开一次——在第一次设置为可见时。即使一个窗口被释放,然后再次显示,它也不会经历“打开”事件。

为什么?

如何在不编写处理程序和跟踪此事件的情况下知道窗口是否打开?

如何关闭窗口,使其在设置可见时再次经历打开事件? IE。如何将窗口对象返回到初始状态?

是否有任何其他状态或事件可以具有所需的属性?

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.AbstractAction;
import javax.swing.AbstractListModel;
import javax.swing.ComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.event.ListDataListener;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Tester_JFrame_Closing_01 {

    private static Logger log = LoggerFactory.getLogger(Tester_JFrame_Closing_01.class);

    protected static Toolkit toolkit = Toolkit.getDefaultToolkit();
    protected static EventQueue eventQueue = toolkit.getSystemEventQueue();

    public static enum CloseOperation {

        DO_NOTHING_ON_CLOSE(JFrame.DO_NOTHING_ON_CLOSE),
        HIDE_ON_CLOSE(JFrame.HIDE_ON_CLOSE),
        DISPOSE_ON_CLOSE(JFrame.DISPOSE_ON_CLOSE),
        EXIT_ON_CLOSE(JFrame.EXIT_ON_CLOSE)
        ;

        public static ComboBoxModel newModel() {

            return new ComboBoxModel() {
                private CloseOperation selected = HIDE_ON_CLOSE;

                @SuppressWarnings("serial")
                private final AbstractListModel core = new AbstractListModel() {

                    @Override
                    public int getSize() {
                        return values().length;
                    }

                    @Override
                    public Object getElementAt(int index) {
                        return values()[index];
                    }

                };

                @Override
                public int getSize() {
                    return core.getSize();
                }

                @Override
                public Object getElementAt(int index) {
                    return core.getElementAt(index);
                }

                @Override
                public void addListDataListener(ListDataListener l) {
                    core.addListDataListener(l);
                }

                @Override
                public void removeListDataListener(ListDataListener l) {
                    core.removeListDataListener(l);
                }

                @Override
                public void setSelectedItem(Object anItem) {
                    selected = (CloseOperation) anItem;
                }

                @Override
                public Object getSelectedItem() {
                    return selected;
                }

            };

        }


        public final int Value;

        private CloseOperation(int value) {
            this.Value = value;
        }

        @Override
        public String toString() {
            switch(this) {
            case DISPOSE_ON_CLOSE:
                return "DISPOSE_ON_CLOSE";
            case HIDE_ON_CLOSE:
                return "HIDE_ON_CLOSE";
            case DO_NOTHING_ON_CLOSE:
                return "DO_NOTHING_ON_CLOSE";
            case EXIT_ON_CLOSE:
                return "EXIT_ON_CLOSE";
            default:
                return "<UNKNOWN>";
            }
        }
    }

    public static void main(String[] args) {

        WindowAdapter windowAdapter = new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent e) {
                log.debug("windowClosed");
            }

            @Override
            public void windowClosing(WindowEvent e) {
                log.debug("windowClosing");
            }

            @Override
            public void windowOpened(WindowEvent e) {
                log.debug("windowOpened");
            }

        };

        final JFrame frame = new JFrame("Controlled window");
        frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        frame.addWindowListener(windowAdapter);

        final WindowEvent closeEvent = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);

        @SuppressWarnings("serial")
        AbstractAction closeAction = new AbstractAction("close") {
            @Override
            public void actionPerformed(ActionEvent e) {
                eventQueue.postEvent(closeEvent);
            }
        };

        @SuppressWarnings("serial")
        AbstractAction hideAction = new AbstractAction("hide") {
            @Override
            public void actionPerformed(ActionEvent e) {
                frame.setVisible(false);
            }
        };

        @SuppressWarnings("serial")
        AbstractAction showAction = new AbstractAction("show") {
            @Override
            public void actionPerformed(ActionEvent e) {
                frame.setVisible(true);
            }
        };

        @SuppressWarnings("serial")
        AbstractAction disposeAction = new AbstractAction("dispose") {

            @Override
            public void actionPerformed(ActionEvent e) {
                frame.dispose();
            }
        };

        JButton closeButton = new JButton(closeAction);
        JButton hideButton = new JButton(hideAction);
        JButton showButton = new JButton(showAction);
        JButton disposeButton = new JButton(disposeAction);

        ComboBoxModel closeOperationModel = CloseOperation.newModel();

        final JComboBox closeOperationCombo = new JComboBox(closeOperationModel);
        closeOperationCombo.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                log.debug("closeOperationCombo.actionPerformed({})", e);
                frame.setDefaultCloseOperation(((CloseOperation)closeOperationCombo.getSelectedItem()).Value);
            }
        });

        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout());

        buttonPanel.add(showButton);
        buttonPanel.add(hideButton);
        buttonPanel.add(disposeButton);
        buttonPanel.add(closeButton);
        buttonPanel.add(closeOperationCombo);

        JFrame controlFrame = new JFrame("Controller window");
        controlFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        controlFrame.setLayout(new FlowLayout());
        controlFrame.add(buttonPanel, BorderLayout.SOUTH);
        controlFrame.pack();
        controlFrame.setLocation(100, 100);
        controlFrame.setVisible(true);

        frame.setBounds(100, 100 + controlFrame.getHeight(), controlFrame.getWidth(), 480);

    }
}

不可思议

他们有一个名为 Window.state 的字段,他们甚至不初始化(因此它为零),然后他们在 show() 方法中测试一次如果为 0,则将其设置为 1。这是唯一使用 state 的地方,这里 windowOpened 被触发。没有代码可以在任何地方将 state 返回到 0。此外,他们在 Frame 子类中放弃了这个 state 变量,并用一个具有相同名称的新变量覆盖它,该变量按位保存一些新状态,包括图标化和类似状态,并忘记打开位!酷!

最佳答案

how to return window object back to initial state?

如果您想将变量和组件返回到初始状态,那么我认为您需要重新创建窗口。

How to close window so that it undergo open event again on set visible?

您可以通过执行以下操作自行跟踪窗口的关闭/打开:

    WindowAdapter windowAdapter = new WindowAdapter()
    {
        boolean closed = false;

        @Override
        public void windowClosed(WindowEvent e) {
            closed = true;
            System.out.println("windowClosed");
        }

        @Override
        public void windowClosing(WindowEvent e) {
            System.out.println("windowClosing");
        }

        @Override
        public void windowOpened(WindowEvent e) {
            System.out.println("windowOpened");
            closed = false;
        }

        @Override
        public void windowActivated(WindowEvent e) {
            System.out.println("windowActivated");

            if (closed)
                windowOpened(e);

        }
    };

为了使“关闭”按钮起作用,您还需要使用:

    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

关于java - 什么时候开窗?如何在不监听窗口事件的情况下知道窗口已打开?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15260285/

相关文章:

java - Java中如何通过LDAP获取AD组的所有成员

java - JTable 的特定行中的 Celleditor (JComboBox)

java - 在 java swing 中对文本应用小型大写字母

java - 如何验证 ScheduledExecutorService 已启动?

java - 如何使用 J2ME 读取数据库?

java - 将对象添加到对象数组中

java - 方法必须调用 Netbeans 中的 super() 错误

java - 隐藏操作栏图标

java - 如何让 JComboBox 创建一个或多个新的 JComboBox

java - 如何将此文本路径发送到 encrypt.actionListener