问题描述
基本上,我有这段代码,最初用于控制台 i/o,现在我必须将其连接到 UI.这可能是完全错误的,我尝试了多种方法,尽管最终还是冻结了 GUI.
我尝试将控制台 I/O 重定向到 GUI 滚动窗格,但 GUI 仍然冻结.可能它必须对线程做一些事情,但我对它的了解有限,所以我需要更深入的解释如何在当前情况下实现它.
这是 GUI 类上的按钮,包含需要更改此 GUI 的方法.
公共类GUI {...btnNext.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {controller.startTest(index, idUser);}});}
这是来自另一个包含 Question 类实例的类的 startTest 方法.
public int startTest() {for (int i = 0; i < this.numberofQuestions; i++) {问题 qt = this.q[i];qt.askQuestion();<--- 这需要改变 GUI 中的标签if(!qt.userAnswer()) <--- 这需要从 TextField 获取字符串减少分数(1);}返回actScore();}
askQuestion 方法:
public void askQuestion() {System.out.println(getQuestion());/* 我试图从那里改变 GUI 中静态声明的框架 */}
userAnswer 方法:
public boolean userAnswer() {@SuppressWarnings("资源")扫描仪scanner = new Scanner(System.in);if( Objects.equals(getAnswer(),userInput) ) {System.out.println("正确");返回真;}System.out.println("假");返回假;}
感谢您的帮助.
您认为它与线程有关是正确的.
当您尝试在 Swing 线程中执行需要很长时间处理(例如下载大文件)的代码时,Swing 线程将暂停以完成执行并导致 GUI 冻结.这是通过在单独的线程中执行长时间运行的代码来解决的.
正如 Sergiy Medvynskyy 在他的评论中指出的那样,您需要在 SwingWorker 类.
实现它的一个好方法是:
public class TestWorker extends SwingWorker{@覆盖受保护的整数 doInBackground() 抛出异常 {//这是你执行长时间运行的地方//代码controller.startTest(index, idUser);发布(完成");}@覆盖受保护的无效进程(列表块){//当任务执行完成时调用.//这是您可以在何时更新GUI的地方//任务完成或你想要的时候//通知用户更改.}}
使用TestWorker.execute()
来启动worker.
这个网站提供了一个关于如何使用的很好的例子SwingWorker 类.
basically, I have this code which was initially working with console i/o now I have to connect it to UI. It may be completely wrong, I've tried multiple things although it still ends up with freezing the GUI.
I've tried to redirect console I/O to GUI scrollpane, but the GUI freezes anyway. Probably it has to do something with threads, but I have limited knowledge on it so I need the deeper explanation how to implement it in this current situation.
public class GUI {
...
btnNext.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
controller.startTest(index, idUser);
}
});
}
public int startTest() {
for (int i = 0; i < this.numberofQuestions; i++) {
Question qt = this.q[i];
qt.askQuestion(); <--- This needs to change Label in GUI
if(!qt.userAnswer()) <--- This needs to get string from TextField
decreaseScore(1);
}
return actScore();
}
public void askQuestion() {
System.out.println(getQuestion());
/* I've tried to change staticaly declared frame in GUI from there */
}
public boolean userAnswer() {
@SuppressWarnings("resource")
Scanner scanner = new Scanner(System.in);
if( Objects.equals(getAnswer(),userInput) ) {
System.out.println("Correct");
return true;
}
System.out.println("False");
return false;
}
Thanks for help.
You're correct in thinking that it related to threads.
When you try executing code that will take a long time to process (eg. downloading a large file) in the swing thread, the swing thread will pause to complete execution and cause the GUI to freeze. This is solved by executing the long running code in a separate thread.
As Sergiy Medvynskyy pointed out in his comment, you need to implement the long running code in the SwingWorker class.
A good way to implement it would be this:
public class TestWorker extends SwingWorker<Integer, String> {
@Override
protected Integer doInBackground() throws Exception {
//This is where you execute the long running
//code
controller.startTest(index, idUser);
publish("Finish");
}
@Override
protected void process(List<String> chunks) {
//Called when the task has finished executing.
//This is where you can update your GUI when
//the task is complete or when you want to
//notify the user of a change.
}
}
Use TestWorker.execute()
to start the worker.
This website provides a good example on how to usethe SwingWorker class.
这篇关于Java Swing GUI 更新/更改方法 - 循环冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!