2011-11-26 18 views
5

Ai đó có thể giải thích cho tôi tại sao tôi bị mất lựa chọn (được thiết lập bởi setSelected()) cho JCheckBox khi tôi đặt JOptionPane vào ItemListener? Đây có phải là lỗi không?Tại sao setSelected trên JCheckBox mất hiệu lực?

Thật kỳ lạ, nếu quá trình này bị trì hoãn với invokeLater(), setSelected() hoạt động chính xác như tôi mong đợi.

enter image description hereenter image description here

từ 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+ câu hỏi. Tôi đã nhìn thấy điều này trước đây và đã giải quyết nó như bạn có - bằng cách xếp hàng hiển thị của JOptionPane trên EDT, nhưng tôi không thể giải thích nó vì tôi đã không có thời gian hoặc năng lượng để slog thông qua mã nguồn được nêu ra. –

+0

@Hovercraft Full Of Eels Tôi gỡ lỗi bên trong các phương thức Java API, trước khi tôi đăng câu hỏi này ở đây, mọi thứ trông giống hệt, trình thông báo được thực hiện bên trong phương thức này trong cả hai trường hợp, tôi vẫn không thể tìm thấy sự khác biệt giữa các bước (các bước bên trong phương thức Java) JCheckBox đơn giản và JCheckBox với JOptionPane, cảm ơn sự đồng ý của bạn – mKorbel

Trả lời

4

Đó là lỗi đã biết được xác nhận bởi Oracle Bug ID:6924233 Hình JOptionPane dường như khiến một sự kiện khác được tạo với giá trị hộp kiểm = false.

Sửa lỗi được đề xuất là để tạo nhanh JOptionPane sử dụng invokeLater.

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

Trên Mac OS X & Ubuntu Tôi không thấy bất kỳ sự khác biệt: Bắt đầu từ trạng thái DESELECTED, tôi nhấp vào hộp kiểm. Tôi thấy dấu kiểm xuất hiện ngay lập tức, tiếp theo là ngăn tùy chọn. Tôi nhận được kết quả tương tự có hoặc không có Runnable.

Trên Windows, kết quả được mô tả, nhưng tôi thấy một nhấp nháy nhỏ của dấu kiểm khi ngăn tùy chọn đến nền trước. Hiệu ứng dễ nhìn hơn trong trình mô phỏng, chẳng hạn như VirtualBox, có thể làm chậm mọi thứ. Xếp hàng Runnable khôi phục hoạt động bình thường.

+0

Xin lỗi, đây không thực sự là câu trả lời, nhưng nó có thể hướng dẫn tìm kiếm lỗi. – trashgod

+0

(mỗi lần) tôi đánh giá cao việc chạy bất kỳ mã nào trên MAC/Linux hoặc yêu cầu mã tương thích với các Hệ điều hành gốc +1 này – mKorbel

Các vấn đề liên quan