当窗口打开?如何知道窗口在没有监听窗口事件的情况下打开?
以下示例允许窗口显示,隐藏,处置和关闭(通过发送事件)。当窗口打开?如何知道窗口在没有监听窗口事件的情况下打开?
示例显示,该窗口仅打开一次 - 第一组可见。即使窗户被丢弃,然后再次显示,它也不会经历“开放”事件。
为什么?
如何知道是否在不编写处理程序并跟踪此事件的情况下打开窗口?
如何关闭窗口,使其在设置可见时再次发生打开事件?即如何将窗口对象返回到初始状态?
是否有任何其他状态或事件可以具有所需的属性?
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
他们有一个字段中指定Window.state
他们甚至不初始化(因此它是零),那么他们测试它在show()
方法一次并将其设置为1
,如果它是0
。这是唯一的地方state
被使用,这里windowOpened
被解雇。没有任何代码将state
返回到0
任何地方。而且,他们在Frame
子类中放弃了这个state
变量,并用新名称覆盖它,并且新名称按住了一些新的状态,包括图标化和类似,并忘记了已打开的位!凉!
您可以使用此
查找活动窗口(不论是一帧或一个对话框),你可以用下面的递归方法的Java Swing应用程序:
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;
}
我可能在这里错过了一些东西,但是这与这个问题有什么关系? – MadProgrammer 2013-03-06 23:49:26
他说,他想知道什么窗口是活动的,而不使用事件处理程序。这将返回活动窗口。 – 2013-03-06 23:51:49
嗯,这是一个小边界线,但我想我可以忍受那个;) – MadProgrammer 2013-03-06 23:53:02
如何将窗口对象返回初始状态?
如果你想返回变量和组件到初始状态,那么我认为你需要重新创建窗口。
如何关闭窗口,使其在设置可见时再次发生打开事件?
你可以自己做类似跟踪窗口的关闭/打开:
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);
通过处理'windowActivated'并从其中调用'windowOpened',你正在使用坏技巧。这并不意味着subsytem会称之为。问题是关于子系统:它为什么要多次关闭并打开一次? – 2013-03-07 13:57:32
P.S. 'setDefaultCloseOperation'方法只是通过在窗口角中按十字按钮来定义当用户“关闭”窗口时发生的事情。 – 2013-03-07 14:17:39
这就是它的设计方式,因为我建议我不认为你可以对此做任何事情。是的,当您点击窗口的关闭按钮时,setDefaultCloseOperation()适用。如果将其保留在“隐藏”位置,那么windowClosed事件将永远不会被触发。我也相信,无论您单击“关闭”菜单项还是“关闭”按钮,逻辑应该与用户单击窗口上的“关闭”按钮相同,这就是为什么您应该适当地设置默认关闭操作。查看我的“关闭应用程序”链接,对您的问题发表评论。 – camickr 2013-03-07 16:38:16
'eventQueue.postEvent(closeEvent);'为什么? – MadProgrammer 2013-03-06 23:40:59
@MadProgrammer,而不是直接调用'setVisible(false)'或'dispose()',这就像用户点击框架的关闭按钮。然后将执行默认关闭操作。 – camickr 2013-03-07 04:13:21
@camickr好吧,我还是抓我头:P – MadProgrammer 2013-03-07 04:45:29