Боюсь, что это немного сложно, так как я не смог воссоздать проблему в примере, который я написал для этого вопроса (пример ниже работает отлично). Надеюсь, кто-то может иметь представление о возможных проблемах с фактическим применением.
Я написал приложение с выполняет несколько длинных текстовых операций. Каждая операция выполняется в своем собственном потоке. Существует фрейм, который обновляется потоками, чтобы пользователь мог видеть, как все идет.
Проблема в том, что фрейм отображается со всеми обновлениями, которые были ему отправлены, только после того, как все потоки выполнены с их заданиями.
Я упростил все приложение в приведенном ниже коде, но, как я уже сказал, проблема в том, что оно работает здесь. Любые идеи очень приветствуются.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Main {
private MyFrame frame;
private ExecutorService executorService;
public static void main(String[] args) throws InterruptedException {
Main main = new Main();
main.startProcess();
}
public void startProcess() throws InterruptedException {
// Initialize the frame
frame = new MyFrame();
EventQueue.invokeLater(new Runnable() {
public void run() {
frame.setVisible(true);
}
});
// Initialize executorService for 3 threads and also 6 runnables
executorService = Executors.newFixedThreadPool(3);
MyRunnable runnable;
for(int i = 0; i < 6; i++) {
runnable = new MyRunnable(this, i);
executorService.execute(runnable);
}
// Start runnables
executorService.shutdown();
// Wait until all runnables are executed
while (!executorService.isTerminated()) {
Thread.sleep(10000);
}
// When all runnables are done close the frame
EventQueue.invokeLater(new Runnable() {
public void run() {
frame.setVisible(false);
}
});
}
// Update the frame display
public synchronized void updateDisplay(final String update) {
EventQueue.invokeLater(new Runnable() {
public void run() {
frame.updateDisplay(update);
}
});
}
private class MyFrame extends JFrame {
private JPanel contentPane;
private JLabel lblDisplay;
public MyFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = new JPanel();
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
lblDisplay = new JLabel("Display");
contentPane.add(lblDisplay, BorderLayout.CENTER);
pack();
}
public void updateDisplay(String update) {
lblDisplay.setText(update);
pack();
}
}
private class MyRunnable implements Runnable {
private int id;
private Main main;
public MyRunnable (Main main, int id) {
this.main = main;
this.id = id;
}
@Override
public void run() {
for(int i = 0; i < 3; i++) {
main.updateDisplay("Runnable " + id + " stepped " + i + " times.");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}