2010-12-20 138 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()定期检查自己的中断状态,并在请求时干净地退出。