Skip to content

Commit

Permalink
spaghetti code style intensifies
Browse files Browse the repository at this point in the history
  • Loading branch information
octo-kumo committed Aug 10, 2020
1 parent 3be4b50 commit 6adde25
Show file tree
Hide file tree
Showing 10 changed files with 185 additions and 50 deletions.
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {
}

group 'app.nush'
version '1.3.8-beta'
version '1.3.9-beta'

applicationName = 'Exam Clock'
mainClassName = 'app.nush.examclock.Main'
Expand All @@ -20,7 +20,7 @@ repositories {
// }
}

double jdkVersion = 1.8
double jdkVersion = 1.14
println "JDK version = ${jdkVersion}"

sourceCompatibility = 1.14
Expand All @@ -33,7 +33,7 @@ dependencies {
implementation "org.openjfx:javafx-graphics:11:win"
implementation "org.openjfx:javafx-graphics:11:mac"
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'no.tornado:tornadofx-controls:1.0.4'
implementation 'no.tornado:tornadofx-controls:1.0.6'
implementation 'io.socket:socket.io-client:1.0.0'
implementation group: 'com.dlsc.preferencesfx', name: 'preferencesfx-core', version: preferenceFx
}
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/app/nush/examclock/ExamClock.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
public class ExamClock extends Application {
public static Preferences preferences;
private static ExamClock instance;
private static Stage stage;
private MainController controller;

public static void main(String[] args) {
Expand All @@ -39,15 +40,19 @@ public static ExamClock getInstance() {
return instance;
}

public static Stage getStage() {
return stage;
}

@Override
public void start(Stage primaryStage) {
stage = primaryStage;
try {
instance = this;
preferences = Preferences.userNodeForPackage(ExamClock.class);
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml_main.fxml"));
Parent root = loader.load();
controller = loader.getController();
controller.setStage(primaryStage);
Scene scene = new Scene(root);
scene.getStylesheets().add("/main.css");
scene.getStylesheets().add("/theme.css");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package app.nush.examclock.controllers;

import app.nush.examclock.display.TimePicker;
import app.nush.examclock.model.Exam;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
Expand Down Expand Up @@ -41,12 +42,12 @@ public class AddExamController {
public DatePicker date_input;
public Spinner<Integer> duration_hours;
public Spinner<Integer> duration_minutes;
public TextField start_time_input;
public TextField end_time_input;
public TimePicker start_time_input;
public TimePicker end_time_input;

private MainController mainController;

private static LocalTime parseTime(String time, int index) {
public static LocalTime parseTime(String time, int index) {
if (index >= timeFormatters.length) throw new DateTimeParseException("No match found", time, 0);
try {
return LocalTime.parse(time.replace(" ", ""), timeFormatters[index]);
Expand All @@ -72,38 +73,19 @@ public LocalDate fromString(String dateString) {
}
});
date_input.setValue(LocalDate.now());

start_time_input.textProperty().addListener((observable, newv, oldv) -> {
start_time_input.timeProperty.addListener((observable, oldValue, newValue) -> end_time_input.timeProperty.set(newValue.plusHours(duration_hours.getValue()).plusMinutes(duration_minutes.getValue())));
end_time_input.timeProperty.addListener((observable, oldValue, newValue) -> {
try {
LocalTime parsed = parseTime(start_time_input.getText().toLowerCase(), 0);
start_time_input.setUserData(parsed);
end_time_input.setText(timeFormatters[0].format(parsed.plusHours(duration_hours.getValue()).plusMinutes(duration_minutes.getValue())));
} catch (DateTimeParseException e) {
// if (start_time_input.getUserData() != null)
// start_time_input.setText(timeFormatter.format((LocalTime) start_time_input.getUserData()));
}
});
end_time_input.textProperty().addListener((observable, newv, oldv) -> {
try {
LocalTime parsed = parseTime(end_time_input.getText().toLowerCase(), 0);
end_time_input.setUserData(parsed);
LocalTime start = (LocalTime) start_time_input.getUserData();
int minutes = (int) start.until(parsed, ChronoUnit.MINUTES);
int minutes = (int) start_time_input.timeProperty.get().until(newValue, ChronoUnit.MINUTES);
duration_hours.getValueFactory().setValue(minutes / 60);
duration_minutes.getValueFactory().setValue(minutes % 60);
} catch (DateTimeParseException e) {
// if (end_time_input.getUserData() != null)
// end_time_input.setText(timeFormatter.format((LocalTime) end_time_input.getUserData()));
}
});
duration_hours.valueProperty().addListener((observable, oldValue, newValue) -> {
if (start_time_input.getUserData() == null) return;
end_time_input.setText(timeFormatters[0].format(((LocalTime) start_time_input.getUserData()).plusHours(duration_hours.getValue()).plusMinutes(duration_minutes.getValue())));
});
duration_minutes.valueProperty().addListener((observable, oldValue, newValue) -> {
if (start_time_input.getUserData() == null) return;
end_time_input.setText(timeFormatters[0].format(((LocalTime) start_time_input.getUserData()).plusHours(duration_hours.getValue()).plusMinutes(duration_minutes.getValue())));
});
duration_hours.valueProperty().addListener((observable, oldValue, newValue) -> end_time_input.timeProperty.set(start_time_input.timeProperty.get().plusHours(duration_hours.getValue()).plusMinutes(duration_minutes.getValue())));
duration_minutes.valueProperty().addListener((observable, oldValue, newValue) -> end_time_input.timeProperty.set(start_time_input.timeProperty.get().plusHours(duration_hours.getValue()).plusMinutes(duration_minutes.getValue())));
}

/**
Expand Down
26 changes: 12 additions & 14 deletions src/main/java/app/nush/examclock/controllers/MainController.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,6 @@ public class MainController {
* if male toilet is occupied.
*/
public SimpleBooleanProperty toiletMaleOccupied = new SimpleBooleanProperty(false);
/**
* The Stage.
*/
public Stage stage;
/**
* The Add exam stage.
*/
Expand Down Expand Up @@ -201,6 +197,12 @@ public void initialize() throws IOException {

initAddExamStage();
initConnectionStage();
PreferenceController.nightMode.addListener((observable, oldValue, newValue) -> {
addExamStage.getScene().getStylesheets().removeAll("/theme.dark.css", "/theme.light.css");
addExamStage.getScene().getStylesheets().add(newValue ? "/theme.dark.css" : "/theme.light.css");
connectStage.getScene().getStylesheets().removeAll("/theme.dark.css", "/theme.light.css");
connectStage.getScene().getStylesheets().add(newValue ? "/theme.dark.css" : "/theme.light.css");
});

preferenceController.initPreferences(); // load preferences after adding listeners
loadExams(null); // load exams from disk
Expand Down Expand Up @@ -394,8 +396,8 @@ public void showConnection(ActionEvent event) {
}

@FXML
public void importExams(ActionEvent actionEvent) {
File file = fileChooser.showOpenDialog(stage);
public void importExams(ActionEvent event) {
File file = fileChooser.showOpenDialog(ExamClock.getStage());
if (file == null) return;
try {
String str = new String(Files.readAllBytes(Paths.get(file.toURI())));
Expand All @@ -412,8 +414,8 @@ public void importExams(ActionEvent actionEvent) {
}

@FXML
public void exportExams(ActionEvent actionEvent) {
File file = fileChooser.showSaveDialog(stage);
public void exportExams(ActionEvent event) {
File file = fileChooser.showSaveDialog(ExamClock.getStage());
if (file == null) return;
try {
Files.write(Paths.get(file.toURI()), gson.toJson(exams).getBytes());
Expand All @@ -423,7 +425,7 @@ public void exportExams(ActionEvent actionEvent) {
}

@FXML
public void about(ActionEvent actionEvent) {
public void about(ActionEvent event) {
try {
Stage stage = new Stage();
Group logo = FXMLLoader.load(getClass().getResource("/logo_light.fxml"));
Expand Down Expand Up @@ -463,14 +465,10 @@ public void about(ActionEvent actionEvent) {
}

@FXML
public void help(ActionEvent actionEvent) {
public void help(ActionEvent event) {
ExamClock.getInstance().getHostServices().showDocument("https://github.com/appventure-nush/exam-clock-2020/blob/master/README.md");
}

public void setStage(Stage stage) {
this.stage = stage;
}

public void onClose(WindowEvent event) {
stop();
connectionController.onClose(event);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ public void initPreferences() {
*/
public void attachListeners() {
nightMode.addListener((observable, oldValue, newValue) -> {
controller.stage.getScene().getStylesheets().removeAll("/theme.dark.css", "/theme.light.css");
controller.stage.getScene().getStylesheets().add(newValue ? "/theme.dark.css" : "/theme.light.css");
ExamClock.getStage().getScene().getStylesheets().removeAll("/theme.dark.css", "/theme.light.css");
ExamClock.getStage().getScene().getStylesheets().add(newValue ? "/theme.dark.css" : "/theme.light.css");
preferencesFx.getView().getScene().getStylesheets().removeAll("/theme.dark.css", "/theme.light.css");
preferencesFx.getView().getScene().getStylesheets().addAll("/theme.css", nightMode.get() ? "/theme.dark.css" : "/theme.light.css");
});
Expand Down
46 changes: 46 additions & 0 deletions src/main/java/app/nush/examclock/display/TimePicker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package app.nush.examclock.display;

import app.nush.examclock.model.CustomBinding;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.Bounds;
import javafx.scene.control.TextField;

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

import static app.nush.examclock.controllers.AddExamController.parseTime;

public class TimePicker extends TextField {
public static final DateTimeFormatter defaultFormatter = DateTimeFormatter.ofPattern("hh:mm a");
private final TimePopup popup;
public SimpleObjectProperty<LocalTime> timeProperty;
public SimpleIntegerProperty hour;
public SimpleIntegerProperty minute;

public TimePicker() {
timeProperty = new SimpleObjectProperty<>();
hour = new SimpleIntegerProperty(0);
minute = new SimpleIntegerProperty(0);

popup = new TimePopup(this);

CustomBinding.bindBidirectional(timeProperty, hour, LocalTime::getHour, hour -> LocalTime.of(hour.intValue(), minute.get()));
CustomBinding.bindBidirectional(timeProperty, minute, LocalTime::getMinute, minute -> LocalTime.of(hour.get(), minute.intValue()));
CustomBinding.bindBidirectional(timeProperty, textProperty(), localTime -> localTime.format(defaultFormatter), text -> {
try {
return parseTime(text, 0);
} catch (Exception ignored) {
return timeProperty.get();
}
});

setPromptText("00:00 am");
focusedProperty().addListener((observable, oldValue, newValue) -> {
if (!oldValue && newValue) { //gain focus
Bounds bounds = localToScreen(getBoundsInLocal());
popup.show(TimePicker.this, bounds.getMinX(), bounds.getMaxY());
}
});
}
}
55 changes: 55 additions & 0 deletions src/main/java/app/nush/examclock/display/TimePopup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package app.nush.examclock.display;

import app.nush.examclock.model.CustomBinding;
import javafx.scene.Node;
import javafx.scene.control.PopupControl;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Skin;
import javafx.scene.layout.HBox;
import tornadofx.control.ListItem;
import tornadofx.control.ListMenu;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class TimePopup extends PopupControl {

public TimePopup(TimePicker picker) {
HBox root = new HBox();
root.setPrefHeight(300);
ListMenu hourMenu = new ListMenu();
List<ListItem> hourMenuItems = IntStream.range(0, 24).mapToObj(i -> new ListItem(String.valueOf(i))).collect(Collectors.toList());
hourMenu.getChildren().addAll(hourMenuItems);

ListMenu minuteMenu = new ListMenu();
List<ListItem> minuteMenuItems = IntStream.range(0, 60).mapToObj(i -> new ListItem(String.valueOf(i))).collect(Collectors.toList());
minuteMenu.getChildren().addAll(minuteMenuItems);

CustomBinding.bindBidirectional(hourMenu.activeProperty(), picker.hour, listItem -> Integer.parseInt(listItem.getText()), hour -> hourMenuItems.get((Integer) hour));
CustomBinding.bindBidirectional(minuteMenu.activeProperty(), picker.minute, listItem -> Integer.parseInt(listItem.getText()), minute -> minuteMenuItems.get((Integer) minute));
root.getChildren().addAll(new ScrollPane(hourMenu) {{
setVbarPolicy(ScrollBarPolicy.ALWAYS);
setHbarPolicy(ScrollBarPolicy.NEVER);
}}, new ScrollPane(minuteMenu) {{
setVbarPolicy(ScrollBarPolicy.ALWAYS);
setHbarPolicy(ScrollBarPolicy.NEVER);
}});

setSkin(new Skin<TimePopup>() {
public TimePopup getSkinnable() {
return TimePopup.this;
}

public Node getNode() {
return root;
}

public void dispose() {
}
});
setHideOnEscape(true);
setAutoFix(true);
setAutoHide(true);
}
}
37 changes: 37 additions & 0 deletions src/main/java/app/nush/examclock/model/CustomBinding.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package app.nush.examclock.model;

import javafx.beans.property.Property;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.beans.value.WritableValue;

import java.util.function.Function;

public class CustomBinding {

public static <A, B> void bindBidirectional(Property<A> propertyA, Property<B> propertyB, Function<A, B> updateB, Function<B, A> updateA) {
addFlaggedChangeListener(propertyA, propertyB, updateB);
addFlaggedChangeListener(propertyB, propertyA, updateA);
}

public static <A, B> void bind(Property<A> propertyA, Property<B> propertyB, Function<A, B> updateB) {
addFlaggedChangeListener(propertyA, propertyB, updateB);
}

private static <X, Y> void addFlaggedChangeListener(ObservableValue<X> propertyX, WritableValue<Y> propertyY, Function<X, Y> updateY) {
propertyX.addListener(new ChangeListener<X>() {
private boolean alreadyCalled = false;

@Override
public void changed(ObservableValue<? extends X> observable, X oldValue, X newValue) {
if (alreadyCalled) return;
try {
alreadyCalled = true;
propertyY.setValue(updateY.apply(newValue));
} finally {
alreadyCalled = false;
}
}
});
}
}
7 changes: 4 additions & 3 deletions src/main/resources/fxml_add_exam.fxml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>

<?import app.nush.examclock.display.TimePicker?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import tornadofx.control.*?>
<Form fx:id="form" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="app.nush.examclock.controllers.AddExamController">
<Fieldset inputGrow="SOMETIMES" text="Exam Details">
<Fieldset inputGrow="SOMETIMES" text="Exam Details" labelPosition="HORIZONTAL">
<Field text="Name">
<TextField fx:id="name_input"/>
</Field>
Expand All @@ -19,10 +20,10 @@
<Spinner fx:id="duration_minutes" editable="true" max="59" min="0"/>
</Field>
<Field text="Start Time">
<TextField fx:id="start_time_input" maxWidth="Infinity" promptText="hh:mm am/pm"/>
<TimePicker fx:id="start_time_input" maxWidth="Infinity"/>
</Field>
<Field text="End Time">
<TextField fx:id="end_time_input" maxWidth="Infinity" promptText="hh:mm am/pm"/>
<TimePicker fx:id="end_time_input" maxWidth="Infinity"/>
</Field>
<Field>
<Button onAction="#addExam" text="Add" styleClass="primary-raised"/>
Expand Down
11 changes: 11 additions & 0 deletions src/main/resources/theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@
-fx-padding: 0;
}

.list-item {
-fx-fill: white;
-fx-text-fill: -fx-fill;
}

.list-item .text {
-fx-fill: white;
-fx-text-fill: -fx-fill;
}


/* Fix scroll bar buttons arrows colors */
.scroll-bar > .increment-button > .increment-arrow,
.scroll-bar > .decrement-button > .decrement-arrow {
Expand Down

0 comments on commit 6adde25

Please sign in to comment.