2015-05-26 129 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的调试打印。其中之一未被正确初始化