2016-09-01 11 views
-1

スイングの進捗バーを表示および増分し、進捗情報を表示し、データベース操作を実行するスレッドがあります。スレッドは、次のようにボタンのイベントから開始されます。Javaスレッドから抜け出す方法

`public class SetupPanel extends javax.swing.JFrame 
{ 
    private static Thread myThread = null; 
    private void initComponents() 
    { 
     setupPanel = new javax.swing.JPanel(); 
     setupBtn = new JButton("Save Setup"); 

     //.. all the other swing components needed.. 

     setupBtn.addActionListener(new ActionListener() 
     { 
      @Override 
      public void actionPerformed(ActionEvent e) 
      { 
       myThread = new Thread(new Runnable() 
       { 
       @Override 
       public void run() 
       {       
       try 
       { 
        //update db, progress bar, display messages, sleep 
         myThread.yield(); 
       } 
       catch (InterruptedException e) 
       { 
         Logger.getLogger(SwingProgressBar.class.getName()) 
         .log(Level.SEVERE, null, e); 
         System.exit(0); 
       } 

       } 
      }); 
      myThread.start(); 
      } 
     });` 

私はデータベースとプログレスバー上のすべての操作が終了した後に実行を停止するスレッドを好きですが、(Thread.stopのようです)もう使用できず、thread.yield()は動作しません。スレッドから抜け出す方法はわかりません。

私はこのようなエラーをキャッチしてスレッドを破ることができるという希望でスレッドの歩留まり後にゼロで割るなどのエラーを強制しましたが、これはどちらもうまくいかなかった。

+0

注意をそれを更新するSwingWorkerのを使用する方法についていくつかのコードをSwingWorker.を使用することができます直接(あなたは多くの競合状態に遭遇する可能性があります)。 UIスレッドでのみUI操作を行うことができます。 'EventQueue.invokeLater'を使用して、データベース更新スレッドからUIスレッドでいくつかの作業をスケジュールできます。 –

+0

スレッド**は、コードがなくなると終了するメソッドと同じように、プログラムフローが完了すると停止します。あなたの質問は、これが起こることを妨げているものを示していません。 –

+0

注: 'myThread.yield()'は 'myThread'に何もしません。それはそれを呼び出したスレッドで動作します。 'yield()'はインスタンスメソッドではありません: 'Thread'クラスの' static'メソッドです。 –

答えて

2

スレッドから確認できるブール値のフラグが親クラスにあります。

final private boolean doStop = false; 
private static Thread myThread = null; 

public void run() 
{       
    if (doStop) return; 
} 
0

スレッドが内部的にこれらの方法のいずれかを使用して停止することができます。

  • runメソッドがリターンサブルーチンを打ちます。
  • メソッドの実行が終了し、暗黙的に戻ります。

またThread.stop();

3

Swingコンポーネントは一度に1つのスレッドだけアクセスすることができる代わりに、Threadオブジェクトのinterrupt()メソッドを呼び出すことにより、外部からそれを行うことができます。一般に、このスレッドはイベントディスパッチスレッドです。あなたが並行性を必要とするとき、あなたは、他の場所からデータを取得し、プログレスバーで使用すると、プログレスバーを更新して、別のスレッドからのメッセージを更新することはできません

class Task extends SwingWorker<Void, Void> { 
    /* 
    * Main task. Executed in background thread.you can use it to communicate with database 
    */ 
    @Override 
    public Void doInBackground() { 
     Random random = new Random(); 
     int progress = 0; 
     //Initialize progress property. 
     setProgress(0); 
     while (progress < 100) { 
      //Sleep for up to one second. 
      try { 
       Thread.sleep(random.nextInt(1000)); 
      } catch (InterruptedException ignore) {} 
      //Make random progress. 
      progress += random.nextInt(10); 
      setProgress(Math.min(progress, 100)); 
     } 
     return null; 
    } 

    /* 
    * Executed in event dispatching thread 
    */ 
    @Override 
    public void done() { 
     // you can do any operation about swing component 
    } 
} 

// to execute the task and update the progress bar 
Task task = new Task(); 
    task.addPropertyChangeListener(new PropertyChangeListener(){ 

     /** 
     * Invoked when task's progress property changes. 
     */ 
     @Override 
     public void propertyChange(PropertyChangeEvent evt) { 
      if ("progress" == evt.getPropertyName()) { 
       int progress = (Integer) evt.getNewValue(); 
       progressBar.setValue(progress); 
       taskOutput.append(String.format(
         "Completed %d%% of task.\n", task.getProgress())); 
      } 

     } 

    }); 
    task.execute(); 
関連する問題