如何使复选框执行连续任务,直到它被取消选中?

时间:2012-11-09 12:36:34

标签: java swing jcheckbox

任何人都知道如何让复选框执行任务,直到它被取消选中?

JCheckBox chckbxInspecAuto = new JCheckBox("Inspe. Auto.");
chckbxInspecAuto.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0)
{
try {

      gimage = vision.grab();
      cvSaveImage("image001.bmp", gimage);
      ipanel.loadImage("image001.bmp");


            } catch (com.googlecode.javacv.FrameGrabber.Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 


        }
    });
编辑:代码就在那边......

3 个答案:

答案 0 :(得分:2)

您可以扩展SwingWorker类甚至Thread,以实现您希望复选框控制的功能。创建方法contiueWorking()stopWorking()并在run方法中检查一些布尔标志以查看是执行任务还是休眠。 正如Robin在下面的帖子中评论的那样,只能从Event Worker Thread访问swing组件。我在下面的示例中违反了这个规则,因为我想生成一些简单的东西,因为正在运行的线程大部分时间都在休眠,所以它工作正常。

我会使用SwingWorker进行更耗时的任务,我希望在执行时更新用户。例如,假设我们有一个线程生成然后发送一组电子邮件消息,并且对于每个电子邮件,在UI中显示一些确认消息已发送的文本或指示其无法传递的原因。每条消息都可能会将线程锁定一段时间。 UI不会与Thread执行电子邮件任务同步更新。 SwingWorker救援。 java2s.com网站有一个SwingWokerDemo

import java.awt.BorderLayout;
import javax.swing.*;
import java.awt.event.*;
import java.util.ArrayList;

/**
 *  The sequence of prime integers is calculated and displayed on the screen.
 *  This little program demonstrates how a checkbox can be used
 *  to start and stop a thread. 
 */
public class ThreadDemo extends JFrame {

    JCheckBox runningCB;
    JTextArea displayArea;
    JTextField delayField;
    PrimeCalcThread workerThread = null;
    public ThreadDemo() {
        super("Prime Numbers");
        runningCB = new JCheckBox("Calculate Primes");
        JPanel topPanel = new JPanel();
        topPanel.add(runningCB);
        topPanel.add(new JLabel("Dealy: "));
        delayField = new JTextField(10);
        delayField.setText("500");
        topPanel.add(delayField);
        getContentPane().add(topPanel,BorderLayout.NORTH);

        displayArea = new JTextArea(30,80);
        displayArea.setText("2, 3, 5, ");
        displayArea.setLineWrap(true);
        JScrollPane scroller = new JScrollPane(displayArea);
        getContentPane().add(scroller,BorderLayout.CENTER);
        pack();

        runningCB.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if(runningCB.isSelected() ) {
                    if(workerThread != null)
                        workerThread.contiueWorking();
                    else {
                        workerThread = new PrimeCalcThread();
                        workerThread.start();
                    }
                }
                else {
                   if(workerThread != null)
                       workerThread.stopWorking(); 
                }
            }
        });
        delayField.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String input = delayField.getText().trim();
                try {
                    int d = Integer.parseInt(input);
                    workerThread.setDelay(d);
                }
                catch(NumberFormatException nfe) { }
            }
        });
        setVisible(true);
    }

    public static void main(String[] arg) {
        ThreadDemo window = new ThreadDemo();
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    /**
     * When this thread is active it calculates prime numbers. The Thread 
     * continues until it is paused with stopWorking() or until the 
     * boolean field endThread is set to true.
     */
    class PrimeCalcThread extends Thread {
        ArrayList<Integer> primeList;
        int delay = 500;
        boolean active = true;
        boolean endThread = false;
        private int lastPrime;

        public PrimeCalcThread() {
            primeList = new ArrayList<> (1024);
            primeList.add(2); primeList.add(3); primeList.add(5);
            lastPrime=5;
        }

        public void run() {
            while(!endThread) {
                if(active) {
                    calcNextPrime();
                    displayArea.append(lastPrime + ", ");
                }
                try { sleep(delay);  }
                catch(InterruptedException whatever) { }
            }
        }

        private void calcNextPrime() {
            int p = lastPrime+2;
            while(!isPrime(p))
                p+=2;
            primeList.add(p);
            lastPrime = p;
        }

        /**
         * Checks if p is prime by checking for divisibility by all primes in the
         * calculated primeList so far. This method only works if sqrt(p) < lastPrime
         */
        private boolean isPrime(int p) {
            int maxCheck = (int) Math.sqrt(p) + 1;
            for(int prime: primeList) {
                if(p % prime == 0)
                    return false;
                if(prime > maxCheck)
                    break;
            }
            return true;
        }

        public int getLastPrime() {
            return lastPrime;
        }

        public ArrayList<Integer> getPrimeList() {
            return primeList;
        }

        public int getDelay() {
            return delay;
        }

        public void setDelay(int waitTime) {
            if(waitTime>=0)
                delay = waitTime;
        }

        public void contiueWorking() {
            active=true;
        }
        public void stopWorking() {
            active=false;
        }
    }
}

答案 1 :(得分:0)

- 创建一个守护程序线程并在无限循环中运行它,让它继续使用isSelected()方法或ItemListener检查是否检查了JCheckBox。 / p>

- JCheckBox 被选中然后创建一个帖子来执行任务使用SwingWorker Class正确同步UI和非UI线程的工作。

答案 2 :(得分:0)

这取决于任务。

如果任务在其他计算机上的其他进程中,您只需发送正确的消息即可。 如果任务是同一个应用程序中的分离线程,你可以做wxyz建议的,或者你可以使用某种类型的Listener来启动和停止Thread(线程总是相同的,或者你每次都在创建一个新的你选择了复选框吗?)。

我最喜欢的是以“PUSH”的方式使用Observer模式,所以你会在线程中使用某种外部信号,当发送时它会创建和/或停止它。