Suzan Cioc
Suzan Cioc

Reputation: 30097

When window is opened? How to know window is opened without listening window events?

Example below allows window to be showed, hided, disposed and closed (by sending event).

Example showed, that window is opened only once -- on first set visible. Even if a window is disposed, and then showed again, it doesn't undergo "open" event.

Why?

How to know if window is opened without writing a handler and tracking this event?

How to close window so that it undergo open event again on set visible? I.e. how to return window object back to initial state?

Is there any other state or event which can have the required properties?

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);

    }
}

INCREDIBLE

They have a field named Window.state which they even don't initialize (and hence it is zero), then they test it in show() method once and set it to 1 if it is 0. This is the only place state is used and here windowOpened is fired. No code to return state back to 0 anywhere. Moreover, they abandon this state variable in Frame subclass and override it with new one with the same name which hold some new states bitwise, including iconified and similar and forget about opened bit! Cool!

Upvotes: 1

Views: 434

Answers (2)

camickr
camickr

Reputation: 324098

how to return window object back to initial state?

If you want to return variables and components to initial state then I think you need to recreate the window.

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

You can track the closing/opening of a window yourself by doing something like:

    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);

        }
    };

In order for the "Close" button to work you would also need to use:

    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

Upvotes: 2

DotNetRussell
DotNetRussell

Reputation: 9857

You can use this

To find the active Window(be it a frame or a dialog) in a java swing application you can use the following recursive method:

Window getSelectedWindow(Window[] windows) {
    Window result = null;
    for (int i = 0; i < windows.length; i++) {
        Window window = windows[i];
        if (window.isActive()) {
            result = window;
        } else {
            Window[] ownedWindows = window.getOwnedWindows();
            if (ownedWindows != null) {
                result = getSelectedWindow(ownedWindows);
            }
        }
    }
    return result;
}

Reference this article Get current active window's title in Java

Upvotes: 1

Related Questions