WindowListener does not work as expected

前端 未结 3 500
慢半拍i
慢半拍i 2020-12-21 07:49

I want my GUI to make some checks when a JOptionPane appears. Because I can\'t find any other way, I though I can do those each time the application window loses focus(its j

相关标签:
3条回答
  • 2020-12-21 07:58

    I'm not going to go into why you are doing what you are doing, but it is not working as you expect for the following reason:

    WindowAdapter is a convenience class so you can create one listener and register it for multiple types of events. You have only registered it for one set of events, you need to also register it for focus events via: 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);
    
    0 讨论(0)
  • 2020-12-21 08:01

    The key to me is that you want a change in the GUI triggered by a change of a String variable. The best way I see to solve this is to make the String variable a bound property by using PropertyChangeListenerSupport. This way you can have the GUI attach a PropertyChangeListener to the class that holds the String variable and then be notified when it changes allowing you to update the GUI appropriately.

    If you go this route, consider giving the observed class a SwingPropertyChangeSupport field so that the listeners will be notified on the Swing event thread and hopefully avoid any Swing concurrency issues.

    Here's a brief example:

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

    The key to all this in my mind is to use the listener so that the class with the bound property -- the String being listened to -- has no knowledge of the GUI, the listener, and the GUI, likewise has no knowledge of the class with the bound property. They are fully decoupled.

    0 讨论(0)
  • 2020-12-21 08:04

    1) JOptionPane / modal JDialog have got modality issue, but modality could be advantage if all containers have got own owner, for real workaround you need to know (I'll talking about how can I do test that)

    • numbers of Window[], and if isDisplayable(), then you can use follows

    • you can get SwingUtilities#getAccessibleIndexInXxx can returns AccessibleState

    • KeyboardFocusManager (very interesting methods for multi-touch) returns getXxxFocusXxx methods

    • Focus, FocusSubsystem is pretty asynchronous,

    2) Please, with due respect, I don't know why you needed that, for why reasons I need to know about that, there is about business rules, you always need to know ...., and if is done on EDT

    • Focus, FocusSubsystem is pretty asynchronous,
    0 讨论(0)
提交回复
热议问题