1

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

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();
            } 


        }
    });

编辑:代码现在在那里......

4

3 回答 3

2

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

我会使用 SwingWorker 来完成一项更耗时的任务,我希望在执行时更新用户。例如,假设我们有一个线程生成然后发送一组电子邮件消息,并且对于每封电子邮件,在 UI 中显示一些文本,以确认消息已发送或指示无法发送的原因。每条消息都可能将线程锁定一段时间。UI 不会与线程执行电子邮件任务同步更新。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;
        }
    }
}
于 2012-11-09T13:44:47.913 回答
0

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

-JCheckBox 被选中时,创建一个线程来执行任务,或者使用SwingWorker Class它来正确同步 UI 和非 UI 线程的工作。

于 2012-11-09T12:51:01.847 回答
0

这取决于任务。

如果任务在其他机器上的其他进程上,您可以简单地发送正确的消息。如果任务是同一应用程序中的一个单独线程,您可以执行 wxyz 建议的操作,或者您可以使用某种具有启动和停止线程能力的侦听器(线程始终相同,或者您每次都在创建一个新线程您选择复选框?)。

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

于 2012-11-09T12:56:11.697 回答