0

У меня проблема при создании JProgressBar, который установлен в неопределенный. Следующий код моя реализация JProgressBar и называется/строится из другого класса:JProgressBar неопределенная нить

public class Progress implements Runnable 
{ 
    private JFrame frameProgress; 
    private JProgressBar progressBar; 

    public Progress(String title, String message) 
    { 
    try 
    { 
     UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
    } 
    catch (Exception e) 
    { 
     GlobalVariables.LOGGING_logger.error("Error instatiating progress bar.", 
      e); 
    } 

    UIManager.put("ProgressBar.selectionForeground", Color.black); 
    UIManager.put("ProgressBar.selectionBackground", Color.black); 

    this.frameProgress = new JFrame(title); 
    this.frameProgress.setIconImage(GlobalVariables.GUI_icon.getImage()); 
    this.frameProgress.setSize(300, 60); 
    this.frameProgress.setLocation(16, 16); 
    this.progressBar = new JProgressBar(); 
    this.progressBar.setStringPainted(true); 
    this.progressBar.setString(message); 
    this.progressBar.setIndeterminate(true); 
    this.frameProgress.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    this.frameProgress.add(this.progressBar); 
    this.frameProgress.setResizable(false); 
    this.frameProgress.setVisible(true); 
    } 

    public void start() 
    { 
    new Thread(this).start(); 
    } 

    public void close() 
    { 
    this.frameProgress.dispose(); 
    this.frameProgress = null; 
    this.progressBar = null; 
    } 

    @Override 
    public void run() 
    { 
    SwingUtilities.invokeLater(new Runnable() 
    { 
     public void run() 
     { 
     // do nothing, because progress bar is indeterminate 
     } 
    }); 
    } 
} 

Вызывающий этого JProgressBar является следующий фрагмент кода:

Progress p = new Progress("bla", "blub"); 
    p.start(); 
    boolean successfull = xmlWriter.writeCommonSettingsFromGUI(this); 
    p.close(); 

А теперь я хочу, в то время как xmlWriter.writeCommonSettingsFromGUI(this); делает что-то, что отображается JProgressBar и работает во время работы алгоритма.

Как я могу это достичь? Я не так много знаю о потоковом и обыске на многих других форумах, но я не нашел ответа на свой вопрос.

Пожалуйста, помогите мне, и спасибо заранее;)

EDIT: Прогресс JFrame открывает без содержания для этого времени, алгоритм работает.

+0

Опишите, что не работает над вашим текущим кодом? –

+0

Индикатор выполнения не отображается, и я получаю исключение: Исключение в потоке «AWT-EventQueue-0» java.lang.NullPointerException \t на de.Progress $ 1.run (Прогресс.Java: 63) \t на java.awt.event.InvocationEvent.dispatch (InvocationEvent.java:251) \t на java.awt.EventQueue.dispatchEventImpl (EventQueue.java:727) \t в java.awt.EventQueue.access $ 200 (EventQueue.java:103)) ... –

+0

Хорошо ... ошибок больше нет ... но: если я начну поток, он откроет JRrame прогресса, но в нем нет содержимого (нет JProgressBar) ... –

ответ

3

Возможно, вы столкнулись с проблемами параллелизма с Swing. Если предположить, что следующий код работает на EDT (Event Диспетчерская Thread):

Progress p = new Progress("bla", "blub"); 

в конце концов, это откроет JFrame с индикатором прогресса в нем.

  • Я бы рассмотреть вопрос об использовании JDialog вместо JFrame
  • Я бы не заставить размер JFrame, а называют pack()

Затем, по-прежнему работает на EDT (и, таким образом, блокируя все UI-события, такие как перерисовка, щелчки мышью и т. д.), вы вызываете p.start(), который запускает new Thread(), который будет вызывать run(), который сам вызывает

SwingUtilities.invokeLater(new Runnable() 
{ 
    public void run() 
    { 
    // do nothing, because progress bar is indeterminate 
    } 
}); 

Это в основном ничего не сделает, кроме как нажать дополнительное событие в EventQueue, и оно будет запущено после всех текущих ожидающих событий. Это событие будет запущено ... «ничего», так как ваш Runnable просто пуст. Новая нить умирает почти сразу. Таким образом, весь этот код бесполезен.

Продолжая следовать по EDT, вы вызываете boolean successfull = xmlWriter.writeCommonSettingsFromGUI(this); (кстати, «успешный» заканчивается только одним «l»). Это будет продолжаться при блокировке EDT, предотвращении возникновения перекрасок и предотвращении рисования самого изображения. В конце концов вы выберете JFrame, но поскольку весь этот код работает на EDT, пользователь не увидит большую часть индикатора выполнения, и пользовательский интерфейс будет выглядеть замороженным.

Рассмотрите возможность просмотра Swing tag wiki (особенно последняя часть с 3 важными ссылками).

Использование SwingWorker должно помочь вам в этом.