5

私のJavaGUIアプリには、がJButtonあり、クリックすると、functionに接続するためにadatabaseを呼び出し、次に、内のafunctionを呼び出し、次に、あるファイルからテキストを読み取るaを呼び出し、別のファイルからテキストを読み取るaを呼び出してロードします。両方から、そしてDB内のまたはデータのいずれかを呼び出します。これらはすべて正常に機能します。cleartableDBfunctionvariablesfunctiondatafunctionupdateinsert

しかし、私の質問はに関連してJButtonいます。クリックすると、ユーザーが作業が行われていることを認識できるように実行したいのですが、Indeterminate progress barそれが終了する直前にaction listener setIndeterminate to false、の値をに設定しますprogress bar100(complete)、私の場合はクリックするbuttonとクリック状態のままでprogress barフリーズします。

これを防ぐために何を実装する必要がありますか?おそらく糸脱毛?しかし、私はJavaでのスレッド化にまったく慣れていません。これが私のアクションリスナーです:

    private class buttonListener implements ActionListener
        {
            public void actionPerformed(ActionEvent e)
            {
                if( e.getSource() == genButton )
                {
                    progressBar.setIndeterminate(true);
                    progressBar.setString(null);
                    try 
                    {
                        dbConnect(); //connects to DB
                        clearSchedules(); // deletes data in tables
                        readFile(); // reads first file and calls the other functions
                        dbClose();// closes the DB
                        progressBar.setIndeterminate(false);
                        progressBar.setValue(100);
                    } 
                    catch (Exception e1){
                        System.err.println("Error: " + e1.getMessage());
                    }
                }
            }
        }

ちなみに、プログラムの進行に合わせて実際にアクションバーを動かしてもらいたいのですが、進行状況を監視する方法がわかりませんでした。

ありがとう、ビーフ。

ここでの更新 は、SwingWorkerの私の例とその使用方法です。

グローバルに宣言

 private functionWorker task;


    private abstract class functionWorker extends SwingWorker { 

        public void execute() {
            try {
                dbConnect();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            clearSchedules();
            try {
                readFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
            dbClose();
        }
    }

私のactionPerformedメソッドの内部

if( e.getSource() == genButton )
            {

                progressBar.setIndeterminate(true);
                progressBar.setString(null);
                try 
                {
                    task.execute();

                    progressBar.setIndeterminate(false);
                    progressBar.setValue(100);
                } 
                catch (Exception e1){
                    System.err.println("Error: " + e1.getMessage());
                }
            }
4

4 に答える 4

7

この問題は、UIスレッドでの高価な操作(データベースへの接続、ファイルからの読み取り、他の関数の呼び出し)に接続することに関連している可能性があります。いかなる状況でも、UIスレッドから過剰なCPU時間を使用するコードを呼び出さないでください。コードの実行中はインターフェイス全体を進めることができず、コンポーネントが次の状態のままで「デッド」に見えるアプリケーションになります。高価な操作が完了するまでの時間。別のスレッドを実行し、その中で高価な作業を行ってからSwingUtilities.invokeLater(Runnable doRun)、進行状況を更新するパスされたランナブルでを使用する必要があります。

コンポーネントの状態に関連する同期の問題がある可能性がありますが、これらは後で修正できます。

于 2011-09-23T14:58:40.500 に答える
6

アクションの実行時に新しいスレッドを作成してスレッド内の新しい関数を呼び出すことはできますか、それとも実際の関数自体の中でスレッド化を行う必要がありますか?

ここSwingWorkerに示すように、ボタンのハンドラーから開始できます。関連する実装例をここに示します。Runnable

于 2011-09-23T15:12:58.050 に答える
5

プログレスバーを処理する1つの方法SwingWorkerは、クラスで拡張することです。 SwingWorkerバックグラウンドタスクの実行を処理するため、不明な問題が発生する可能性のある独自のスレッドを実装する必要はありません。まず、プログレスバーUIを処理するクラスは、グローバル変数に基づいてプログレスバーのステータスを更新するために実装PropertyChangeListener および実装する必要があります。public void propertyChange(PropertyChangeEvent evt) {

バックグラウンドタスククラスは次のようになります(これは内部クラスである可能性があります):

class ProgressTask extends SwingWorker<Void, Void> {
        @Override
        public Void doInBackground() {
             //handle your tasks here
             //update global variable to indicate task status.
        }
        @Override
        public void done() {
             //re-enabled your button
        }
}

ボタンのイベントリスナー:

 public void actionPerformed(ActionEvent evt) {
    //disable your button
    //Create new instance of "ProgressTask"
    //make the task listen to progress changes by task.addPropertyChangeListener(this);
    //calll task.execute();
 }

私はコード例を骨抜きにしようとしました。これらすべての要素がどのように組み合わされているかを理解するには、チュートリアルを読む必要があります。ただし、重要な点は、スレッドをコーディングせず、代わりに使用することです。SwingWorker

于 2011-09-23T15:11:37.287 に答える
0
                    progressBar.setIndeterminate(true);
                    progressBar.setValue(0);                        
dbConnect(); //connects to DB
                    progressBar.setIndeterminate(true);
                    progressBar.setValue(10);
                    clearSchedules(); // deletes data in tables
                    progressBar.setIndeterminate(true);
                    progressBar.setValue(50);
                    readFile(); // reads first file and calls the other functions
                    progressBar.setIndeterminate(true);
                    progressBar.setValue(75);
                    dbClose();// closes the DB
                    progressBar.setIndeterminate(false);
                    progressBar.setValue(100);

完了率がわからないため、進行状況バーにどの程度の進行状況があったかを通知する必要があります。さらに良いことに、ここでメソッド呼び出しを繰り返すのではなく、プログレスバーを更新して再描画するメソッドを記述します。

updateProgressBar(int progress, boolean isDeterminate, String msg){};

また、特定のボタンが実行されたアクションを実行していることを確認する必要があります。

class IvjEventHandler implements java.awt.event.ActionListener {
        public void actionPerformed(java.awt.event.ActionEvent e) {
            if (e.getSource() == JMyPanel.this.getJButtonUpdate()) 
                connEtoC1(e);
    };
};

connEtoC1(e); GUIから起動するのではなく、コントローラークラスまたはSwingWorkerを実行する必要があります

于 2011-09-23T15:12:59.433 に答える