2016-05-21 3 views
2

У меня есть небольшая проблема с моим модальным JDialog. Я хочу, чтобы он показывался, пока код работает в фоновом режиме (загрузка некоторых файлов) и обновление диалогового окна, поэтому пользователь может видеть текущий статус. Его загрузка прекрасна, но не обновляет диалог ... Помогите мне! Я не могу найти свою ошибку. : Сmodal JDialog не обновляется

фрагмент кода:

JDialog dialog = new JDialog(parentFrame, "Element download...", true); 
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); 
dialog.setResizable(false); 
dialog.getContentPane().setLayout(new BorderLayout()); 

JPanel panel = new JPanel(); 
panel.setBorder(new EmptyBorder(5, 5, 5, 5)); 
panel.setPreferredSize(new Dimension(300, 100)); 
panel.setLayout(null); 
dialog.add(panel); 

final JLabel label = new JLabel("Starting download..."); 
label.setBounds(new Rectangle(0, 0, 300, 20)); 
label.setHorizontalTextPosition(JLabel.CENTER); 
panel.add(label); 

final JProgressBar bar = new JProgressBar(0, 118); 
bar.setBounds(new Rectangle(20, 0, 300, 80)); 
panel.add(bar); 

dialog.pack(); 
dialog.setLocationRelativeTo(parentFrame); 

new Thread(new Runnable() { 
    @Override 
    public void run() { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       // Executin some code (that works fine) 
       bar.setValue(value); 
       label.setText(text); 
       System.out.println(text); 
       dialog.dispose(); 
      } 
     }); 
    } 
}).start(); 
dialog.setVisible(true); 
+0

Где код, который скачивает файлы? Весь код в вашем потоке выполняется в потоке диспетчера событий. Кроме того, вы должны сделать JDialog видимым до начала Thread. –

+0

Зачем вам нужен код? Я отрезал его, потому что он очень длинный. Если я установил JDialog, видимый перед выполнением потока, поток будет выполняться до тех пор, пока диалог не будет закрыт, из-за того, что JDialog блокирует любые другие действия. – Nicolas

ответ

1

Вы используете тему и SwingUtilities.invokeLater() неправильно.

Точка Thread предназначена для выполнения долгого задания (загрузка файла) в отдельном потоке, поэтому вы не блокируете Event Dispatch Thread (EDT).

Пункт SwingUtilities.invokeLater() заключается в добавлении кода в EDT.

Итак, в вашем случае вы добавляете код загрузки файла в EDT, что означает, что графический интерфейс не может отвечать на события или перерисовываться до тех пор, пока все загрузки файлов не будут завершены.

Вы хотите, чтобы нить запускала код для загрузки, а затем по завершении загрузки каждого файла вы создаете SwingUtilities.invokeLater (...) для обновления панели и метки.

Самый простой способ сделать это - использовать результаты SwingWorker и publish(), по мере их появления.

Для получения дополнительной информации и рабочих примеров SwingWorker ознакомьтесь с разделом из учебника Swing по телефону Concurrency.

+0

Большое спасибо! – Nicolas

Смежные вопросы