2011-11-26 19 views
5

ItemListenerJOptionPaneを入れたときに、私はJCheckBoxの選択を失った理由を説明できますか(setSelected()で設定)。 これはバグですか?JCheckBoxでsetSelectedが無効になるのはなぜですか?

このプロセスがinvokeLater()で遅れている場合は、setSelected()が期待どおり正しく動作することが不思議です。マックOS X & Ubuntuで

enter image description hereenter image description here

SSCCE

から

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class ComponentEventDemo extends JPanel 
     implements ComponentListener, ItemListener { 

    private static final long serialVersionUID = 1L; 
    private JFrame frame; 
    private JTextArea display; 
    private String newline = "\n"; 
    private JTextField field1; 

    public ComponentEventDemo() { 
     super(new BorderLayout()); 
     display = new JTextArea(10, 25); 
     display.setEditable(false); 
     JPanel panel = new JPanel(new GridLayout(0, 2)); 
     field1 = new JTextField(); 
     field1.setDisabledTextColor(Color.red); 
     JCheckBox checkbox = new JCheckBox("Label visible", true); 
     checkbox.addItemListener(this); 
     panel.add(checkbox); 
     panel.add(field1); 
     panel.addComponentListener(this); 
     JScrollPane scrollPane = new JScrollPane(display); 
     frame = new JFrame("ComponentEventDemo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(scrollPane, BorderLayout.CENTER); 
     frame.add(panel, BorderLayout.SOUTH); 
     frame.addComponentListener(this); 
     frame.setLocation(200, 200); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public void itemStateChanged(ItemEvent evt) { 
     System.out.println("STATE CHANGED!"); 
     if (evt.getStateChange() == ItemEvent.SELECTED) { 
      //javax.swing.SwingUtilities.invokeLater(new Runnable() { 

      //public void run() { 
      int returnVal = JOptionPane.showConfirmDialog(display, 
        "Bla Bla Bla Text"); 
      if (returnVal == JOptionPane.OK_OPTION) { 
       field1.setText("SELECTED - OK btn"); 
      } else if (returnVal == JOptionPane.NO_OPTION) { 
       field1.setText("SELECTED - NO btn"); 
      } else if (returnVal == JOptionPane.CANCEL_OPTION) { 
       field1.setText("SELECTED - Cancel btn"); 
      } else if (returnVal == JOptionPane.CLOSED_OPTION) { 
       field1.setText("SELECTED - Close btn"); 
      } 
      //} 
      //}); 
     } else if (evt.getStateChange() == ItemEvent.DESELECTED) { 
      field1.setText("DESELECTED"); 
     } 
    } 

    protected void displayMessage(String message) { 
     display.append(message + newline); 
     display.setCaretPosition(display.getDocument().getLength()); 
    } 

    public void componentHidden(ComponentEvent e) { 
     displayMessage(e.getComponent().getClass().getName() + " ---> Hidden"); 
    } 

    public void componentMoved(ComponentEvent e) { 
     displayMessage(e.getComponent().getClass().getName() + " ---> Moved"); 
    } 

    public void componentResized(ComponentEvent e) { 
     displayMessage(e.getComponent().getClass().getName() + " ---> Resized "); 
    } 

    public void componentShown(ComponentEvent e) { 
     displayMessage(e.getComponent().getClass().getName() + " ---> Shown"); 

    } 

    public static void main(String[] args) { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 

      public void run() { 
       ComponentEventDemo ced = new ComponentEventDemo(); 
      } 
     }); 
    } 
} 
+1

1 + question。私は以前これを見て、あなたが持っているようにそれを解決しました--JOptionPaneの表示をEDTにキューイングしますが、まだソースコードを掘り下げる時間やエネルギーがないので説明できません。 –

+0

@Hovercraft Eelsの完全な私はJava APIのメソッドの中でこの問題を投稿する前に、すべてが正しく表示される前に、デバッガをデバッグしています。プレーンJCheckBoxとJCheckBox with JOptionPane、ご協力ありがとうございました – mKorbel

答えて

4

Oracle Bug ID:6924233によって確認された既知のバグです。JOptionPaneは、明らかにチェックボックスの値= falseで別のイベントを生成します。

invokeLaterを使用してJOptionPaneをインスタンス化することをお勧めします。

Submitted On 09-MAR-2010 

The change is in the BasicButtonListener - Method focusLost() 

In 1.6.0_18 it is 

     ... 
     ButtonModel model = b.getModel(); 
     model.setPressed(false); 
     model.setArmed(false); 

in 1.6.0_10 it was 

     ... 
     ButtonModel model = b.getModel(); 
     model.setArmed(false); 
     model.setPressed(false); 

(The order of the statements changed) 

And a setPressed(false) with armed==true leads on an ToggleButton like 
the JCheckBox to a change of the selection (see ToggleButtonModel) 
2

私はどんな違いが表示されません:私は、チェックボックスをクリックし、DESELECTED状態からスタートします。すぐにチェック・マークが表示され、続いてオプション・ペインが表示されます。 Runnableの有無にかかわらず同じ結果が得られます。

Windowsの場合、結果は説明されているとおりですが、オプションの枠が前景になるので、チェックマークがわずかにちらつきます。 VirtualBoxのようなエミュレータでは、エフェクトが見やすくなり、処理が遅くなる可能性があります。 Runnableをキューに入れると、通常の操作に戻ります。

+0

申し訳ありませんが、これは本当の回答ではありませんが、バグの検索に役立つかもしれません。 – trashgod

+0

(毎回)私はMAC/Linux上で任意のコードを実行するか、これらのネイティブOSと互換性のあるコードを要求しています – mKorbel

関連する問題