-2

重複の可能性:
Java の SwingWorker

一緒に作業する必要があるクラスがいくつかありますが、そうではありません。

1つには、メインがあります:

public class Main
{

 public static void main(String[] args)
 {

  SwingUtilities.invokeLater(new Runnable()
  {

   @Override
   public void run()
   {

   //JFrame dummy for JDialog errors
   modal = new JFrame();

   new PrimaryErrorDialog("Title", "Message", e, false);

    JFrame masterWindow = new JFrame();
     masterWindow.setVisible();
   }
  }
 }
}

PrimaryErrorDialog クラスを作成します。

private JDialog dialog = this;
private JTextArea text;
private JPanel buttonContainer;
private JButton sendErrorReportT, sendErrorReportF;

public PrimaryErrorDialog(String title, String message,
final Exception error, final boolean exit)
{
 super(Main.modal, title, true);

 //JButton for sending error report
 sendErrorReportT = new JButton("Send Error Report");
 sendErrorReportT.addActionListener(new ActionListener()
 {
  @Override
  public void actionPerformed(ActionEvent e)
  {
   dialog.dispose();

   dialog = new JDialog(Main.modal, "Sending...", true);

   Worker thread = new Worker(error);
   thread.start();

   JProgressBar progress = new JProgressBar();
   progress.setIndeterminate(true);

   dialog.add(progress);    
   dialog.pack();
   dialog.setVisible(true);
  }
 });

 //JButton for not sending error report
 sendErrorReportF = new JButton("Don't send error report");
 sendErrorReportF.addActionListener(new ActionListener()
 {
  @Override
  public void actionPerformed(ActionEvent e)
   {
    dialog.dispose();

    if (exit)
    {
     System.exit(0);
    }
   }
  });

 buttonContainer = new JPanel();
 buttonContainer.add(sendErrorReportT);
 buttonContainer.add(sendErrorReportF);

 add(text);
 add(buttonContainer);

 pack();
 setLocationRelativeTo(null);
 setVisible(true);
}

public void cleanUpAndContinue()
 {
  dialog.dispose();
  dialog = new JDialog(Main.modal, "title", true);
  dialog.add(/*Jbutton with listener that disposes this dialog*/)
  dialog.setVisible(true);
 }

Thread を拡張する Worker クラスを呼び出します。

public class Worker extends Thread
{
    Exception e;

    public Worker(Exception error)
    {
        e = error;
    }

    @Override
    public void run()
    {
    //do something that takes time
     PrimaryErrorDialog.cleanUpAndContinue();
    }

PrimaryErrorDialog に戻り、タスクが完了したことをユーザーに通知し、そのダイアログを終了する必要があります。

次に、masterWindow が作成される main に戻ります。

エラーが発生したときにこのセグメントが実行されるため (LAF が存在しない場合、.proprties ファイルが見つからない場合など)、このコードはすべて masterWindow の作成前に実行されます...

そのため、JDialog を接続できるようにダミーの JFrame を作成しました。これを JFrame にしたくありませんでした。

このコードは、プログラムの後半でも実行されます。「実際の」実行時エラーの場合、一部のクラスには少し異なるパラメーターやコンストラクターがあります。

しかし、これは機能しません。私は何百万もの方法で試しました.SwingWorkerで試しましたが、私が望むものは何もないようです. 通常、電子メールコードに到達しないか、プログラムがダイアログが破棄されるのを待ちません...

そして、私は何をしたいですか?

エラーが発生します。エラーが発生したことを通知し、エラー レポートを送信するかどうかを尋ねるダイアログが表示されます。いいえ、エラーが致命的である場合は、ダイアログが閉じ、プログラム全体がダウンします。はいと言います-ダイアログが閉じ、新しいダイアログが不定のプログレスバーで開き、スタックトレースを含む電子メールがバックグラウンドで送信されています。電子メールが送信され、プログレスバーを含むダイアログが閉じ、エラーレポートが送信されたことを示す新しいダイアログが開きます。[OK] を押すとダイアログが閉じ、エラーが致命的な場合はプログラム全体が削除され、それ以外の場合は Main クラスから離れたところから続行されます。

注: エラーはどのクラスでも発生する可能性があります。それは Main のみからではありません...

4

2 に答える 2

4

ただし、前の質問を読んでいません...

あなたが抱えている基本的な問題は、バックグラウンドスレッドが完了したことをダイアログ (EDT 内にある) に通知する必要があることです (可能であればユーザーにフィードバックを提供することもできます)。

これについては、Swing の同時実行のレッスンで説明されています。

以下は、概念の簡単な証明です。個人的には、通常はカスタム パネルを作成して a に配置しますJDialogが、これは概念実証にすぎません。

public class TestSwingWorker {

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {

                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                final JDialog dialog = new JDialog((Frame)null, "Happy, Happy, Joy, Joy", true);
                // This is so I can get my demo to work, you won't need it...
                dialog.addWindowListener(new WindowAdapter() {

                    @Override
                    public void windowClosing(WindowEvent e) {
                        System.exit(0);
                    }

                });

                JPanel panel = new JPanel(new GridBagLayout());
                panel.setBorder(new EmptyBorder(8, 8, 8, 8));
                dialog.setContentPane(panel);

                // You'll need you own icon...
                JLabel lblIcon = new JLabel(new ImageIcon(getClass().getResource("/waiting-64.png")));
                JLabel lblMessage = new JLabel("<html>Hard and work here<br>Please wait...</html>");
                final JProgressBar progressBar = new JProgressBar();

                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridx = 0;
                gbc.gridy = 0;
                gbc.anchor = GridBagConstraints.NORTH;
                gbc.weighty = 1;
                gbc.insets = new Insets(2, 2, 2, 2);
                gbc.gridheight = GridBagConstraints.REMAINDER;
                dialog.add(lblIcon, gbc);

                gbc.gridheight = 1;
                gbc.gridx = 1;
                gbc.gridy = 0;
                gbc.anchor = GridBagConstraints.WEST;
                gbc.weighty = 0;
                gbc.weightx = 1;
                dialog.add(lblMessage, gbc);

                gbc.gridy = 1;
                gbc.anchor = GridBagConstraints.NORTH;
                gbc.weighty = 1;
                dialog.add(progressBar, gbc);

                dialog.pack();
                dialog.setLocationRelativeTo(null);

                MyWorker worker = new MyWorker();
                // Get notification back from the worker...
                worker.addPropertyChangeListener(new PropertyChangeListener() {

                    @Override
                    public void propertyChange(PropertyChangeEvent evt) {

                        MyWorker worker = (MyWorker) evt.getSource();
                        // Progress has been updated
                        if (evt.getPropertyName().equalsIgnoreCase("progress")) {

                            progressBar.setValue((Integer)evt.getNewValue());

                        // The state of the worker has changed...
                        } else if (evt.getPropertyName().equalsIgnoreCase("state")) {

                            if (worker.getState().equals(SwingWorker.StateValue.DONE)) {

                                dialog.dispose();

                            }

                        }

                    }
                });

                worker.execute();

                dialog.setVisible(true);

            }

        });

    }

    protected static class MyWorker extends SwingWorker<Object, Object> {

        @Override
        protected Object doInBackground() throws Exception {

            // My long running task...
            for (int index = 0; index < 100; index++) {

                // Change this to make it faster or slower...
                Thread.sleep(250);
                setProgress(index);

            }

            return null;

        }

    }

}
于 2012-09-28T21:25:10.210 に答える
3
  • ダーティハックラップdialog.setVisible(true);インinvokeLater()

  • 使用するSwingWorkerか、Runnable#Thread代わりにまたはプレーンThread

  • 回答、特に前の質問からのコメントを無視した問題はありますか

  • Swing Guiは、スレッドからの出力を気にしません。イベントディスパッチスレッドの通知機能が実装されていないため、invokeLaterで呼び出すか、を使用する必要がありますSwingWorker

  • SwingWorkersメソッドdonepublishおよびprogressEDTに正しく通知できます

于 2012-09-28T17:45:31.263 に答える