2015-12-29 9 views
0

У меня есть класс WaitBox, который я бы хотел всплыть, показать индикатор выполнения, а затем закрыть, когда индикатор выполнения достигнет 100%. Прямо сейчас, это всплывает, но странно, что он ждет, пока код не закончит рисовать компоненты (индикатор выполнения) в WaitBox ...Компонент ждет более позднего кода для выполнения перед его розыгрышем

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

WaitBox класс:

public class WaitBox extends JDialog implements Runnable { 
private static final long serialVersionUID = 1L; 

private int width = 450; 
private int height = 200; 
public static int widthOfBar = 400; 
private int heightOfBar = 50; 
private JPanel container; 
private JProgressBar progressBar; 
private Thread thread; 
private boolean running = false; 

public WaitBox() { 
    initializeComponents(); 
    add(container); 
    pack(); 
    setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 
    setTitle("Loading..."); 
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    setResizable(false); 
    setLocationRelativeTo(null); 
    setVisible(true); 
} 

private void initializeComponents() { 
    container = new JPanel(); 
    container.setPreferredSize(new Dimension(width, height)); 
    progressBar = new JProgressBar(0, widthOfBar); 
    progressBar.setPreferredSize(new Dimension(widthOfBar, heightOfBar)); 
    progressBar.setStringPainted(true); 
    progressBar.setValue(0); 
    container.add(progressBar); 
} 

public void run() { 
    while (running) { 
     System.out.println(Fill.currentPos); 
     progressBar.setValue((int) Fill.currentPos); 
     if (progressBar.getValue() >= widthOfBar) running = false; 
    } 
    stop(); 
} 

public synchronized void start() { 
    running = true; 
    thread = new Thread(this); 
    thread.start(); 
} 

public synchronized void stop() { 
    running = false; 
    try { 
     thread.join(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    setCursor(null); 
    dispose(); 
} 

} 

Как его называют:

WaitBox waitBox = new WaitBox(); 
waitBox.start(); 
for (int yy = 0; yy < Constants.map_height; yy++) { 
    for (int xx = 0; xx < Constants.map_width; xx++) { 
     image.setRGB(xx * 32, yy * 32, 32, 32, pixels, 0, 32); 
    } 
} 

ответ

3

stop Вашего метод ждет thread до конца, который блокирует событие диспетчерского тему.

См Concurrency in Swing для более подробной информации

Вашего метод run нарушают отдельные правила резьбы свинга, обновление пользовательского интерфейса из-за пределы событий Диспетчерской Thread, помните, Swing однопоточная, но также не поточно.

Вы должны использовать вместо этого SwingWorker, который имеет прогресс и PropertyChange. См Worker Threads and SwingWorker для более подробной информации

что продемонстрировано:

среди других мест

+0

я могу начать SwingWorker внутри моего конструктора, или где бы вы рекомендовали поместить его? – kneedhelp

+0

Вы можете запустить его, когда/когда вам это нужно. Он использует собственный фоновый поток для вызова метода doInBackground. Вы должны просто использовать поддержку 'PropertyChangeListener' и/или функцию' publish/process' для обновления пользовательского интерфейса от – MadProgrammer

+0

. Я добавил SwingWorker и поместил весь материал run/WaitBox внутри него, и он работал так же, как я хотел это к. Большое спасибо! – kneedhelp