Почему мой JTextArea не обновляется? - PullRequest
3 голосов
/ 21 июля 2011

У меня есть следующий код:

class SimplifiedClass extends JApplet {

    private JTextArea outputText;
    // Lots of methods
    public void DoEverything() {
        String output = "";
        for(int i = 0; i <= 10; i++) {
            output += TaskObject.someLongTask(i);
            outputText.setText(output);
        }
    }
}

Однако вместо обновления текстовой области после каждой итерации цикла, когда вызывается setText, он, по-видимому, обновляет текст только после завершения всех запусков задачи. Почему это происходит, и как я могу решить это?

Ответы [ 5 ]

3 голосов
/ 21 июля 2011
private JTextArea outputText = new JTextArea();

public void DoEverything() {
    String output = "";
    for(int i = 0; i <= 10; i++) {
        output += TaskObject.someLongTask(i);
        appendNewText(output);
    }
}

public void appendNewText(String txt) {
  SwingUtilities.invokeLater(new Runnable() {
     public void run() {
        outputText.setText(outputText.getText + txt);
       //outputText.setText(outputText.getText + "\n"+ txt); Windows LineSeparator
     }
  });
}
3 голосов
/ 21 июля 2011

Возможно, вы используете поток Swing, который ожидает выполнения вашего кода, прежде чем он сможет обновить пользовательский интерфейс. Попробуйте использовать отдельный поток для этого цикла.

public void DoEverything() {
  SwingUtilities.invokeLater(new Runnable() {
    public void run() {
      String output = "";
      for(int i = 0; i <= 10; i++) {
        output += TaskObject.someLongTask(i);
        outputText.setText(output);
      }
    }
  });
}
2 голосов
/ 24 сентября 2012

Вы используете базовые потоки, которые называются начальными.Вместо этого используйте рабочие потоки.Попробуйте использовать SwingWorker для рабочих потоков.

Для получения дополнительной информации перейдите по следующей ссылке: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html

0 голосов
/ 27 ноября 2014

Как говорилось в сообщении, важно не блокировать EDT (поток отправки событий).В моем примере ниже фактическая работа начинается с потока EDT, как это происходит при нажатии кнопки ActionListener.Мне нужно обернуть его отдельным потоком, чтобы он был отделен от потока отправки событий.Таким образом, EDT не блокируется.

Также обратите внимание, что вам необходимо использовать SwingUtilities.invokeLater () при обновлении пользовательского интерфейса из отдельного потока.Пример кода ниже немного упрощен от моего исходного кода.Я на самом деле выполняю несколько задач параллельно, используя несколько потоков, и в каждом из этих потоков вызывается updateProgress () для обновления TextArea путем добавления последнего статуса.

Полный исходный код здесь: https://github.com/mhisoft/rdpro/blob/master/src/main/java/org/mhisoft/rdpro/ui/ReproMainForm.java

btnOk.addActionListener(new ActionListener() {
  @Override
  public void actionPerformed(ActionEvent e) {
    //Don't block the EDT, wrap it in a seperate thread
    DoItJobThread t = new DoItJobThread();
    t.start();

  } 
});


class DoItJobThread extends Thread {
    @Override
    public void run() {
       //do some task 
       // output the progress
       updateProgress();    
    }
}


public void updateProgress(final String msg) {
    //invokeLater()
    //This method allows us to post a "job" to Swing, which it will then run
    // on the event dispatch thread at its next convenience.

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            // Here, we can safely update the GUI
            // because we'll be called from the
            // event dispatch thread
            outputTextArea.append(msg);
            outputTextArea.setCaretPosition(outputTextArea.getDocument().getLength());
            //labelStatus.setText(msg);
        }
    });

}
0 голосов
/ 18 мая 2012

Попробуйте использовать outputText.validate () после outputText.setText (output)

Я пробовал это для моей программы, которая аналогична.По какой-то причине использование Thread.sleep(delay), непосредственно следующего за outputText.setText("dsfgsdfg"), даже с outputText.validate() не позволяет пользователю увидеть вывод.Это самая странная вещь.Это похоже на то, что код читается после попытки вызова метода setText.Затем нажимает метод сна, и все идет в ад.

...