2010-12-20 137 views
0

我想知道它是怎麼回事stop a 線程GUI。我認爲如果線程是在製作按鈕之前創建的,我會很好,但我也試圖放入JProgressBar,以便我可以更新它。所以現在我被困在如何做到這一點。如果你能幫上忙,那會很好。如何從GUI按鈕停止線程?

在此先感謝!

代碼:

import java.awt.Dimension; 
import java.awt.Toolkit; 
import java.awt.datatransfer.Clipboard; 
import java.awt.datatransfer.StringSelection; 
import javax.swing.JOptionPane; 

public class mainJFrame extends javax.swing.JFrame { 

    //set Global variables 
    Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); 
    final int screenH = dim.height, screenW = dim.width; 
    private volatile boolean isStop = true; 

    public mainJFrame() { 
     initComponents(); 
    } 

    @SuppressWarnings("unchecked")       
    private void initComponents() { 

     jProgressBar1 = new javax.swing.JProgressBar(); 
     jLabel1 = new javax.swing.JLabel(); 
     jTextField1 = new javax.swing.JTextField(); 
     jButton1 = new javax.swing.JButton(); 
     jButton2 = new javax.swing.JButton(); 
     jMenuBar1 = new javax.swing.JMenuBar(); 
     jMenu1 = new javax.swing.JMenu(); 
     jMenuItem1 = new javax.swing.JMenuItem(); 

     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
     setTitle("Zeveso's MD5 Cracker"); 
     setBounds(new java.awt.Rectangle(200, 200, 0, 0)); 
     setResizable(false); 

     jLabel1.setText("MD5:"); 

     jButton1.setText("Start"); 
     jButton1.addActionListener(new java.awt.event.ActionListener() { 
      public void actionPerformed(java.awt.event.ActionEvent evt) { 
       jButton1ActionPerformed(evt); 
      } 
     }); 

     jButton2.setText("Stop"); 
     jButton2.addActionListener(new java.awt.event.ActionListener() { 
      public void actionPerformed(java.awt.event.ActionEvent evt) { 
       jButton2ActionPerformed(evt); 
      } 
     }); 

     jMenu1.setText("File"); 

     jMenuItem1.setText("Create MD5"); 
     jMenuItem1.addActionListener(new java.awt.event.ActionListener() { 
      public void actionPerformed(java.awt.event.ActionEvent evt) { 
       jMenuItem1ActionPerformed(evt); 
      } 
     }); 
     jMenu1.add(jMenuItem1); 

     jMenuBar1.add(jMenu1); 

     setJMenuBar(jMenuBar1); 

     javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
     getContentPane().setLayout(layout); 
     layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
       .addContainerGap() 
       .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
        .addComponent(jProgressBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 234, Short.MAX_VALUE) 
        .addGroup(layout.createSequentialGroup() 
         .addComponent(jLabel1) 
         .addGap(18, 18, 18) 
         .addComponent(jTextField1, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE)) 
        .addGroup(layout.createSequentialGroup() 
         .addComponent(jButton1) 
         .addGap(18, 18, 18) 
         .addComponent(jButton2))) 
       .addContainerGap()) 
     ); 
     layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
       .addContainerGap() 
       .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 
        .addComponent(jLabel1) 
        .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 
       .addGap(18, 18, 18) 
       .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 
        .addComponent(jButton1) 
        .addComponent(jButton2)) 
       .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 29, Short.MAX_VALUE) 
       .addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE) 
       .addContainerGap()) 
     ); 

     pack(); 
    }      

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {           
     if(isStop == true){ 
     jProgressBar1.setIndeterminate(true); 
     myMDThread.start(); 
     isStop = false; 
     } 
     else{ 
      System.out.println("Already running!"); 
     } 
    }           

    private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {           
     createMD5 myMD = new createMD5(); 
     String myPass = JOptionPane.showInputDialog(null, "Please put your password!"); 
     myPass = myMD.getMD5(myPass); 
     JOptionPane.showMessageDialog(null, "MD5: " + myPass); 
     System.out.println(myPass); 
     Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 
     StringSelection stringSelection = new StringSelection(myPass); 
     clipboard.setContents(stringSelection, null); 
    }           

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {           
     jProgressBar1.setIndeterminate(false); 
     isStop = true; 
    }           


    public static void main(String args[]) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 

      public void run() { 
       new mainJFrame().setVisible(true); 
      } 
     }); 
    }     
    private javax.swing.JButton jButton1; 
    private javax.swing.JButton jButton2; 
    private javax.swing.JLabel jLabel1; 
    private javax.swing.JMenu jMenu1; 
    private javax.swing.JMenuBar jMenuBar1; 
    private javax.swing.JMenuItem jMenuItem1; 
    private javax.swing.JProgressBar jProgressBar1; 
    private javax.swing.JTextField jTextField1;     
} 

回答

1

你有你的線程的來源?

一般而言,除非您有能力這樣做,否則無法停止線程。例如,你的線程可能會暴露像stopProcessing這樣的方法,當被調用時,它會設置一個標誌。您的線程的run方法會定期檢查此標誌以查看是否應該停止。

如果你有一點工作不能很好地映射到這一點,那麼你唯一的選擇就是忽略線程,隱藏進度條,並給出線程已經停止的錯覺。

+0

同意你的觀點的主旨,但是沒有必要定義你自己的旗幟和方法。這正是'Thread.interrupt'和'Thread.interrupted'方法的用處。 – 2010-12-20 01:34:29

+0

@Neil Bartlett - 除了Java 1.5有一個災難性的錯誤,如果中斷的線程碰巧在ClassLoader中,那麼它試圖加載的類將被永久標記爲ClassNotFound。 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4764778 – 2010-12-20 02:14:10

3

沒有安全的方法來強制線程停止(請參閱Thread.stop()方法上的JavaDoc以獲取更多解釋)。

最好的方法是致電interrupt方法,這是一個「合作」的停止。如果線程處於可中斷呼叫的中間,則它將拋出InterruptedException。如果線程是計算密集型的,那麼它應該使用Thread.interrupted()定期檢查自己的中斷狀態,並在請求時乾淨地退出。