尽管我们从另一个线程更新 GUI 组件,但没有遇到任何 GUI 冻结问题
Not facing any GUI freezing issue though we updates GUI components from another thread
作为在 Java swing 上学习 SwingWorker 的一部分,我创建了一个简单的程序,其中一个不同的线程(EDT 除外)正在执行一些后台任务,一旦完成,该线程就会更新 GUI组件(JTextArea)。
据我所知,如果我们尝试从 EDT 以外的外部线程更新 GUI 组件,那么 UI 可能会被冻结。但这并没有发生。我真的很想创造那种情况(冻结UI)以便更好地理解它。以下是我尝试过的代码。谁能帮我说说我需要对我的代码做些什么,这样 UI 就会被冻结。
App.java
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class App {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MainFrame();
}
});
}
}
MainFrame.java
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class MainFrame extends JFrame implements ActionListener {
private JButton btn,btn2;
private JTextArea txtArea;
public MainFrame() {
super("Hello World");
setLayout(new BorderLayout());
btn = new JButton("Click Me!");
btn2 = new JButton("Click Me New!");
txtArea = new JTextArea();
btn.addActionListener(this);
add(txtArea,BorderLayout.CENTER);
add(btn,BorderLayout.SOUTH);
add(btn2,BorderLayout.NORTH);
setSize(600,800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
MyTestThread extThr = new MyTestThread();
extThr.setBtnRef(txtArea);
extThr.start();
}
}
MyTestThread.java
import javax.swing.JTextArea;
public class MyTestThread extends Thread {
private int i = 0;
private JTextArea txtAreaRef;
public void setBtnRef(JTextArea ta) {
this.txtAreaRef = ta;
}
public void run() {
while (i < 500000) {
try {
txtAreaRef.append("test"+i+"\n");
i=i+1;
sleep(2000);
} catch (InterruptedException e) {System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
}
我不知道你从哪里得到这些信息,但是在 EDT 之外调用 GUI 更新不会导致 UI 冻结。
如果您想产生冻结效果,请尝试在 EDT 中进行无限循环,就像这样。
这将导致 UI 永久冻结。
public void actionPerformed(ActionEvent e) {
//MyTestThread extThr = new MyTestThread();
//extThr.setBtnRef(txtArea);
//extThr.start();
while(true) {}
}
作为在 Java swing 上学习 SwingWorker 的一部分,我创建了一个简单的程序,其中一个不同的线程(EDT 除外)正在执行一些后台任务,一旦完成,该线程就会更新 GUI组件(JTextArea)。
据我所知,如果我们尝试从 EDT 以外的外部线程更新 GUI 组件,那么 UI 可能会被冻结。但这并没有发生。我真的很想创造那种情况(冻结UI)以便更好地理解它。以下是我尝试过的代码。谁能帮我说说我需要对我的代码做些什么,这样 UI 就会被冻结。
App.java
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class App {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MainFrame();
}
});
}
}
MainFrame.java
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class MainFrame extends JFrame implements ActionListener {
private JButton btn,btn2;
private JTextArea txtArea;
public MainFrame() {
super("Hello World");
setLayout(new BorderLayout());
btn = new JButton("Click Me!");
btn2 = new JButton("Click Me New!");
txtArea = new JTextArea();
btn.addActionListener(this);
add(txtArea,BorderLayout.CENTER);
add(btn,BorderLayout.SOUTH);
add(btn2,BorderLayout.NORTH);
setSize(600,800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
MyTestThread extThr = new MyTestThread();
extThr.setBtnRef(txtArea);
extThr.start();
}
}
MyTestThread.java
import javax.swing.JTextArea;
public class MyTestThread extends Thread {
private int i = 0;
private JTextArea txtAreaRef;
public void setBtnRef(JTextArea ta) {
this.txtAreaRef = ta;
}
public void run() {
while (i < 500000) {
try {
txtAreaRef.append("test"+i+"\n");
i=i+1;
sleep(2000);
} catch (InterruptedException e) {System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
}
我不知道你从哪里得到这些信息,但是在 EDT 之外调用 GUI 更新不会导致 UI 冻结。
如果您想产生冻结效果,请尝试在 EDT 中进行无限循环,就像这样。
这将导致 UI 永久冻结。
public void actionPerformed(ActionEvent e) {
//MyTestThread extThr = new MyTestThread();
//extThr.setBtnRef(txtArea);
//extThr.start();
while(true) {}
}