3

ファイルをロードすると同時に、ファイルがロードされていることをユーザーに通知するウィンドウを表示するプログラムがあります。実際にファイルの読み込みを処理するSwingWorkerであるFileLoaderクラスと、渡されたSwingWorkerのステータスをユーザーに通知するPropertyChangeListenerを実装するProgressWindowを作成することにしました。

私のコードは現在次のようになっています:

FileLoader loader = new FileLoader(filePath);
new ProgressWindow(loader, "Loading File", "Loading File");
//ProgressWindow's constructor calls loader.execute() inherited from SwingWorker
doc = loader.get(); //GUI Freezes when called

問題は、loader.get()を呼び出すと、GUIがフリーズするため、進行状況ウィンドウの進行状況バーが実行されず、すべてが無意味になることです。私の知る限り、これはGUIを制御するスレッドがloader.get()を呼び出すスレッドと同じであり、loader.execute()の実行中に保留になるためです。

これまで、loader.get()コマンドまたはloader.execute()メソッドのいずれかに対して新しいスレッドを作成し、そのスレッドでSwingUtilities.invokeLater()を呼び出しようとしましたが、プログラム全体がフリーズします。

SwingWorker.isDone()の場合にChangeListenerを作成してから、loader.get()を実行することを検討しましたが、これには、コードのやり直しが必要になります。

誰かがこれを機能させるための最良の方法を教えてもらえますか?

4

3 に答える 3

6

get()join()呼び出されるまでブロックし、SwingWorkerが終了するのを待ってから呼び出されるという点で似ています。間違って使用すると、そもそもSwingWorkerを使用することのすべての利点が完全に無効になる可能性があります。

解決策:get()SwingWorkerの処理が完了したことがわかるまで、SwingWorkerのdone()メソッドで呼び出すか、呼び出し元のコードから呼び出す必要がある場合は、SwingWorkerに追加されたPropertyChangeListenerで呼び出さないでください。 SwingWorkerの「state」プロパティがSwingWorker.StateValue.DONEの場合。

何かのようなもの:

  final FileLoader loader = new FileLoader(filePath);

  loader.addPropertyChangeListener(new PropertyChangeListener() {
     @Override
     public void propertyChange(PropertyChangeEvent evt) {
        if ("state".equals(evt.getPropertyName())) {
           // since DONE is enum, no need for equals(...) method
           if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
              try {
                 loader.get();
              } catch (InterruptedException e) {
                 e.printStackTrace();
              } catch (ExecutionException e) {
                 e.printStackTrace();
              }
           }
        }
     }
  });

  new ProgressWindow(loader, "Loading File", "Loading File");

注:コードはコンパイルもテストもされていません

編集:try/catchが追加されました。

于 2012-07-18T18:14:01.713 に答える
3

これまで、loader.get()コマンドまたはloader.execute()メソッドのいずれかに対して新しいスレッドを作成し、そのスレッドでSwingUtilities.invokeLater()を呼び出しようとしましたが、プログラム全体がフリーズします。

SwingUtilities.invokeLater()GUIをフリーズするEDTでスレッドを実行するスレッドを呼び出す場合。代わりに、そのメソッドを呼び出してスレッドを実行し、のプログレスバーを更新する必要がある場合にstart()のみ使用してください。SwingUtilities.invokeLater()PropertyChangeListener

于 2012-07-18T18:05:55.553 に答える
0

スレッドとGUIの現在/メインスレッドを処理するWorkerThreadクラスを作成しました。XXXServerを起動するイベントが発生したときにGUIアプリケーションをWorkerThreadのconstruct()メソッドに配置すると、すべてのスレッドがアクティブになり、GUIがフリーズすることなくスムーズに動作します。見てください。

/**
* Action Event
* 
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(ActionEvent ae) {
    log.info("actionPerformed begin..." + ae.getActionCommand());

    try {
        if (ae.getActionCommand().equals(btnStart.getText())) {
             final int portNumber = 9990;
             try {

                 WorkerThread workerThread = new WorkerThread(){
                    public Object construct(){

                        log.info("Initializing the Server GUI...");
                        // initializing the Server
                         try {
                            xxxServer = new XXXServer(portNumber);
                            xxxServer.start();
                            btnStart.setEnabled(false);                             
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            log.info("actionPerformed() Start button ERROR IOEXCEPTION..." + e.getMessage());
                            e.printStackTrace();
                        }
                        return null;
                    }
                };workerThread.start();
                } catch (Exception e) {
                    log.info("actionPerformed() Start button ERROR..." + e.getMessage());
                    e.printStackTrace();
             }


        } else if (ae.getActionCommand().equals(btnStop.getText())) {
            log.info("Exit..." + btnStop.getText());
            closeWindow();
        }

    } catch (Exception e) {
        log
            .info("Error in ServerGUI actionPerformed==="
                + e.getMessage());
    }

}
于 2014-12-23T12:25:32.163 に答える