Java Swing GUI更新/更改方法 - 冻结循环

时间:2018-04-05 11:54:42

标签: java swing user-interface

基本上,我有这个代码,最初使用的是控制台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;

}

感谢您的帮助。

2 个答案:

答案 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();