Reputation: 30097
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
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
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