基本上,我有这个代码,最初使用的是控制台i / o,现在我必须将它连接到 UI 。这可能是完全错误的,虽然它最终会冻结GUI,但我尝试了多种方法。
我尝试将控制台I / O重定向到GUI滚动窗格,但GUI仍会冻结。可能它必须对线程做一些事情,但我对它的知识有限,所以我需要更深入的解释如何在当前情况下实现它。
这是GUI类上的按钮,包含需要更改此GUI的方法。
public class 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++) {
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();
}
askQuestion方法:
public void askQuestion() {
System.out.println(getQuestion());
/* I've tried to change staticaly declared frame in GUI from there */
}
userAnswer方法:
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;
}
感谢您的帮助。
答案 0 :(得分:0)
你认为它与线程相关是正确的。
当你在swing线程中尝试执行需要很长时间处理的代码(例如,下载大文件)时,swing线程将暂停以完成执行并导致GUI冻结。这可以通过在单独的线程中执行长时间运行的代码来解决。
正如Sergiy Medvynskyy在他的评论中指出的那样,你需要在SwingWorker类中实现长时间运行的代码。
实现它的一个好方法是:
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.
}
}
使用TestWorker.execute()
启动工作人员。
This网站提供了一个如何使用的好例子 SwingWorker类。
答案 1 :(得分:-1)
正如其他答案所指出的那样,在GUI线程上做大量工作会冻结GUI。你可以使用SwingWorker
,但在很多情况下,只需要一个简单的Thread
来完成工作:
Thread t = new Thread(){
@Override
public void run(){
// do stuff
}
};
t.start();
或者如果您使用Java 8 +:
Thread t = new Thread(() -> {
// do stuff
});
t.start();