2013-02-20 72 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 
     } 
    } 
}