2011-11-26 4 views
5

ItemListenerJOptionPane을 넣었을 때 JCheckBox에 대한 선택을 잃어버린 이유를 설명 할 사람이 있습니까 (setSelected()에 의해 설정 됨). 이것은 버그입니까?JCheckBox에서 setSelected가 적용되지 않는 이유는 무엇입니까?

궁금한 점이 있다면이 프로세스가 invokeLater()으로 지연되면 setSelected()이 예상대로 올바르게 작동합니다. 맥 OS X & 우분투에 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 + 질문. 이전에 JOptionPane의 디스플레이를 EDT에 대기시킴으로써이 문제를 해결했지만 해결할 수는 있지만 아직 소스 코드를 들여다 볼 시간이나 에너지가 없었기 때문에 설명 할 수 없습니다. –

+0

@ Hovercraft 전체 뱀장어 나는이 질문을 게시하기 전에 Java API 메서드 내에서 디버깅, 모든 것이 올바르게 보이고, 알리미가 두 경우 모두에서이 메서드 내부에서 수행됩니다. 여전히 차이점을 찾을 수 없습니다. betweens (Java 메서드 내부 단계) 일반 JCheckBox 및 JCheckBox with JOptionPane, 귀하의 동의에 감사드립니다. – mKorbel

답변

4

이것은 알려진 버그입니다. Oracle Bug ID:6924233JOptionPane은 분명히 다른 이벤트가 checkbox value = 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

에서 enter image description here

enter image description here

내가 어떤 차이가 표시되지 않습니다 다음 DESELECTED 상태에서 시작을, 나는 체크 박스를 클릭합니다. 확인 표시가 즉시 나타나고 옵션 창이 표시됩니다. Runnable의 유무에 관계없이 동일한 결과가 나타납니다.

Windows의 경우 결과는 설명 된대로 표시되지만 옵션 창이 전경에 오면 작은 확인 표시가 깜박입니다. 효과는 느려질 수있는 VirtualBox과 같은 에뮬레이터에서 더 쉽게 볼 수 있습니다. Runnable 대기열로 정상 작동 상태로 복원됩니다.

+0

죄송합니다, 이것은 실제로 답변이 아니지만 버그를 검색하는 데 도움이 될 수 있습니다. – trashgod

+0

(매번) MAC/Linux에서 임의의 코드를 실행하거나 이러한 기본 OS +1과 호환되는 코드를 요청하면 감사하게됩니다. – mKorbel