引用ActionListener类的问题

时间:2013-02-20 15:55:09

标签: java swing timer actionlistener

我有问题将Timer引用到ActionListener类。我想在Java显示显示时间的对话框后停止计时器,并在单击“是”后再次启动。

这就是我目前所拥有的:

public class AlarmClock 
{
    public static void main(String[] args)
    {
        boolean status = true;

        Timer t = null;

        ActionListener listener = new TimePrinter(t);
        t = new Timer(10000, listener);

        t.start();

        while(status)
        {
        } 
    }
}

class TimePrinter implements ActionListener
{   
    Timer t;

    public TimePrinter(Timer t)
    {
        this.t = t;
    }
    public void actionPerformed(ActionEvent event)
    {   
        t.stop();                //To stop the timer after it displays the time

        Date now = Calendar.getInstance().getTime();
        DateFormat time = new SimpleDateFormat("HH:mm:ss.");

        Toolkit.getDefaultToolkit().beep();
        int choice = JOptionPane.showConfirmDialog(null, "The time now is "+time.format(now)+"\nSnooze?", "Alarm Clock", JOptionPane.YES_NO_OPTION);

        if(choice == JOptionPane.NO_OPTION)
        {
            System.exit(0);
        }
        else
        {
            JOptionPane.showMessageDialog(null, "Snooze activated.");
            t.start();           //To start the timer again
        }
    }
}

但是,此代码提供空指针异常错误。有没有其他方法可以引用Timer?

2 个答案:

答案 0 :(得分:2)

这里有鸡和蛋的问题,因为两个类的构造函数都需要相互引用。你需要以某种方式打破循环,最简单的方法是在没有监听器的情况下构造Timer,然后构造监听器,然后将其添加到计时器:

    t = new Timer(10000, null);
    ActionListener l = new TimePrinter(t);
    t.addActionListener(l);

或者,您可以将一个setter添加到TimePrinter,而不是将Timer传递给它的构造函数:

class TimePrinter implements ActionListener
{   
    Timer t;

    public TimePrinter() {}

    public setTimer(Timer t)
    {
        this.t = t;
    }

然后再做

    TimePrinter listener = new TimePrinter();
    t = new Timer(10000, listener);
    listener.setTimer(t);

无论哪种方式,最终结果都是一样的。

答案 1 :(得分:0)

您已经有计时器参考,因为您在计时器上下文中工作。其他参考仅导致您的示例中出现的新问题。使用ActionEventgetSource()方法:

ActionListener actionListener = new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
        Timer timer = (Timer) e.getSource();

        timer.stop();
    }
};
Timer timer = new Timer(100, actionListener);
timer.start();

之后你的例子可能是这样的:

import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.swing.JOptionPane;
import javax.swing.Timer;

public class Program {

    public static void main(String[] args) throws InterruptedException {
        Timer timer = new Timer(1000, new TimePrinter());
        timer.start();

        Thread.sleep(10000);
    }
}

class TimePrinter implements ActionListener {

    public void actionPerformed(ActionEvent event) {
        Timer timer = (Timer) event.getSource();
        timer.stop(); // To stop the timer after it displays the time

        Date now = Calendar.getInstance().getTime();
        DateFormat time = new SimpleDateFormat("HH:mm:ss.");

        Toolkit.getDefaultToolkit().beep();
        int choice = JOptionPane.showConfirmDialog(null, "The time now is " + time.format(now) + "\nSnooze?", "Alarm Clock", JOptionPane.YES_NO_OPTION);

        if (choice == JOptionPane.NO_OPTION) {
            System.exit(0);
        } else {
            JOptionPane.showMessageDialog(null, "Snooze activated.");
            timer.start(); // To start the timer again
        }
    }
}