2016-10-09 2 views
4

私はすべてJOptionPaneメソッドがActionListenersに "干渉"していることに気付きました。 JOptionPaneを開いた後でもActionListenerをアクティブにしておく必要があります。例えばアクションリスナーとのJOptionPaneの干渉を避ける

私はJButtonを持って、私はマウスが押されて登録し、ボタン赤を描きます。解放されると、私はそれを青く描きます。

  • 私がただをクリックした場合、をクリックするとボタンが青色に変わります。 Ok
  • をクリックすると、がクリックされ、ボタンは赤色のままになります。 [OK]を
  • 私はにそれをクリックして、オープンJOptionPaneダイアログに設定した場合、それは私がマウスをリリースしているにもかかわらず、レッドのまま。 OKでない

私は、この特定の動作上の任意のドキュメントを見つけることができていない誰かが正しい方向に私を指すことができますか?

私は本当にJOptionPaneを使用する必要があります。

答えて

4

1つのオプション - 呼び出しをキューに入れ、SwingイベントキューのJOptionPaneを開きます。これにより、モーダルJOptionPaneのオープンが少し遅れて、他のボタンアクションが実行されるようになります。

もう1つの方法は、JOptionPaneからJDialogを抽出し、ノンモダルの方法で呼び出すことです。例えば

import java.awt.Color; 
import java.awt.Component; 
import java.awt.Dialog.ModalityType; 
import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import javax.swing.*; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 

public class TestOptionPane extends JPanel { 
    private static final Color FOREGROUND = Color.RED; 
    private static final Color PRESSED_FG = Color.BLUE; 
    private JButton button1 = new JButton(new Button1Action()); 
    private JButton button2 = new JButton(new Button1Action()); 

    public TestOptionPane() { 
     setPreferredSize(new Dimension(600, 450)); 
     button1.getModel().addChangeListener(new ButtonModelListener(button1)); 
     button1.setForeground(FOREGROUND); 
     add(button1); 
     button2.getModel().addChangeListener(new ButtonModelListener(button2)); 
     button2.setForeground(FOREGROUND); 
     add(button2); 
    } 

    private class Button1Action extends AbstractAction { 
     public Button1Action() { 
      super("Queue JOptionPane on Swing event thread"); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      SwingUtilities.invokeLater(() -> { 
       JOptionPane.showMessageDialog(TestOptionPane.this, "hello"); 
      }); 
     } 
    } 

    private class Button2Action extends AbstractAction { 
     public Button2Action() { 
      super("Show non-modal JOptionPane"); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      SwingUtilities.invokeLater(() -> { 
       Component parentComponent = TestOptionPane.this; 
       JOptionPane optionPane = new JOptionPane("Hello", JOptionPane.PLAIN_MESSAGE); 
       JDialog dialog = optionPane.createDialog(parentComponent, "Fubars Rule!"); 
       dialog.setModalityType(ModalityType.MODELESS); 
       dialog.setLocationRelativeTo(parentComponent); 
       dialog.setVisible(true); 
      }); 
     } 
    } 

    private class ButtonModelListener implements ChangeListener { 
     private JButton button; 

     public ButtonModelListener(JButton button) { 
      this.button = button; 
     } 

     @Override 
     public void stateChanged(ChangeEvent e) { 
      ButtonModel model = (ButtonModel) e.getSource(); 
      if (model.isPressed()) { 
       button.setForeground(PRESSED_FG); 
      } else { 
       button.setForeground(FOREGROUND); 
      } 
     } 

    } 

    private static void createAndShowGui() { 
     JFrame frame = new JFrame("TestOptionPane"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(new TestOptionPane()); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 
} 
+0

私はどのように良いこの回答があるか、どのように迅速にあなたがそれを書いたことで、より感動場合、私は知りません。完璧に動作します、ありがとうございます。 1つの質問:GUIを作成すると、.invokeLater()が呼び出されます。なぜですか?する必要がありますか ? OptionPaneを開くためにそれを呼び出すだけで(.invokeLater)機能するからです。 –

+0

@LoryA:私は両方の**メソッドを表示するように編集されました。最初のものはイベントスレッドにジョイントペインをキューイングし、2番目はoptionpaneを非モーダルダイアログとして表示します。 –

+2

@LoryA:私は、奇妙で予測できないスレッドエラーを防ぐために、SwingイベントスレッドにGUIを作成しようと努力しています。彼らは時々発生し、私はそれらを見た。 –

関連する問題