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.
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+ 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. –
@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