如何停止计时器的actionPerformed()方法?

时间:2012-07-18 11:42:25

标签: java swing user-interface timer

我正在实现一个javax.swing.timer来调用GUI上的同步操作。但是,该操作需要一些时间才能完成,我想为该定时器调用提供一个中止选项。这可能吗?

THX!

import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JMenu;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Iterator;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.swing.JTextField;
import org.omg.CosNaming.IstringHelper;


public class vtm extends JPanel implements ActionListener{

    private JFrame frame;
    private String children[];
    private ConsoleApp hawk[];
    public static String data[][];
    public Timer timer;
    private int count1, count2;
    private int i;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    vtm window = new vtm();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public vtm() {
        timer = new Timer(25000, this);
        //timer.setInitialDelay(190);
        timer.start();
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {

        frame = new JFrame("VTM");
        frame.setSize(1024, 720);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);

        JLabel lblNewLabel_1 = new JLabel("");
        lblNewLabel_1.setIcon(new ImageIcon("config.png"));
        lblNewLabel_1.setBounds(970, 0, 51, 55);
        frame.getContentPane().add(lblNewLabel_1);
        lblNewLabel_1.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                config x = new config();
                x.main(null);
                timer.stop();
                frame.dispose();
            }
            });

        JLabel lblNewLabel = new JLabel("");
        lblNewLabel.setIcon(new ImageIcon("bg.png"));
        lblNewLabel.setBounds(0, 0, 1024, 720);
        frame.getContentPane().add(lblNewLabel);


        String dir = System.getProperty("user.dir");

        File df = new File(dir);

        FilenameFilter fi = new FilenameFilter(){
            public boolean accept(File df, String name){
                return name.startsWith("D-");
            }
        };

        children = df.list(fi);
        hawk=new ConsoleApp[children.length];

        EventQueue.invokeLater(new Runnable(){
            public void run(){

                int count1 = 0; count2 = 0;

                for(i=0;i<children.length;i++)
                {


                hawk[i]=new ConsoleApp(children[i]);

                Iterator<String> it = hawk[i].p.iterator();

                System.out.println("Hi:"+hawk[i].p.size());

                while(it.hasNext())
                {
                    hawk[i].call(it.next());

                    if(count1 == 3)
                    {
                        count2++;
                        count1=0;
                    }

                    System.out.println("Look: " + hawk[i].l.getText().length());
                    hawk[i].l.setBounds((60 + 270*count1) + ((260-(hawk[i].l.getText().length()*7))/2), (70+(count2*60)), 260, 62);
                    hawk[i].c.setBounds(50 + 270*count1, (70+(count2*60)), 273, 62);
                    frame.getContentPane().add(hawk[i].c,0);
                    frame.getContentPane().add(hawk[i].l,0);

                    count1++;
                }
            }
            }
        });
    }

    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub
        System.out.println("lol");

        EventQueue.invokeLater(new Runnable(){
                public void run(){

                    int count1 = 0; count2 = 0;

                    for(i=0;i<children.length;i++)
                    {


                    hawk[i]=new ConsoleApp(children[i]);

                    Iterator<String> it = hawk[i].p.iterator();

                    System.out.println("Hi:"+hawk[i].p.size());

                    while(it.hasNext())
                    {
                        hawk[i].call(it.next());

                        if(count1 == 3)
                        {
                            count2++;
                            count1=0;
                        }

                        hawk[i].l.setBounds((60 + 270*count1) + ((260-(hawk[i].l.getText().length()*7))/2), (70+(count2*60)), 260, 62);
                        hawk[i].c.setBounds(50 + 270*count1, (70+(count2*60)), 273, 62);
                        frame.getContentPane().add(hawk[i].c,0);
                        frame.getContentPane().add(hawk[i].l,0);

                        count1++;
                    }
                }
                }
            });


    }


}

3 个答案:

答案 0 :(得分:2)

你的actionPerformed会触发一个Runnable,我认为这需要花费很长时间以及你想要中止的内容。在Runnable的run方法中,你有两个循环,for(i=0;i<children.length;i++)while(it.hasNext())。如果为这些循环添加停止条件,则可以通过从外部控制该条件来提前完成Runnable完成。

例如,向vtm添加字段abort,并将两个循环分别更改为for(i=0;i<children.length && !abort;i++)while(it.hasNext() && !abort)。您现在可以将abort设置为true,并且Runnable将在下次尝试再次循环时停止。

答案 1 :(得分:2)

使用Swingworker而不是Runnable,这就是实现取消机制的方法:http://docs.oracle.com/javase/tutorial/uiswing/concurrency/cancel.html

另请参阅此问题:How do I use SwingWorker in Java?

答案 2 :(得分:0)

  

我正在实现一个javax.swing.timer来调用GUI上的同步操作。但是,该操作需要一些时间才能完成,我想为该定时器调用提供一个中止选项。这可能吗?

如果您想为您的用户提供UI以取消您在事件调度线程(EDT)运行时发布的Runnable,那么不,这是不可能的。

当您的Runnable代码开始执行时,您的UI将无响应,因为您的Runnable占用了UI线程(EDT)。因此,在Runnable完成之前,任何取消按钮或您想到的任何界面都不会对任何点击做出反应。

你可以在它开始运行之前取消它,但是你可以更好地投入时间来调查你是否真的必须在EDT上执行繁重的工作(通常答案是否定的)。最好对工作Thread执行所有繁重的计算/操作,并在/期间更新UI。 SwingWorker类就是为此而设计的,可以在网上找到许多使用它的例子(在javadoc,官方Swing教程和本网站上)