首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WindowListener不能按预期工作

WindowListener不能按预期工作
EN

Stack Overflow用户
提问于 2012-04-18 04:49:52
回答 3查看 3.3K关注 0票数 3

我想让我的图形用户界面在出现JOptionPane时进行一些检查。因为我找不到其他的方法,我想我可以在每次应用程序窗口失去焦点时这样做(只是检查一个字符串)。出于这个原因,我在我的JFrame上添加了以下代码:

代码语言:javascript
复制
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切换到其他窗口时,不应该打印“焦点丢失”吗?另外,当显示JOptionPane时,此方法是否会被触发?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-04-18 07:48:04

我不会深入讨论你为什么要做你正在做的事情,但由于以下原因,它并没有像你预期的那样工作:

WindowAdapter是一个方便的类,因此您可以创建一个侦听器并为多种类型的事件注册它。您只为一组事件注册了它,还需要通过:Window.addWindowFocusListener()为焦点事件注册它

代码语言:javascript
复制
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);
票数 5
EN

Stack Overflow用户

发布于 2012-04-18 05:04:51

对我来说,关键是您希望通过更改字符串变量来触发GUI中的更改。我看到的解决这个问题的最好方法是使用PropertyChangeListenerSupport将字符串变量设置为绑定属性。通过这种方式,您可以让图形用户界面将一个PropertyChangeListener附加到包含字符串变量的类,然后在它发生更改时得到通知,从而允许您适当地更新图形用户界面。

如果采用这种方式,请考虑为观察到的类提供一个SwingPropertyChangeSupport字段,这样监听器就会收到有关Swing事件线程的通知,并有望避免出现任何Swing并发问题。

下面是一个简单的例子:

代码语言:javascript
复制
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,同样也不知道具有绑定属性的类。它们是完全解耦的。

票数 6
EN

Stack Overflow用户

发布于 2012-04-18 05:47:00

1) JOptionPane / modal JDialog有通道问题,但是如果所有容器都有自己的所有者,通道可能是优势,对于真正的解决方法,你需要知道(我将讨论如何测试它)

  • Window[] of isDisplayable(),if isDisplayable(),那么你可以使用follows
  • 你可以得到SwingUtilities#getAccessibleIndexInXxx can returns getXxxFocusXxx

(非常有趣的多点触控方法)返回methods

  • Focus, FocusSubsystem是相当异步的,

2)请恕我直言,我不知道您为什么需要它,为什么我需要知道它,有业务规则,您总是需要知道...,如果是在EDT上完成的

  • Focus, FocusSubsystem是非常异步的,
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10198936

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档