2013-02-20 56 views
2

我有问题引用Timer的ActionListener类。我想在Java显示显示时间的对话框并在点击“Yes”后重新开始之后停止定时器。ActionListener类引用问题

这是我目前有:

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 
     } 
    } 
} 

然而,这个代码给出了一个空指针异常错误。有没有其他方法可以引用定时器?

回答

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

无论哪种方式的端部r esult是一样的。

+0

有完全相同的鸡与鸡蛋问题,这是一个很好的解决方案,谢谢! – sage88 2013-09-28 23:14:31

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 
     } 
    } 
}