I'm trying to make a Stopwatch
application, but I keep on running into the same runtime exceptions. I've been struggling with it for days, and I am not sure how to fix it. Any advice would be greatly appreciated! This is my first decent length project in Java, so I'm determined to figure it out; just having quite a bit of trouble, and I am unsure of how to get past this.
TimerStopWatch.java
import java.text.DecimalFormat;
import java.util.Optional;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.control.TextInputDialog;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.util.Duration;
class TimerStopWatch {
private ImageView dialImageView = new ImageView();
private ImageView handImageView = new ImageView();
private String dialImageName = "clockface.png";
private String handImageName = "hand.png";
private Image dialImage = new Image(getClass().getResourceAsStream(dialImageName));
private Image handImage = new Image(getClass().getResourceAsStream(handImageName));
private StackPane analogContainer = new StackPane();
private Text digitalLabel = new Text();
private Text timerLabel = new Text();
private Label championLabel = new Label();
private VBox timeInfoBox = new VBox();
private Label lapTimeLabel = new Label();
private Text record1Label = new Text();
private Text record2Label = new Text();
private Text record3Label = new Text();
private VBox recInfoBox = new VBox();
private HBox infoBox = new HBox();
private Button funcButton = new Button("Record");
private Button recButton = new Button("Start");
private HBox buttonsBox = new HBox();
private GridPane grid = new GridPane();
private double tickTimeInSeconds = 0.01;
private double angleDeltaPerSeconds = 6.0;
double secondsElapsed = 0;
private Timeline timeline;
private KeyFrame keyFrame;
private String timeInfo = "00:00.00";
private int timerStartTime = 60;
private double timerSecondsLeft = 60.00;
private int timeUpTag = 0;
private Alert notNumbersAlert = new Alert(Alert.AlertType.ERROR,"Insert only integers!", ButtonType.CLOSE);
private DecimalFormat dfTimer = new DecimalFormat("#.00");
private DecimalFormat dfRec = new DecimalFormat("00");
private double oldTime = 0.00;
private int numberOfRecords = 0;
public TimerStopWatch(){
setupTimer();
setupUI();
setupTimeline();
setupButtonAction();
}
private void setupTimer(){
TextInputDialog dialog = new TextInputDialog("");
dialog.setTitle("Timer Start Time Set Up");
dialog.setHeaderText("Set up the start time:");
dialog.setContentText("Please set up the start time (Integer):");
boolean legalTime = false;
while(!legalTime){
Optional<String> input = dialog.showAndWait();
if(input.isPresent()){
if((input.get().matches("[0-9]+") && input.get().length() > 0 ) == false){
notNumbersAlert.showAndWait();
}else{
timerStartTime = Integer.valueOf(input.get());
legalTime = true;
}
}
}
timerSecondsLeft = timerStartTime;
}
private void setupUI(){
dialImageView.setImage(dialImage);
handImageView.setImage(handImage);
analogContainer.getChildren().addAll(dialImageView, handImageView);
digitalLabel.setText(timeInfo);
digitalLabel.setFont(Font.font ("Verdana", 30));
timerLabel.setText("Timer: " + String.valueOf(timerSecondsLeft) + ".00");
timerLabel.setFont(Font.font ("Verdana", 20));
championLabel.setText("Champion: 00:00:00");
championLabel.setFont(Font.font ("Verdana", 20));
lapTimeLabel.setText("Lap Time");
lapTimeLabel.setFont(Font.font ("Verdana", 20));
record1Label.setText("Rec 00 +00:00.00");
record1Label.setFont(Font.font ("Verdana", 18));
record2Label.setText("Rec 00 +00:00.00");
record2Label.setFont(Font.font ("Verdana", 18));
record3Label.setText("Rec 00 +00:00.00");
record3Label.setFont(Font.font ("Verdana", 18));
infoBox.setAlignment(Pos.CENTER);
infoBox.setSpacing(20);
infoBox.getChildren().addAll(timeInfoBox, recInfoBox);
timeInfoBox.setAlignment(Pos.CENTER);
timeInfoBox.setSpacing(10);
timeInfoBox.getChildren().addAll(digitalLabel, timerLabel, championLabel);
recInfoBox.setAlignment(Pos.CENTER);
recInfoBox.setSpacing(5);
recInfoBox.getChildren().addAll(lapTimeLabel, record1Label, record2Label, record3Label);
buttonsBox.setAlignment(Pos.CENTER);
buttonsBox.setSpacing(10);
buttonsBox.getChildren().addAll(funcButton, recButton);
grid.setVgap(30);
grid.setHgap(10);
grid.setAlignment(Pos.CENTER);
grid.add(analogContainer, 0, 0);
grid.add(infoBox, 0, 1);
grid.add(buttonsBox, 0, 2);
}
private void setupTimeline(){
if(isRunning()){
timeline.stop();
}
keyFrame = new KeyFrame(Duration.millis(tickTimeInSeconds*1000), (ActionEvent event) -> {
update();
});
timeline = new Timeline(keyFrame);
timeline.setCycleCount(Animation.INDEFINITE);
}
private void setupButtonAction(){
recButton.setOnAction((ActionEvent event) -> {
if(timeline.getStatus() != Animation.Status.RUNNING){
timeline.play();
recButton.setText("Stop");
funcButton.setText("Record");
}else {
timeline.stop();
recButton.setText("Start");
funcButton.setText("Reset");
}
});
funcButton.setOnAction((ActionEvent event) -> {
if(timeline.getStatus() == Animation.Status.RUNNING){
if(timerLabel.getText() != "Time's Up!"){
numberOfRecords++;
if(numberOfRecords == 1){
championLabel.setText("Champion: " + getMessage(secondsElapsed));
}
if((numberOfRecords % 3) == 1){
record1Label.setText("Rec " + dfRec.format(numberOfRecords) + " +" + getMessage(secondsElapsed - oldTime));
}else if ((numberOfRecords % 3) == 2){
record2Label.setText("Rec " + dfRec.format(numberOfRecords) + " +" + getMessage(secondsElapsed - oldTime));
}else{
record3Label.setText("Rec " + dfRec.format(numberOfRecords) + " +" + getMessage(secondsElapsed - oldTime));
}
oldTime = secondsElapsed;
}else{
timeUp();
}
}else{
reset();
}
});
}
public void timeUp(){
Alert alert = new Alert(Alert.AlertType.INFORMATION, "Time is up... No more records...");
alert.setTitle("Time is up!!!");
alert.setHeaderText("Alert");
alert.show();
}
public void reset(){
secondsElapsed = 0.0;
timerSecondsLeft = timerStartTime;
handImageView.setRotate(0.0);
funcButton.setText("Record");
digitalLabel.setText("00:00:00");
timerLabel.setText("Timer: " + String.valueOf(timerSecondsLeft) + ".00");
championLabel.setText("Champion: 00:00.00");
record1Label.setText("Rec 00 +00:00.00");
record2Label.setText("Rec 00 +00:00.00");
record3Label.setText("Rec 00 +00:00.00");
timeUpTag = 0;
numberOfRecords = 0;
oldTime = 0.00;
}
public boolean isRunning(){
if(timeline != null){
if(timeline.getStatus() == Animation.Status.RUNNING){
return true;
}
}
return false;
}
public void update(){
secondsElapsed += tickTimeInSeconds;
double rotation = secondsElapsed * angleDeltaPerSeconds;
handImageView.setRotate(rotation);
digitalLabel.setText(getMessage(secondsElapsed));
timerSecondsLeft -= tickTimeInSeconds;
if(timerSecondsLeft <= 0.0 && timeUpTag == 0){
timerLabel.setText("Time's Up!");
timeUpTag = 1;
}else if(timeUpTag == 0){
timerLabel.setText("Timer: " + dfTimer.format(timerSecondsLeft));
}
}
public String getMessage(double secondsElapsed){
timeInfo = (String.format("%02d:", (int)secondsElapsed/60) +
String.format("%02d.", (int)secondsElapsed%60) +
String.format("%02d", (int)((secondsElapsed*100)%100)));
return timeInfo;
}
public Double getWidth(){
if(dialImage != null)
return dialImage.getWidth();
else
return 0.0;
}
public Double getHeight(){
if(dialImage != null)
return dialImage.getHeight();
else
return 0.0;
}
public Parent getRootGrid(){
return grid;
}
}
StopWatch.java
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class StopWatch extends Application {
@Override
public void start(Stage primaryStage) {
TimerStopWatch timerStopWatch = new TimerStopWatch();
Scene scene = new Scene(timerStopWatch.getRootGrid(),
timerStopWatch.getWidth() + 200,
timerStopWatch.getHeight() + 220);
primaryStage.setTitle("Timer Stopwatch");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Result
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoClassDefFoundError: stopwatch/TimerStopWatch
at stopwatch.StopWatch.start(StopWatch.java:24)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
... 1 more
Caused by: java.lang.ClassNotFoundException: stopwatch.TimerStopWatch
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 10 more