3

JOptionPaneが表示されたときにGUIでチェックを行いたい。他の方法が見つからないので、アプリケーションウィンドウがフォーカスを失うたびに(文字列をチェックするだけで)それらを行うことができます。そのため、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から他のウィンドウに切り替えるたびに「FocusLost」が印刷されるべきではありませんか?また、このメソッドはJOptionPaneが表示されたときにトリガーされますか?

4

3 に答える 3

6

私にとって重要なのは、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についての知識を持たないように、リスナーを使用することです。バインドされたプロパティを持つクラス。それらは完全に分離されています。

于 2012-04-17T21:04:51.013 に答える
5

なぜあなたがしていることをしているのかについては説明しませんが、次の理由で期待どおりに機能していません。

WindowAdapterは便利なクラスなので、1つのリスナーを作成して、複数のタイプのイベントに登録できます。1セットのイベントにのみ登録しました。また、次の方法でフォーカスイベントにも登録する必要があります。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);
于 2012-04-17T23:48:03.530 に答える
2

1)JOptionPane/モーダルJDialogにはモダリティの問題がありますが、すべてのコンテナーに独自の所有者がいる場合はモダリティが有利になる可能性があります。実際の回避策については、知っておく必要があります(これをテストする方法について説明します)

2)敬意を表して、なぜあなたがそれを必要としたのかわかりません。なぜ私がそれについて知る必要があるのか​​、ビジネスルールについてあります、あなたは常に知る必要があります....そしてEDTで行われる場合

于 2012-04-17T21:47:00.477 に答える