Compare commits
9 Commits
129a26e1a9
...
e9fbbf2f9f
Author | SHA1 | Date |
---|---|---|
|
e9fbbf2f9f | |
|
ce8bdaba7e | |
|
7e5730a19f | |
|
ec42a6e75a | |
|
2452e42b72 | |
|
3d36c85941 | |
|
84df4c07a1 | |
|
4ae9eec9f7 | |
|
d0959f535b |
|
@ -1,14 +0,0 @@
|
|||
package ch.zhaw.gartenverwaltung;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
|
||||
public class HelloController {
|
||||
@FXML
|
||||
private Label welcomeText;
|
||||
|
||||
@FXML
|
||||
protected void onHelloButtonClick() {
|
||||
welcomeText.setText("Welcome to JavaFX Application!");
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ import java.lang.annotation.RetentionPolicy;
|
|||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotates a method to be executed after all dependencies annotates with {@link Inject}
|
||||
* Annotates a method to be executed after all dependencies annotated with {@link Inject}
|
||||
* have been injected.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
|
|
@ -23,6 +23,10 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Class responsible for bootstrapping the application wide dependencies
|
||||
* and injecting them into JavaFX Controllers.
|
||||
*/
|
||||
public class AppLoader {
|
||||
/**
|
||||
* Caching the panes
|
||||
|
@ -32,17 +36,24 @@ public class AppLoader {
|
|||
/**
|
||||
* Application-wide dependencies
|
||||
*/
|
||||
private final PlantList plantList = new JsonPlantList();
|
||||
private final CropList cropList = new JsonCropList();
|
||||
private final TaskList taskList = new JsonTaskList();
|
||||
|
||||
private final GardenSchedule gardenSchedule = new GardenSchedule(taskList, plantList);
|
||||
private final Garden garden = new Garden(gardenSchedule, cropList);
|
||||
|
||||
private final Map<String, Object> dependencies = new HashMap<>();
|
||||
|
||||
public AppLoader() throws IOException {
|
||||
}
|
||||
PlantList plantList = new JsonPlantList();
|
||||
CropList cropList = new JsonCropList();
|
||||
TaskList taskList = new JsonTaskList();
|
||||
GardenSchedule gardenSchedule = new GardenSchedule(taskList, plantList);
|
||||
|
||||
dependencies.put(PlantList.class.getSimpleName(), plantList);
|
||||
dependencies.put(CropList.class.getSimpleName(), cropList);
|
||||
dependencies.put(TaskList.class.getSimpleName(), taskList);
|
||||
|
||||
dependencies.put(PlantListModel.class.getSimpleName(), new PlantListModel(plantList));
|
||||
|
||||
dependencies.put(GardenSchedule.class.getSimpleName(), gardenSchedule);
|
||||
dependencies.put(Garden.class.getSimpleName(), new Garden(gardenSchedule, cropList));
|
||||
dependencies.put(AppLoader.class.getSimpleName(), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads and returns a {@link Pane} (cached).
|
||||
|
@ -135,26 +146,18 @@ public class AppLoader {
|
|||
});
|
||||
|
||||
Arrays.stream(controller.getClass().getMethods())
|
||||
.filter(method -> method.isAnnotationPresent(AfterInject.class))
|
||||
.filter(method -> method.isAnnotationPresent(AfterInject.class) && method.getParameterCount() == 0)
|
||||
.forEach(afterInjectMethod -> {
|
||||
if (afterInjectMethod.getParameterCount() == 0) {
|
||||
try {
|
||||
afterInjectMethod.invoke(controller);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
afterInjectMethod.invoke(controller);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
// TODO: Log
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Object getAppDependency(Class<?> type) {
|
||||
return switch (type.getSimpleName()) {
|
||||
case "Garden" -> garden;
|
||||
case "PlantList" -> plantList;
|
||||
case "PlantListModel" -> new PlantListModel(plantList);
|
||||
case "GardenSchedule" -> gardenSchedule;
|
||||
case "AppLoader" -> this;
|
||||
default -> null;
|
||||
};
|
||||
return dependencies.get(type.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,20 @@ package ch.zhaw.gartenverwaltung.bootstrap;
|
|||
import javafx.event.Event;
|
||||
import javafx.event.EventType;
|
||||
|
||||
/**
|
||||
* Represents an event that should lead to a view being changed.
|
||||
*/
|
||||
public class ChangeViewEvent extends Event {
|
||||
private final String view;
|
||||
|
||||
public static final EventType<ChangeViewEvent> CHANGE_MAIN_VIEW = new EventType<>("CHANGE_MAIN_VIEW");
|
||||
|
||||
/**
|
||||
* Creates an Event that should lead to the main view being changed.
|
||||
*
|
||||
* @param eventType The {@link EventType<ChangeViewEvent>} specifying which view should be changed.
|
||||
* @param view The filename of the View to be changed to
|
||||
*/
|
||||
public ChangeViewEvent(EventType<? extends Event> eventType, String view) {
|
||||
super(eventType);
|
||||
this.view = view;
|
||||
|
|
|
@ -6,7 +6,7 @@ import java.lang.annotation.RetentionPolicy;
|
|||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotates a Field to be injected from the application-dependencies
|
||||
* Annotates a Field to be injected from the application-dependencies.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
|
|
|
@ -6,6 +6,10 @@ import java.io.IOException;
|
|||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Represents a List of {@link Crop}s.
|
||||
* The interface specifies the operations to add/update and remove entries.
|
||||
*/
|
||||
public interface CropList {
|
||||
/**
|
||||
* Yields a list of all {@link Crop}s in the database.
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
package ch.zhaw.gartenverwaltung.io;
|
||||
|
||||
/**
|
||||
* Provides an sequential ID starting from the given initial Value.
|
||||
*/
|
||||
public class IdProvider {
|
||||
private long currentId;
|
||||
public IdProvider(long initialValue) {
|
||||
currentId = initialValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Yields the next ID in the sequence.
|
||||
* @return The next ID
|
||||
*/
|
||||
public long incrementAndGet() {
|
||||
return ++currentId;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,11 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Implements the {@link CropList} interface for reading and writing {@link Crop} objects
|
||||
* from and to a local JSON file.
|
||||
* The reads are cached to minimize file-io operations.
|
||||
*/
|
||||
public class JsonCropList implements CropList {
|
||||
private final URL dataSource;
|
||||
|
||||
|
@ -40,7 +45,7 @@ public class JsonCropList implements CropList {
|
|||
}
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
* Default constructor. Uses a file from the app resources.
|
||||
*/
|
||||
public JsonCropList() {
|
||||
this.dataSource = getClass().getResource("user-crops.json");
|
||||
|
|
|
@ -20,8 +20,8 @@ import java.util.Map;
|
|||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Implements the {@link PlantList} interface for loading {@link Plant} objects
|
||||
* from a JSON file.
|
||||
* Implements the {@link PlantList} interface for reading {@link Plant} objects
|
||||
* from a local JSON file.
|
||||
* The reads are cached to minimize file-io operations.
|
||||
*/
|
||||
public class JsonPlantList implements PlantList {
|
||||
|
@ -44,9 +44,17 @@ public class JsonPlantList implements PlantList {
|
|||
imageModule.addDeserializer(Image.class, new PlantImageDeserializer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor. Uses a file from the app resources.
|
||||
*/
|
||||
public JsonPlantList() {
|
||||
this.dataSource = getClass().getResource("plantdb.json");
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to use a specified {@link URL} as a {@link #dataSource}
|
||||
* @param dataSource A {@link URL} to the file to be used as a data source
|
||||
*/
|
||||
public JsonPlantList(URL dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
@ -67,7 +75,7 @@ public class JsonPlantList implements PlantList {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see PlantList#getPlantById(long)
|
||||
* @see PlantList#getPlantById(HardinessZone, long)
|
||||
*/
|
||||
@Override
|
||||
public Optional<Plant> getPlantById(HardinessZone zone, long id) throws HardinessZoneNotSetException, IOException {
|
||||
|
|
|
@ -20,8 +20,8 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Implements the {@link TaskList} interface for loading and writing {@link Task} objects
|
||||
* from and to a JSON file.
|
||||
* Implements the {@link TaskList} interface for reading and writing {@link Task} objects
|
||||
* from and to a local JSON file.
|
||||
* The reads are cached to minimize file-io operations.
|
||||
*/
|
||||
public class JsonTaskList implements TaskList {
|
||||
|
@ -45,9 +45,17 @@ public class JsonTaskList implements TaskList {
|
|||
timeModule.addSerializer(LocalDate.class, dateSerializer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor. Uses a file from the app resources.
|
||||
*/
|
||||
public JsonTaskList() {
|
||||
this.dataSource = getClass().getResource("taskdb.json");
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to use a specified {@link URL} as a {@link #dataSource}
|
||||
* @param dataSource A {@link URL} to the file to be used as a data source
|
||||
*/
|
||||
public JsonTaskList(URL dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import java.util.List;
|
|||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* A database of {@link Plant}s.
|
||||
* A List of {@link Plant}s.
|
||||
* The interface specifies the minimal required operations.
|
||||
*/
|
||||
public interface PlantList {
|
||||
|
|
|
@ -7,8 +7,8 @@ import java.time.LocalDate;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A database of {@link Task}s.
|
||||
* The interface specifies the minimal required operations.
|
||||
* Represents a List of {@link Task}s.
|
||||
* The interface specifies the operations to add/update and remove entries.
|
||||
*/
|
||||
public interface TaskList {
|
||||
/**
|
||||
|
|
|
@ -7,6 +7,9 @@ import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Used by the Jackson Library to deserialize a String to a {@link GrowthPhaseType}
|
||||
*/
|
||||
public class GrowthPhaseTypeDeserializer extends StdDeserializer<GrowthPhaseType> {
|
||||
public GrowthPhaseTypeDeserializer(Class<?> vc) {
|
||||
super(vc);
|
||||
|
|
|
@ -7,6 +7,9 @@ import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Used by the Jackson Library to deserialize a String to a {@link HardinessZone}
|
||||
*/
|
||||
public class HardinessZoneDeserializer extends StdDeserializer<HardinessZone> {
|
||||
public HardinessZoneDeserializer(Class<?> vc) {
|
||||
super(vc);
|
||||
|
|
|
@ -13,6 +13,9 @@ import java.io.InputStream;
|
|||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Used by the Jackson Library to deserialize a String to a {@link Image}
|
||||
*/
|
||||
public class PlantImageDeserializer extends JsonDeserializer<Image> {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -146,14 +146,18 @@ public class GardenSchedule {
|
|||
dayTaskList.add(new ArrayList<>());
|
||||
final int finalI = i;
|
||||
weekTasks.forEach(task -> {
|
||||
LocalDate checkDate = task.getNextExecution();
|
||||
do {
|
||||
if (date.equals(checkDate) && !date.isAfter(task.getEndDate().orElse(LocalDate.MIN))) {
|
||||
dayTaskList.get(finalI).add(task);
|
||||
}
|
||||
if (task.getInterval().orElse(0) == 0) break;
|
||||
checkDate = checkDate.plusDays(task.getInterval().orElse(0));
|
||||
} while (task.getInterval().isPresent() && checkDate.isBefore(LocalDate.now().plusDays(listLength)));
|
||||
if (task.getNextExecution() == null) {
|
||||
task.isDone();
|
||||
} else {
|
||||
LocalDate checkDate = task.getNextExecution();
|
||||
|
||||
do {
|
||||
if (date.equals(checkDate) && !date.isAfter(task.getEndDate().orElse(LocalDate.MIN))) {
|
||||
dayTaskList.get(finalI).add(task);
|
||||
}
|
||||
checkDate = checkDate.plusDays(task.getInterval().orElse(0));
|
||||
} while (!(task.getInterval().orElse(0) == 0) && checkDate.isBefore(LocalDate.now().plusDays(listLength)));
|
||||
}
|
||||
});
|
||||
}
|
||||
return dayTaskList;
|
||||
|
@ -188,6 +192,6 @@ public class GardenSchedule {
|
|||
* @return a sorted coppy of the given Tasklist
|
||||
*/
|
||||
private List<Task> getSortedTaskList(List<Task> taskList, Comparator<Task> comparator) {
|
||||
return taskList.stream().sorted(comparator).collect(Collectors.toList());
|
||||
return taskList.stream().filter(task -> task.getNextExecution() != null).sorted(comparator).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public class TaskTemplate {
|
|||
}
|
||||
|
||||
public Task generateTask(LocalDate realStartDate, long cropId) {
|
||||
LocalDate endDate = relativeEndDate != null ? realStartDate.plusDays(relativeEndDate) : realStartDate.plusDays(0);
|
||||
LocalDate endDate = relativeEndDate != null ? realStartDate.plusDays(relativeEndDate) : realStartDate;
|
||||
|
||||
if (interval == null) {
|
||||
this.interval = 0;
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
|
||||
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="938.0" prefWidth="1110.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.zhaw.gartenverwaltung.MainFXMLController">
|
||||
<children>
|
||||
<HBox maxWidth="35.0" minHeight="35.0" prefHeight="38.0" prefWidth="1110.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<HBox fx:id="menubar" maxWidth="35.0" minHeight="40.0" prefHeight="38.0" prefWidth="1110.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<Button fx:id="home_button" mnemonicParsing="false" onAction="#goToHome" prefHeight="38.0" prefWidth="40.0" HBox.hgrow="NEVER" />
|
||||
<Button fx:id="home_button" mnemonicParsing="false" onAction="#goToHome" prefHeight="38.0" prefWidth="38.0" HBox.hgrow="NEVER" />
|
||||
<Button fx:id="myGarden_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#goToMyPlants" prefHeight="38.0" prefWidth="121.0" text="My Garden" />
|
||||
<Button fx:id="mySchedule_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#goToMySchedule" prefHeight="38.0" prefWidth="121.0" text="My Schedule" />
|
||||
<Button fx:id="tutorial_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#showTutorial" prefHeight="38.0" prefWidth="121.0" text="Tutorial" />
|
||||
<Pane maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" />
|
||||
<Button fx:id="settings_button" maxHeight="1.7976931348623157E308" mnemonicParsing="false" onAction="#openSettings" prefHeight="38.0" prefWidth="40.0" HBox.hgrow="NEVER" />
|
||||
<Pane fx:id="menu_pane" maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" />
|
||||
<Button fx:id="settings_button" mnemonicParsing="false" onAction="#openSettings" prefHeight="38.0" prefWidth="38.0" HBox.hgrow="NEVER" />
|
||||
</children>
|
||||
</HBox>
|
||||
<AnchorPane fx:id="mainPane" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="35.0" />
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
.button{
|
||||
-fx-text-fill: rgb(49, 89, 23);
|
||||
-fx-border-color: rgb(49, 89, 23);
|
||||
-fx-border-radius: 5;
|
||||
-fx-padding: 3 6 6 6;
|
||||
}
|
||||
/*
|
||||
|
||||
#home_button, #myGarden_button,
|
||||
#mySchedule_button, #settings_button,
|
||||
#tutorial_button, #menu_pane {
|
||||
-fx-text-fill: white;
|
||||
-fx-background-color: rgb(0,128,0);
|
||||
}
|
||||
|
||||
#menubar {
|
||||
-fx-background-color: rgb(0,128,0);
|
||||
}
|
||||
|
||||
#home_button:hover, #myGarden_button:hover,
|
||||
#mySchedule_button:hover, #settings_button:hover,
|
||||
#tutorial_button:hover,
|
||||
#home_button:focused, #myGarden_button:focused,
|
||||
#mySchedule_button:focused, #settings_button:focused,
|
||||
#tutorial_button:focused{
|
||||
-fx-background-color: darkgreen;
|
||||
}
|
||||
|
||||
.root, .split-pane {
|
||||
-fx-background-color: linear-gradient(green 0%, lawngreen 33%, lightgreen 66%, #eee 100%);
|
||||
}./
|
Loading…
Reference in New Issue