About this question
I made a simple JavaFX app. It is just a Pomodoro timer, it works as expected.
The Pomodoro study pattern is a technique where you study for 25 minutes and take a 5-minute break and after 4 periods of this, you get a longer 15-minute break (and then repeat the whole thing). I made a simple countdown timer that keeps track of which study session you are on.
I am just wondering if I implemented the MVC pattern correctly. The Main class seems a bit redundant to me. Are there any other improvements I could make to the code?
Thanks
public class Controller {
public Controller(Model model, View view) {
view.getStartPauseBtn().setOnAction((e) -> {
if (model.isRunning()) {
model.pauseTimer();
model.setRunning(false);
} else {
model.startTimer();
model.setRunning(true);
}
});
}
}
import javafx.application.Platform;
import javafx.scene.control.Label;
import java.util.Timer;
import java.util.TimerTask;
public class Model {
private boolean isRunning = false;
private boolean isBreak = false;
private Timer timer = new Timer();
private int counter = 60 * 25; // 60 * 25 Testing:10
private final Label timerLbl, studySessionLbl, whatsNextLbl;
private int seconds, minutes, studySessionNum =0;
public Model(Label timerLbl, Label studySessionLbl, Label whatsNextLbl) {
this.timerLbl = timerLbl;
this.studySessionLbl = studySessionLbl;
this. whatsNextLbl = whatsNextLbl;
}
public boolean isRunning() {
return isRunning;
}
public void setRunning(boolean running) {
isRunning = running;
}
public void pauseTimer() {
timer.cancel();
}
public void startTimer() {
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
Platform.runLater(() -> {
counter--;
seconds = counter `;
minutes = counter / 60;
if (seconds < 10> timerLbl.setText("0" + minutes + ":0" + seconds);
} else if (minutes < 10> timerLbl.setText("0" + minutes + ":" + seconds);
} else {
timerLbl.setText(minutes + ":" + seconds);
}
if (counter == 0 && studySessionNum == 4 && !isBreak) { // long break
isBreak = true;
counter = 15 * 60; // 15 * 60 Testing: 5
studySessionNum = 0;
} else if (counter == 0 && !isBreak) { // short break
counter = 5 * 60; // 5 * 60 Testing: 2
isBreak = true;
} else if (counter == 0) { // break finished
counter = 25 * 60; // 25 * 60 Testing: 10
studySessionNum++;
isBreak = false;
}
// update labels
studySessionLbl.setText("Study session number: " + studySessionNum);
if (isBreak) {
whatsNextLbl.setText("Next: Study session (25 minutes)");
} else if (studySessionNum == 4) {
whatsNextLbl.setText("Next: Long study break (15 minutes)");
} else {
whatsNextLbl.setText("Next: Short study break (5 minutes)");
}
});
}
}, 0, 1000);
}
}
Main class:
import javafx.application.Application;
import javafx.stage.Stage;
public class Pomodoro extends Application {
@Override
public void start(Stage stage) {
View view = new View();
Model model = new Model(view.getTimerLbl(), view.getStudySessionNumLbl(), view.getWhatsNextLbL());
new Controller(model, view);
stage.setTitle("Pomodoro Timer");
stage.setScene(view.getScene());
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I did not use a fxml file for the view.
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
public class View {
private final Label studySessionNumLbl, whatsNextLbL, timerLbl;
private final Button startPauseBtn;
private final Scene scene;
// UI Setup
public View() {
studySessionNumLbl = new Label();
whatsNextLbL = new Label();
HBox hbox = new HBox(studySessionNumLbl, whatsNextLbL);
hbox.setAlignment(Pos.CENTER);
hbox.setSpacing(10);
timerLbl = new Label("25:00");
timerLbl.setFont(Font.font("Verdana", FontWeight.BOLD, 70));
startPauseBtn = new Button("> ||");
VBox vbox = new VBox(timerLbl, startPauseBtn, hbox);
vbox.setAlignment(Pos.CENTER);
vbox.setSpacing(20);
scene = new Scene(vbox, 400, 400);
}
public Scene getScene() {
return scene;
}
public Label getStudySessionNumLbl() {
return studySessionNumLbl;
}
public Label getWhatsNextLbL() {
return whatsNextLbL;
}
public Button getStartPauseBtn() {
return startPauseBtn;
}
public Label getTimerLbl() {
return timerLbl;
}
}