как показать диалог занятости / работы / загрузки с динамическим сообщением - PullRequest
2 голосов
/ 17 января 2012

Я хочу показать модальное диалоговое окно, которое заблокирует мое главное окно, и я хочу управлять им извне с помощью методов showLoadingDialog (), hideLoadingDialog () и setLoadingMessage (String message) - я пробовал этот код, но он не работает - Диалог загрузки виден, но без сообщения

</p> <pre><code>import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; public class LoadingExample { private static class LoadingDialog extends JDialog { private JLabel label = new JLabel("working"); public LoadingDialog(JFrame owner) { super(owner, ModalityType.APPLICATION_MODAL); setUndecorated(true); add(label); pack(); // move window to center of owner int x = owner.getX() + (owner.getWidth() - getPreferredSize().width) / 2; int y = owner.getY() + (owner.getHeight() - getPreferredSize().height) / 2; setLocation(x, y); repaint(); } public void setMessage(String message) { label.setText(message); } } private static LoadingDialog loadingDialog; public static void main(String[] args) { final JFrame mainWindow = new JFrame("Main frame"); mainWindow.setLayout(new GridLayout(3, 3)); for (int i = 1; i <= 9; i++) { final int workTime = i; JButton workButton = new JButton("work for " + i + " second"); //action listener, which had to show loading dialog and countdown seconds before finish workButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { showLoadingDialog(mainWindow); for (int j = 0; j < workTime; j++) try { // ... do some work here setLoadingMessage("remain " + (workTime - j) + " second(s)"); loadingDialog.repaint(); Thread.sleep(1000); } catch (InterruptedException e1) { e1.printStackTrace(); } hideLoadingDialog(); } }); mainWindow.add(workButton); } mainWindow.pack(); mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); mainWindow.setLocationRelativeTo(null); mainWindow.setVisible(true); } public static void showLoadingDialog(JFrame owner) { if (loadingDialog != null) loadingDialog.dispose(); loadingDialog = new LoadingDialog(owner); new Thread() { @Override public void run() { loadingDialog.setVisible(true); }; }.start(); } public static void setLoadingMessage(String message) { loadingDialog.setMessage(message); } public static void hideLoadingDialog() { if (loadingDialog != null) { loadingDialog.setVisible(false); loadingDialog.dispose(); loadingDialog = null; } } }

спасибо за любые предложения

Ответы [ 2 ]

0 голосов
/ 18 января 2012

Я хотел написать пример кода, но перед запуском среды IDE я провел небольшой поиск в превосходном учебнике по Swing для параллелизма , и вот, он содержит именно тот пример кода, который вы ищете. У вас есть 'задача с промежуточными результатами' . Поэтому, когда у вас есть промежуточные результаты, вы вызываете метод SwingWorker#publish. В методе SwingWorker#process модальный диалог обновляется новым только что опубликованным сообщением. Метод SwingWorker#done позволяет впоследствии удалить модальное диалоговое окно.

Но я предлагаю вам прочитать весь учебник по параллелизму от начала до конца, так как ваш пример кода показывает, что вам не хватает базовых знаний по многопоточности Swing.

0 голосов
/ 17 января 2012

Вы не можете вносить изменения в графический интерфейс из потока, отличного от потока диспетчера, связанного с элементом управления, который вы пытаетесь изменить. Чтобы сделать это правильно, вы можете использовать SwingUtilities.InvokeLater:

new Thread() {
    @Override
    public void run() {

       SwingUtilities.InvokeLater(new Runnable() {
           public void run() {
              loadingDialog.setVisible(true);
           }
       });

    };
}.start();
...