Vì tôi đã cố gắng xem tôi có thể trả lời this question earlier today hay không. Tôi nhận ra rằng tôi không hoàn toàn hiểu được Event Dispatch Thread
(EDT). Googling đều đã được xác nhận và trợ giúp với điều đó và làm rõ why I don't. (This cũng có thể liên quan đến sự hiểu biết.)Việc bỏ qua chuỗi gửi sự kiện cho phép chương trình này hoạt động như thế nào?
Mã thiết lập GUI và sau đó (như trong câu hỏi trước) cập nhật trường văn bản cho đến khi cờ không được đặt.
Tôi có một số câu hỏi/yêu cầu.
Xin giải thích tại sao đoạn code dưới đây chạy tốt nếu cả hai cuộc gọi (để
swingInit
vàdoIt
) nằm ngoàiinvokeLater
khối (như hình), vì cả hai cuộc gọi ảnh hưởng hoặc truy vấn GUI nhưng không được thực hiện trên EDT (là họ?) Đó không phải là sự mời gọi thất bại sao?Mã cũng chạy nếu gọi đến
swingInit
nằm trong vàdoIt
bên ngoàiinvokeLater
. Vì vậy,swingInit
được thực hiện trên EDT, nhưng không nêndoIt
không thực hiện trên EDT là một vấn đề? (Tôi đã rất ngạc nhiên rằng đây làm việc Tôi có nên có được.?)Tôi đoán tôi hiểu tại sao nó bị treo nếu
doIt
là bên tronginvokeLater
không phân biệt nơiswingInit
là: Mục đích củainvokeLater
chỉ dành khởi GUI (đúng?).nên
doIt
chỉ được bắt đầu (có thể là từ một sự kiện xảy ra) trên EDT nhưng chắc chắn không bêninvokeLater
khối?
(Lịch sử của khái niệm EDT là thú vị. Nó không phải luôn luôn như vậy. Xem liên kết ở trên để "tại sao tôi không" hiểu nó.)
import static java.awt.EventQueue.invokeLater;
import java.awt.event.*;
import javax.swing.*;
public class Whatever
{
static boolean flag = true;
static JTextField tf = new JTextField("Hi",20);
static JPanel p = new JPanel();
static JFrame f = new JFrame();
static JButton b = new JButton("End");
public static void main(String[] args)
{
swingInit();
invokeLater
(
new Runnable()
{
@Override
public void run()
{
// swingInit();
// doIt();
}
}
);
doIt();
}
static void swingInit()
{
b.addMouseListener
(
new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
flag = false;
JOptionPane.showMessageDialog(null,"Clicked... exiting");
System.exit(0);
}
}
);
p.add(tf);
p.add(b);
f.add(p);
f.setVisible(true);
f.pack();
f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
}
static String getInfo(){
return "Hello... " + Math.random();
}
static void doIt(){
while(flag)
tf.setText(getInfo());
};
}
Như tôi nghĩ bạn hiểu, bạn không nên cập nhật GUI từ các chủ đề khác với EDT - tuy nhiên, làm như vậy không * nhất thiết * thất bại - nó chỉ là rất nguy hiểm. Vì vậy, đừng ngạc nhiên nếu mã như vậy đôi khi dường như làm việc. – DNA