[英]WindowListener does not work as expected
我希望我的GUI在出现JOptionPane时进行一些检查。 因为我找不到任何其他方式,我虽然每次应用程序窗口失去焦点时都可以执行这些操作(它只是检查字符串)。 出于这个原因,我在我的JFrame上添加了以下代码:
appFrame.addWindowListener(new WindowAdapter() {
@Override
public void windowLostFocus(WindowEvent e) {
System.out.println("Focus Lost");
}
@Override
public void windowClosing(WindowEvent e) {
//some other stuff here that work
}
});
关闭窗口的监听器工作正常。 虽然当JFrame没有集中时没有任何反应。 每次从JFrame切换到其他窗口时,是否应该打印“Focus Lost”? 此外,当显示JOptionPane时是否会触发此方法?
对我而言,关键在于您希望通过更改String变量触发GUI的更改。 我看到解决此问题的最佳方法是使用PropertyChangeListenerSupport使String变量成为绑定属性。 通过这种方式,您可以让GUI将PropertyChangeListener附加到包含String变量的类,然后在更改时通知它,从而允许您适当地更新GUI。
如果你走这条路,考虑给观察的类一个SwingPropertyChangeSupport字段,以便在Swing事件线程上通知监听器,并希望避免任何Swing并发问题。
这是一个简短的例子:
import java.awt.Dimension;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;
public class ShowPropertyChangeSupport {
@SuppressWarnings("serial")
private static void createAndShowGui() {
final MainGUI mainGui = new MainGUI("Title");
final ObservedClass observedClass = new ObservedClass();
observedClass.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent pcEvt) {
if (pcEvt.getPropertyName().equals(ObservedClass.BOUND_PROPERTY)) {
mainGui.setTitle(pcEvt.getNewValue().toString());
}
}
});
mainGui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainGui.pack();
mainGui.setLocationRelativeTo(null);
mainGui.setVisible(true);
int timerDelay = 6000; // every 6 seconds
new Timer(timerDelay, new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
String result = JOptionPane.showInputDialog(mainGui,
"Please enter a String", "Set GUI title", JOptionPane.PLAIN_MESSAGE);
if (result != null) {
observedClass.setBoundProperty(result);
}
}
}){{setInitialDelay(1000);}}.start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
// ** note that I don't like extending JFrame,
// but will do this for sake of example simplicity
class MainGUI extends JFrame {
public MainGUI(String title) {
super(title);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
}
class ObservedClass {
public static final String BOUND_PROPERTY = "bound property";
private String boundProperty = "";
private SwingPropertyChangeSupport spcSupport = new SwingPropertyChangeSupport(
this);
public SwingPropertyChangeSupport getSpcSupport() {
return spcSupport;
}
public void setSpcSupport(SwingPropertyChangeSupport spcSupport) {
this.spcSupport = spcSupport;
}
public String getBoundProperty() {
return boundProperty;
}
public void setBoundProperty(String boundProperty) {
String oldValue = this.boundProperty;
String newValue = boundProperty;
this.boundProperty = newValue;
spcSupport.firePropertyChange(BOUND_PROPERTY, oldValue, newValue);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
spcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
spcSupport.removePropertyChangeListener(listener);
}
}
在我看来,所有这一切的关键是使用监听器,以便具有绑定属性的类 - 被监听的字符串 - 不知道GUI,监听器和GUI,同样不知道具有bound属性的类。 它们完全分离。
我不打算讨论为什么你正在做你正在做的事情,但由于以下原因,它没有像你期望的那样工作:
WindowAdapter
是一个便利类,因此您可以创建一个侦听器并为多种类型的事件注册它。 您只为一组事件注册了它,您还需要通过以下方式注册焦点事件: Window.addWindowFocusListener()
WindowAdapter adapter = new WindowAdapter() {
@Override
public void windowLostFocus(WindowEvent e) {
System.out.println("Focus Lost");
}
@Override
public void windowClosing(WindowEvent e) {
//some other stuff here that work
}
};
appFrame.addWindowListener(adapter);
appFrame.addWindowFocusListener(adapter);
1) JOptionPane
/ modal JDialog
有模态问题,但是如果所有容器都拥有自己的所有者,模态可能是有利的,对于你需要知道的真正的解决方法(我将谈论我该如何测试)
Window[]
,如果isDisplayable()
,则可以使用以下
你可以得到SwingUtilities#getAccessibleIndexInXxx可以返回AccessibleState
KeyboardFocusManager (非常有趣的多点触控方法)返回getXxxFocusXxx方法
Focus,FocusSubsystem非常异步,
2)请充分尊重,我不知道为什么你需要这个,为什么我需要知道的原因,有关于业务规则,你总是需要知道....,如果是在EDT完成
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.