2

Java プログラムで Processbuilder を使用してバックエンドで外部プロセスを実行しています。プロセスの終了ステータスを取得するために process.waitFor を使用しています。バックエンド プロセスには、提供された入力に応じて時間がかかるため、プロセスが完了するまでの不確定な時間のプログレスバーを作成する必要があります。これは、バックエンドでプロセスが進行中であることをユーザーに通知するためのものです。

    try {
        button.setEnabled(false);
        this.progressbar.setVisible(true);
        this.progressbar.setIndeterminate(true);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        perform(this);
    }
}                                    

public void perform(JFrame f)
{
            String cmd[]={"cmd", "/c","a.exe:};
            ProcessBuilder pb = new ProcessBuilder(cmd);
            pb.directory(new File(dir_path));
            pb.redirectErrorStream(true);
            try {
                    p = pb.start();
                } catch (IOException ex) {
                    Logger.getLogger(execution.class.getName()).log(Level.SEVERE, null, ex);
                       }
            try
            {
               int exitVal = p.waitFor();
               if(exitVal>0)
               {
                   this.progressbar.setVisible(false);
                   this.progressbar.setIndeterminate(false);
                   this.button.setEnabled(true);
               }
               if(p.waitFor()==0)
               {
                   this.progressbar.setVisible(false);
                   this.progressbar.setIndeterminate(false);

                   JOptionPane.showMessageDialog(f,"Scan completed successfully.");
               }
             } catch (InterruptedException ex) {
    Logger.getLogger(execution.class.getName()).log(Level.SEVERE, null, ex);
}
}

Button は、呼び出しを呼び出すボタンの名前です。しかし、私が直面している問題は、関数呼び出しの実行がこれらのステートメントを実行せずに行われることです。

    try {
        button.setEnabled(false);
        this.progressbar.setVisible(true);
        this.progressbar.setIndeterminate(true);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

その機能の実行後、ボタンは無効になります。1)なぜそれが起こるのか知っていますか?2) 完了するまでバックエンドの進行状況を示すプログレスバーを作成するための解決策を教えてください。

前もって感謝します。

4

2 に答える 2

2

を使用することをお勧めしSwingWorkerます。このような問題のために作られています。これは私のコードベースからのいくつかのコードのスニペットです(vuiJFrameです):

vui.clearOutput();
vui.setOutput("Waiting for items to copy...\n"
            + "This could take several minutes. Please standby...");
vui.disableExit();
vui.disableInput();
vui.disableNext();
vui.showProgressBar();

// make thread so you can disable all options when zipping and enable progress bar
SwingWorker transferWorker = new SwingWorker() {
    @Override
    protected Void doInBackground() throws Exception {
        try {
            Process p = Runtime.getRuntime().exec("resources/bin/transferCopier.bat");

            StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), "ERROR");
            StreamGobbler outputGobbler = new StreamGobbler(p.getInputStream(), "OUTPUT");
            errorGobbler.start();
            outputGobbler.start();

            p.waitFor();
        } catch (IOException ex) {
            Logger.getLogger(VaderController.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InterruptedException ie) {
            Logger.getLogger(VaderController.class.getName()).log(Level.SEVERE, null, ie);
        }
        return null;
    }
    @Override
    public void done() {
        vui.hideProgressBar();
        vui.clearOutput();
        vui.setOutput("Transfer Complete!\n\n"
                    + "Push \"Exit\" to quit.\n\n");
        vui.enableExit();
        mode = VaderMode.END;
    }
};
transferWorker.execute();

transferWorker.execute();実行されると、doInBackground()が呼び出されます。doInBackground()の計算が完了すると、がdone()呼び出されます。done()GUI の最終的な更新を行う場所です。

上記のコードで重要なことは、実行前にプログレス バーを有効にし、SwingWorker実行SwingWorkerが完了したらプログレス バーを無効にすることです。

資力:

http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

于 2013-04-09T12:29:25.387 に答える