2015-05-26 81 views
0

我想創建5秒後啓動的秒錶。沒有計時器,它的工作原理是完美的,但是當我在Task類中放入方法startStopwatch()時,它負責在時間過去後執行任務,我得到一個錯誤。我會很高興的解釋我做錯了什麼,或者是否有更好的方法去做。 這是我的代碼。帶計時器的Java秒錶

import java.lang.reflect.InvocationTargetException; 
import java.util.Timer; 
import java.util.TimerTask; 
import javax.swing.SwingUtilities; 


public class Stopwatch extends javax.swing.JFrame implements Runnable{ 

private javax.swing.JLabel Display; 
private javax.swing.JButton StartButton; 
private javax.swing.JButton StopButton; 

private final static java.text.SimpleDateFormat timerFormat = new java.text.SimpleDateFormat("mm : ss.SSS"); 
private long elapsed; 
private long startTime; 
private Thread updater; 
private boolean isRunning= false; 
private Timer timer; 

public Stopwatch() { 
    initComponents(); 
} 

private void initComponents() { 

    Display = new javax.swing.JLabel(); 
    StartButton = new javax.swing.JButton(); 
    StopButton = new javax.swing.JButton(); 

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

    Display.setText("00 : 00.000"); 

    StartButton.setText("Start"); 
    StartButton.addActionListener(new java.awt.event.ActionListener() { 
     public void actionPerformed(java.awt.event.ActionEvent evt) { 
      StartButtonActionPerformed(evt); 
     } 
    }); 

    StopButton.setText("Stop"); 
    StopButton.addActionListener(new java.awt.event.ActionListener() { 
     public void actionPerformed(java.awt.event.ActionEvent evt) { 
      StopButtonActionPerformed(evt); 
     } 
    }); 

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
    getContentPane().setLayout(layout); 
    layout.setHorizontalGroup(
     layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
     .addGroup(layout.createSequentialGroup() 
      .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
       .addGroup(layout.createSequentialGroup() 
        .addGap(131, 131, 131) 
        .addComponent(StartButton) 
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 
        .addComponent(StopButton)) 
       .addGroup(layout.createSequentialGroup() 
        .addGap(165, 165, 165) 
        .addComponent(Display))) 
      .addContainerGap(147, Short.MAX_VALUE)) 
    ); 
    layout.setVerticalGroup(
     layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
     .addGroup(layout.createSequentialGroup() 
      .addGap(124, 124, 124) 
      .addComponent(Display) 
      .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 
      .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 
       .addComponent(StartButton) 
       .addComponent(StopButton)) 
      .addContainerGap(133, Short.MAX_VALUE)) 
    ); 

    pack(); 
    setLocationRelativeTo(null); 
}      

private void StopButtonActionPerformed(java.awt.event.ActionEvent evt) {           
    stopStopwatch(); 
}           

private void StartButtonActionPerformed(java.awt.event.ActionEvent evt) {            
    //startStopwatch(); 
    new Stopwatch(5); 
}           

public static void main(String args[]) { 

    java.awt.EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      new Stopwatch().setVisible(true); 
     } 
    }); 
} 

//STOPWATCH 
@Override 
public void run() { 
    try{ 
     while(isRunning){ 
      SwingUtilities.invokeAndWait(displayUpdater); 
      Thread.sleep(10); 
     } 
    }catch(InterruptedException e){ 
     e.printStackTrace(); 
    } catch (InvocationTargetException ex) { 
     ex.printStackTrace(); 
    } 
} 

private final Runnable displayUpdater= new Runnable() { 
    public void run(){ 
     displayElapsedTime(System.currentTimeMillis() - Stopwatch.this.startTime); 
    } 
}; 

private void displayElapsedTime (long elapsedTime1){ 
    Display.setText(timerFormat.format(new java.util.Date(elapsedTime1))); 
} 
public void startStopwatch(){ 
    System.out.println("2:Start stopwatch."); 
    startTime= System.currentTimeMillis(); 
    isRunning = true; 
    updater = new Thread(this); 
    updater.start(); 
} 
private void stopStopwatch(){ 
    System.out.println("3:Stop stopwatch."); 
    elapsed = System.currentTimeMillis() - startTime; 
    isRunning= false; 
    try{ 
     updater.join(); 
    }catch(InterruptedException ie){ 
     ie.printStackTrace(); 
    } 
    displayElapsedTime(elapsed); 
} 

//TIMER 
public Stopwatch(int seconds){ 
    timer = new Timer(); 
    timer.schedule(new Task(), seconds * 1000); 
} 

class Task extends TimerTask{ 
    @Override 
    public void run() { 
     System.out.println("1:Timer has finished."); 
     timer.cancel(); 
     startStopwatch(); 
    } 
} 

}

這裏是一個錯誤,當您使用秒錶的構造定時器

java.lang.reflect.InvocationTargetException 
at java.awt.EventQueue.invokeAndWait(Unknown Source) 
at java.awt.EventQueue.invokeAndWait(Unknown Source) 
at javax.swing.SwingUtilities.invokeAndWait(Unknown Source) 
at test.Stopwatch.run(Stopwatch.java:105) 
at java.lang.Thread.run(Unknown Source) 
Caused by: java.lang.NullPointerException 
at test.Stopwatch.displayElapsedTime(Stopwatch.java:122) 
at test.Stopwatch.access$1(Stopwatch.java:121) 
at test.Stopwatch$1.run(Stopwatch.java:117) 
at java.awt.event.InvocationEvent.dispatch(Unknown Source) 
at java.awt.EventQueue.dispatchEventImpl(Unknown Source) 
at java.awt.EventQueue.access$500(Unknown Source) 
at java.awt.EventQueue$3.run(Unknown Source) 
at java.awt.EventQueue$3.run(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
at java.awt.EventQueue.dispatchEvent(Unknown Source) 
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) 
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) 
at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
at java.awt.EventDispatchThread.run(Unknown Source) 
+0

你的錯誤是什麼? – Juru

+3

你得到的錯誤是什麼。請發佈它,以便我們可以幫助你。 –

+0

心靈讀書http://sscce.org/? – steffen

回答

0

你的顯示元素是空的。出於某種原因,您創建了一個新的秒錶並且不要初始化它。所以你想改變的Display元素爲null。

//TIMER 
public StopWatch(int seconds) { 
    timer = new Timer(); 
    timer.schedule(new Task(), seconds * 1000); 
} 

構造函數應該包含initComponents()以避免產生nullpointer異常。但我不確定它會在功能上做你想做的事情。

//TIMER 
public StopWatch(int seconds) { 
    initComponents(); 
    timer = new Timer(); 
    timer.schedule(new Task(), seconds * 1000); 
} 

這樣做的結果就是您不會再看到錯誤。但是在原始屏幕上也不會發生任何事情。如果您想查看發生了什麼,則需要將其顯示出來。所以它應該看起來像這樣。

//TIMER 
public StopWatch(int seconds) { 
    initComponents(); 
    setVisible(true); 
    timer = new Timer(); 
    timer.schedule(new Task(), seconds * 1000); 
} 

這使得新窗口可見,所以一個單獨的秒錶。這可能或可能不是你想要的?

0

stacktrace顯示方法displayElapsedTime中存在NullPointerException。 這是一種單行方法,所以不應該很難找到問題。添加Display和timerFormat的調試打印。其中之一未被正確初始化