From cf47f08d5e310f25d424845e675061a30f32a190 Mon Sep 17 00:00:00 2001 From: clfreville2 Date: Thu, 15 Dec 2022 10:26:04 +0100 Subject: [PATCH] Initial commit --- .gitignore | 30 +++++ Ebullition.iml | 13 ++ resources/images/visualizer/cold.jpg | Bin 0 -> 3677 bytes resources/images/visualizer/hot.jpg | Bin 0 -> 3309 bytes resources/images/visualizer/warm.jpg | Bin 0 -> 5347 bytes resources/windows/MainWindows.fxml | 29 +++++ .../uca/iut/clfreville2/MainApplication.java | 18 +++ .../uca/iut/clfreville2/gui/MainWindows.java | 121 ++++++++++++++++++ .../uca/iut/clfreville2/gui/ModalFactory.java | 44 +++++++ .../clfreville2/gui/image/ImageSupplier.java | 12 ++ .../gui/image/StandardImageSupplier.java | 30 +++++ .../gui/list/NameableListCell.java | 17 +++ .../iut/clfreville2/model/SensorRegistry.java | 67 ++++++++++ .../model/SequenceIntSupplier.java | 18 +++ .../model/binding/ToBooleanBinding.java | 43 +++++++ .../model/sensor/ManualSensor.java | 20 +++ .../iut/clfreville2/model/sensor/Sensor.java | 73 +++++++++++ .../model/sensor/package-info.java | 4 + .../model/shared/Identifiable.java | 21 +++ .../clfreville2/model/shared/Nameable.java | 26 ++++ .../model/shared/ObservableIdentifiable.java | 35 +++++ .../model/shared/TemperatureHolder.java | 14 ++ .../model/shared/package-info.java | 4 + .../persistence/SensorRegistryLoader.java | 14 ++ .../persistence/SensorRegistrySaver.java | 14 ++ .../persistence/StubSensorRegistryLoader.java | 14 ++ 26 files changed, 681 insertions(+) create mode 100644 .gitignore create mode 100644 Ebullition.iml create mode 100644 resources/images/visualizer/cold.jpg create mode 100644 resources/images/visualizer/hot.jpg create mode 100644 resources/images/visualizer/warm.jpg create mode 100644 resources/windows/MainWindows.fxml create mode 100644 src/fr/uca/iut/clfreville2/MainApplication.java create mode 100644 src/fr/uca/iut/clfreville2/gui/MainWindows.java create mode 100644 src/fr/uca/iut/clfreville2/gui/ModalFactory.java create mode 100644 src/fr/uca/iut/clfreville2/gui/image/ImageSupplier.java create mode 100644 src/fr/uca/iut/clfreville2/gui/image/StandardImageSupplier.java create mode 100644 src/fr/uca/iut/clfreville2/gui/list/NameableListCell.java create mode 100644 src/fr/uca/iut/clfreville2/model/SensorRegistry.java create mode 100644 src/fr/uca/iut/clfreville2/model/SequenceIntSupplier.java create mode 100644 src/fr/uca/iut/clfreville2/model/binding/ToBooleanBinding.java create mode 100644 src/fr/uca/iut/clfreville2/model/sensor/ManualSensor.java create mode 100644 src/fr/uca/iut/clfreville2/model/sensor/Sensor.java create mode 100644 src/fr/uca/iut/clfreville2/model/sensor/package-info.java create mode 100644 src/fr/uca/iut/clfreville2/model/shared/Identifiable.java create mode 100644 src/fr/uca/iut/clfreville2/model/shared/Nameable.java create mode 100644 src/fr/uca/iut/clfreville2/model/shared/ObservableIdentifiable.java create mode 100644 src/fr/uca/iut/clfreville2/model/shared/TemperatureHolder.java create mode 100644 src/fr/uca/iut/clfreville2/model/shared/package-info.java create mode 100644 src/fr/uca/iut/clfreville2/persistence/SensorRegistryLoader.java create mode 100644 src/fr/uca/iut/clfreville2/persistence/SensorRegistrySaver.java create mode 100644 src/fr/uca/iut/clfreville2/persistence/StubSensorRegistryLoader.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a835580 --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +### IntelliJ IDEA ### +.idea +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store diff --git a/Ebullition.iml b/Ebullition.iml new file mode 100644 index 0000000..08da7bc --- /dev/null +++ b/Ebullition.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/resources/images/visualizer/cold.jpg b/resources/images/visualizer/cold.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0d18a4bb0463a007106662a764fa126662e02c22 GIT binary patch literal 3677 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 OF`I{0oGop3IQ<`~U+>KT literal 0 HcmV?d00001 diff --git a/resources/images/visualizer/hot.jpg b/resources/images/visualizer/hot.jpg new file mode 100644 index 0000000000000000000000000000000000000000..91a82a4416d1459924d835833c1d64af744dde99 GIT binary patch literal 3309 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 literal 0 HcmV?d00001 diff --git a/resources/images/visualizer/warm.jpg b/resources/images/visualizer/warm.jpg new file mode 100644 index 0000000000000000000000000000000000000000..09ba2a148dc60ba417ee17db43428247fc9abba2 GIT binary patch literal 5347 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 Qh^NpXad50G + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/fr/uca/iut/clfreville2/MainApplication.java b/src/fr/uca/iut/clfreville2/MainApplication.java new file mode 100644 index 0000000..ea3323e --- /dev/null +++ b/src/fr/uca/iut/clfreville2/MainApplication.java @@ -0,0 +1,18 @@ +package fr.uca.iut.clfreville2; + +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.stage.Stage; + +public class MainApplication extends Application { + + @Override + public void start(Stage primaryStage) throws Exception { + Parent root = FXMLLoader.load(MainApplication.class.getResource("/windows/MainWindows.fxml")); + Scene scene = new Scene(root); + primaryStage.setScene(scene); + primaryStage.show(); + } +} diff --git a/src/fr/uca/iut/clfreville2/gui/MainWindows.java b/src/fr/uca/iut/clfreville2/gui/MainWindows.java new file mode 100644 index 0000000..fa0fa5d --- /dev/null +++ b/src/fr/uca/iut/clfreville2/gui/MainWindows.java @@ -0,0 +1,121 @@ +package fr.uca.iut.clfreville2.gui; + +import fr.uca.iut.clfreville2.gui.image.ImageSupplier; +import fr.uca.iut.clfreville2.gui.image.StandardImageSupplier; +import fr.uca.iut.clfreville2.gui.list.NameableListCell; +import fr.uca.iut.clfreville2.model.SensorRegistry; +import fr.uca.iut.clfreville2.model.binding.ToBooleanBinding; +import fr.uca.iut.clfreville2.model.sensor.ManualSensor; +import fr.uca.iut.clfreville2.model.sensor.Sensor; +import fr.uca.iut.clfreville2.persistence.StubSensorRegistryLoader; +import javafx.fxml.FXML; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.ListView; +import javafx.scene.control.Slider; +import javafx.scene.control.TextField; +import javafx.scene.image.ImageView; +import javafx.scene.text.Text; + +public class MainWindows { + + private final SensorRegistry registry = new StubSensorRegistryLoader().load(); + private final ImageSupplier imageSupplier = new StandardImageSupplier(); + private ModalFactory modalFactory; + + @FXML + private ListView sensorsList; + + @FXML + private Text sensorId; + + @FXML + public TextField sensorName; + + @FXML + private Button changeBtn; + + @FXML + private Button visualizeBtn; + + @FXML + public void onChangeClick() { + Sensor selected = getSelectedSensor(); + if (!(selected instanceof ManualSensor sensor)) { + return; + } + getModalFactory().createModal(selected, root -> { + Slider slider = new Slider(-5, 30, sensor.getTemperature()); + slider.setBlockIncrement(0.5); + slider.setMajorTickUnit(0.5); + slider.setMinorTickCount(0); + slider.setSnapToTicks(true); + slider.valueProperty().bindBidirectional(sensor.temperatureProperty()); + root.getChildren().add(slider); + }).show(); + } + + @FXML + public void onVisualizeClick() { + Sensor selected = getSelectedSensor(); + if (selected == null) { + return; + } + getModalFactory().createModal(selected, root -> { + ImageView imageView = new ImageView(); + imageView.setPreserveRatio(true); + imageView.setFitHeight(200); + selected.temperatureProperty().addListener((observable, old, newValue) -> imageView.setImage(imageSupplier.apply(selected))); + imageView.setImage(imageSupplier.apply(selected)); + root.getChildren().add(imageView); + }).show(); + } + + @FXML + private void initialize() { + bindSensorList(); + bindActiveButtons(); + } + + @FXML + private void bindSensorList() { + sensorsList.setCellFactory(list -> new NameableListCell<>()); + sensorsList.itemsProperty().bind(registry.sensorsProperty()); + sensorsList.getSelectionModel().selectedItemProperty().addListener((list, oldValue, newValue) -> { + if (oldValue != null) { + sensorName.textProperty().unbindBidirectional(oldValue.nameProperty()); + } + if (newValue != null) { + sensorId.textProperty().bind(newValue.displayNameExpression()); + sensorName.textProperty().bindBidirectional(newValue.nameProperty()); + } else { + sensorId.textProperty().unbind(); + sensorId.setText(null); + } + }); + } + + @FXML + private void bindActiveButtons() { + changeBtn.visibleProperty().bind(new ToBooleanBinding<>( + sensorsList.getSelectionModel().selectedItemProperty(), + treeItem -> treeItem instanceof ManualSensor + )); + visualizeBtn.visibleProperty().bind(sensorsList.getSelectionModel().selectedItemProperty().isNotNull()); + } + + private Sensor getSelectedSensor() { + return sensorsList.getSelectionModel().getSelectedItem(); + } + + private ModalFactory getModalFactory() { + if (modalFactory == null) { + Scene scene = sensorsList.getScene(); + if (scene == null) { + throw new IllegalStateException("No scene found"); + } + modalFactory = new ModalFactory(scene.getWindow()); + } + return modalFactory; + } +} diff --git a/src/fr/uca/iut/clfreville2/gui/ModalFactory.java b/src/fr/uca/iut/clfreville2/gui/ModalFactory.java new file mode 100644 index 0000000..af1c7e1 --- /dev/null +++ b/src/fr/uca/iut/clfreville2/gui/ModalFactory.java @@ -0,0 +1,44 @@ +package fr.uca.iut.clfreville2.gui; + +import fr.uca.iut.clfreville2.model.sensor.Sensor; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.layout.Pane; +import javafx.scene.layout.VBox; +import javafx.scene.text.Text; +import javafx.stage.Stage; +import javafx.stage.Window; + +import java.util.function.Consumer; + +import static java.util.Objects.requireNonNull; + +public class ModalFactory { + + private final Window owner; + + public ModalFactory(Window owner) { + this.owner = requireNonNull(owner, "window owner"); + } + + public Stage createModal(Consumer initializer) { + Stage stage = new Stage(); + Button quit = new Button("Quit"); + Pane root = new VBox(); + initializer.accept(root); + root.getChildren().add(quit); + stage.setScene(new Scene(root)); + stage.initOwner(owner); + quit.setOnAction((ev) -> stage.hide()); + return stage; + } + + public Stage createModal(Sensor sensor, Consumer initializer) { + return createModal(root -> { + Text name = new Text(); + name.textProperty().bind(sensor.displayNameExpression().concat(sensor.temperatureProperty().asString(" (%s°C)"))); + root.getChildren().add(name); + initializer.accept(root); + }); + } +} diff --git a/src/fr/uca/iut/clfreville2/gui/image/ImageSupplier.java b/src/fr/uca/iut/clfreville2/gui/image/ImageSupplier.java new file mode 100644 index 0000000..396a606 --- /dev/null +++ b/src/fr/uca/iut/clfreville2/gui/image/ImageSupplier.java @@ -0,0 +1,12 @@ +package fr.uca.iut.clfreville2.gui.image; + +import fr.uca.iut.clfreville2.model.sensor.Sensor; +import javafx.scene.image.Image; + +import java.util.function.Function; + +/** + * Determine the image to display for a given sensor. + */ +public interface ImageSupplier extends Function { +} diff --git a/src/fr/uca/iut/clfreville2/gui/image/StandardImageSupplier.java b/src/fr/uca/iut/clfreville2/gui/image/StandardImageSupplier.java new file mode 100644 index 0000000..1b6f2ae --- /dev/null +++ b/src/fr/uca/iut/clfreville2/gui/image/StandardImageSupplier.java @@ -0,0 +1,30 @@ +package fr.uca.iut.clfreville2.gui.image; + +import fr.uca.iut.clfreville2.model.sensor.Sensor; +import javafx.scene.image.Image; + +public class StandardImageSupplier implements ImageSupplier { + private static final int HOT_THRESHOLD = 22; + private static final int WARM_THRESHOLD = 10; + + private final Image hotImage; + private final Image warmImage; + private final Image coldImage; + + public StandardImageSupplier() { + hotImage = new Image("/images/visualizer/hot.jpg"); + warmImage = new Image("/images/visualizer/warm.jpg"); + coldImage = new Image("/images/visualizer/cold.jpg"); + } + + @Override + public Image apply(Sensor sensor) { + if (sensor.getTemperature() >= HOT_THRESHOLD) { + return hotImage; + } + if (sensor.getTemperature() >= WARM_THRESHOLD) { + return warmImage; + } + return coldImage; + } +} diff --git a/src/fr/uca/iut/clfreville2/gui/list/NameableListCell.java b/src/fr/uca/iut/clfreville2/gui/list/NameableListCell.java new file mode 100644 index 0000000..4b6fedb --- /dev/null +++ b/src/fr/uca/iut/clfreville2/gui/list/NameableListCell.java @@ -0,0 +1,17 @@ +package fr.uca.iut.clfreville2.gui.list; + +import fr.uca.iut.clfreville2.model.shared.ObservableIdentifiable; +import javafx.scene.control.ListCell; + +public class NameableListCell extends ListCell { + + @Override + protected void updateItem(T item, boolean empty) { + super.updateItem(item, empty); + if (empty || item == null) { + textProperty().unbind(); + } else { + textProperty().bind(item.displayNameExpression()); + } + } +} diff --git a/src/fr/uca/iut/clfreville2/model/SensorRegistry.java b/src/fr/uca/iut/clfreville2/model/SensorRegistry.java new file mode 100644 index 0000000..21d8387 --- /dev/null +++ b/src/fr/uca/iut/clfreville2/model/SensorRegistry.java @@ -0,0 +1,67 @@ +package fr.uca.iut.clfreville2.model; + +import fr.uca.iut.clfreville2.model.sensor.ManualSensor; +import fr.uca.iut.clfreville2.model.sensor.Sensor; +import javafx.beans.property.ListProperty; +import javafx.beans.property.ReadOnlyListProperty; +import javafx.beans.property.SimpleListProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; + +import java.util.Iterator; +import java.util.function.IntSupplier; + +/** + * A registry class to hold thermal sensors instances. + */ +public class SensorRegistry implements Iterable { + + private final IntSupplier nextIdSupplier = new SequenceIntSupplier(); + private final ObservableList sensors = FXCollections.observableArrayList(); + private final ListProperty sensorsList = new SimpleListProperty<>(sensors); + + /** + * Create a new manual sensor and add it to the registry. + * + * @param name The name of the sensor. + * @return The sensor created. + */ + public ManualSensor createManual(String name) { + return register(new ManualSensor(nextIdSupplier.getAsInt(), name)); + } + + /** + * Add a new sensor to the registry. + * + * @param sensor The sensor to add. + * @return The sensor added. + * @param The type of sensor. + */ + protected T register(T sensor) { + sensorsList.add(sensor); + return sensor; + } + + /** + * Return a read-only list view of sensors. + * + * @return A list view of sensors. + */ + public ObservableList getSensors() { + return FXCollections.unmodifiableObservableList(sensors); + } + + /** + * Return the read-only list property of sensors. + * + * @return The list property of sensors. + */ + public ReadOnlyListProperty sensorsProperty() { + return sensorsList; + } + + @Override + public Iterator iterator() { + return getSensors().iterator(); + } +} diff --git a/src/fr/uca/iut/clfreville2/model/SequenceIntSupplier.java b/src/fr/uca/iut/clfreville2/model/SequenceIntSupplier.java new file mode 100644 index 0000000..03494bc --- /dev/null +++ b/src/fr/uca/iut/clfreville2/model/SequenceIntSupplier.java @@ -0,0 +1,18 @@ +package fr.uca.iut.clfreville2.model; + +import java.util.function.IntSupplier; + +/** + * A simple integer supplier that returns a sequence of integers. + * + * @implNote This class is not thread-safe. + */ +public class SequenceIntSupplier implements IntSupplier { + + private int current; + + @Override + public int getAsInt() { + return ++current; + } +} diff --git a/src/fr/uca/iut/clfreville2/model/binding/ToBooleanBinding.java b/src/fr/uca/iut/clfreville2/model/binding/ToBooleanBinding.java new file mode 100644 index 0000000..ba6ec04 --- /dev/null +++ b/src/fr/uca/iut/clfreville2/model/binding/ToBooleanBinding.java @@ -0,0 +1,43 @@ +package fr.uca.iut.clfreville2.model.binding; + +import javafx.beans.Observable; +import javafx.beans.binding.BooleanBinding; +import javafx.beans.value.ObservableObjectValue; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; + +import java.util.concurrent.Callable; +import java.util.function.Predicate; + +/** + * Permet de se bind sur une valeur booléenne calculée sur un objet. + * + * @param Le type de l'objet observé. + * @implNote Basé sur {@link javafx.beans.binding.Bindings#createBooleanBinding(Callable, Observable...)} et {@link javafx.beans.binding.Bindings#isNull(ObservableObjectValue)}. + */ +public class ToBooleanBinding extends BooleanBinding { + + private final ObservableObjectValue target; + private final Predicate predicate; + + public ToBooleanBinding(ObservableObjectValue target, Predicate predicate) { + this.target = target; + this.predicate = predicate; + super.bind(target); + } + + @Override + public void dispose() { + super.unbind(target); + } + + @Override + protected boolean computeValue() { + return predicate.test(target.get()); + } + + @Override + public ObservableList getDependencies() { + return FXCollections.singletonObservableList(target); + } +} diff --git a/src/fr/uca/iut/clfreville2/model/sensor/ManualSensor.java b/src/fr/uca/iut/clfreville2/model/sensor/ManualSensor.java new file mode 100644 index 0000000..84991bf --- /dev/null +++ b/src/fr/uca/iut/clfreville2/model/sensor/ManualSensor.java @@ -0,0 +1,20 @@ +package fr.uca.iut.clfreville2.model.sensor; + +import javafx.beans.property.DoubleProperty; +import javafx.beans.property.SimpleDoubleProperty; + +/** + * A simple sensor implementation that can be used to manually set the temperature. + */ +public class ManualSensor extends Sensor { + + private final DoubleProperty temperature = new SimpleDoubleProperty(); + + public ManualSensor(int id, String name) { + super(id, name); + } + + public DoubleProperty temperatureProperty() { + return temperature; + } +} diff --git a/src/fr/uca/iut/clfreville2/model/sensor/Sensor.java b/src/fr/uca/iut/clfreville2/model/sensor/Sensor.java new file mode 100644 index 0000000..b8e0d43 --- /dev/null +++ b/src/fr/uca/iut/clfreville2/model/sensor/Sensor.java @@ -0,0 +1,73 @@ +package fr.uca.iut.clfreville2.model.sensor; + +import fr.uca.iut.clfreville2.model.shared.TemperatureHolder; +import fr.uca.iut.clfreville2.model.shared.ObservableIdentifiable; +import javafx.beans.binding.DoubleBinding; +import javafx.beans.binding.DoubleExpression; +import javafx.beans.binding.StringExpression; +import javafx.beans.property.IntegerProperty; +import javafx.beans.property.ReadOnlyDoubleProperty; +import javafx.beans.property.ReadOnlyIntegerProperty; +import javafx.beans.property.SimpleIntegerProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javafx.beans.value.ObservableDoubleValue; + +import static java.util.Objects.requireNonNull; + +/** + * A sensor base using properties. + */ +public abstract class Sensor implements ObservableIdentifiable, TemperatureHolder { + + private final IntegerProperty id = new SimpleIntegerProperty(); + private final StringProperty name = new SimpleStringProperty(); + private final StringExpression displayName = name.concat(" #").concat(id.asString()); + + public Sensor(int id, String name) { + this.id.set(id); + this.name.set(requireNonNull(name, "name")); + } + + /** + * Get the value binding of this sensor. + * + * @return The value binding. + */ + public abstract DoubleExpression temperatureProperty(); + + @Override + public double getTemperature() { + return temperatureProperty().get(); + } + + @Override + public int getId() { + return id.get(); + } + + @Override + public void setName(String name) { + this.name.set(requireNonNull(name, "name")); + } + + @Override + public String getName() { + return name.get(); + } + + @Override + public ReadOnlyIntegerProperty idProperty() { + return id; + } + + @Override + public StringProperty nameProperty() { + return name; + } + + @Override + public StringExpression displayNameExpression() { + return displayName; + } +} diff --git a/src/fr/uca/iut/clfreville2/model/sensor/package-info.java b/src/fr/uca/iut/clfreville2/model/sensor/package-info.java new file mode 100644 index 0000000..6261cfc --- /dev/null +++ b/src/fr/uca/iut/clfreville2/model/sensor/package-info.java @@ -0,0 +1,4 @@ +/** + * Represent different types of sensors. + */ +package fr.uca.iut.clfreville2.model.sensor; diff --git a/src/fr/uca/iut/clfreville2/model/shared/Identifiable.java b/src/fr/uca/iut/clfreville2/model/shared/Identifiable.java new file mode 100644 index 0000000..8d88990 --- /dev/null +++ b/src/fr/uca/iut/clfreville2/model/shared/Identifiable.java @@ -0,0 +1,21 @@ +package fr.uca.iut.clfreville2.model.shared; + +/** + * An object that can be differentiated by an id. + */ +public interface Identifiable extends Nameable { + + /** + * Get the id of this object. + * + * @return The id. + */ + int getId(); + + /** + * Set the name of this object. + * + * @param name The name. + */ + void setName(String name); +} diff --git a/src/fr/uca/iut/clfreville2/model/shared/Nameable.java b/src/fr/uca/iut/clfreville2/model/shared/Nameable.java new file mode 100644 index 0000000..f329361 --- /dev/null +++ b/src/fr/uca/iut/clfreville2/model/shared/Nameable.java @@ -0,0 +1,26 @@ +package fr.uca.iut.clfreville2.model.shared; + +/** + * Something that has a human-friendly name. + *

+ * This interface differs from {@link Object#toString()} in that it explicitly + * states that the name is not for debugging purposes. + */ +public interface Nameable { + + /** + * Get the name of this object. + * + * @return The name of this object. + */ + String getName(); + + /** + * Get the display name of this object. + * + * @return The display name. + */ + default String getDisplayName() { + return getName(); + } +} diff --git a/src/fr/uca/iut/clfreville2/model/shared/ObservableIdentifiable.java b/src/fr/uca/iut/clfreville2/model/shared/ObservableIdentifiable.java new file mode 100644 index 0000000..fa7d81f --- /dev/null +++ b/src/fr/uca/iut/clfreville2/model/shared/ObservableIdentifiable.java @@ -0,0 +1,35 @@ +package fr.uca.iut.clfreville2.model.shared; + +import javafx.beans.binding.StringExpression; +import javafx.beans.property.ReadOnlyIntegerProperty; +import javafx.beans.property.StringProperty; + +/** + * An identifiable object that can be observed. + */ +public interface ObservableIdentifiable extends Identifiable { + + /** + * Get the id property of this object. + * + * @return The id property. + * @see #getId() + */ + ReadOnlyIntegerProperty idProperty(); + + /** + * Get the name property of this object. + * + * @return The name property. + * @see #getName() + */ + StringProperty nameProperty(); + + /** + * Get the display name of this object. + * + * @return The display name. + * @see #getDisplayName() + */ + StringExpression displayNameExpression(); +} diff --git a/src/fr/uca/iut/clfreville2/model/shared/TemperatureHolder.java b/src/fr/uca/iut/clfreville2/model/shared/TemperatureHolder.java new file mode 100644 index 0000000..d02c6d4 --- /dev/null +++ b/src/fr/uca/iut/clfreville2/model/shared/TemperatureHolder.java @@ -0,0 +1,14 @@ +package fr.uca.iut.clfreville2.model.shared; + +/** + * An object that can have a numeric value. + */ +public interface TemperatureHolder { + + /** + * Get the temperature of this object. + * + * @return The temperature. + */ + double getTemperature(); +} diff --git a/src/fr/uca/iut/clfreville2/model/shared/package-info.java b/src/fr/uca/iut/clfreville2/model/shared/package-info.java new file mode 100644 index 0000000..1323f52 --- /dev/null +++ b/src/fr/uca/iut/clfreville2/model/shared/package-info.java @@ -0,0 +1,4 @@ +/** + * Group commons interfaces and classes. + */ +package fr.uca.iut.clfreville2.model.shared; diff --git a/src/fr/uca/iut/clfreville2/persistence/SensorRegistryLoader.java b/src/fr/uca/iut/clfreville2/persistence/SensorRegistryLoader.java new file mode 100644 index 0000000..03f1c40 --- /dev/null +++ b/src/fr/uca/iut/clfreville2/persistence/SensorRegistryLoader.java @@ -0,0 +1,14 @@ +package fr.uca.iut.clfreville2.persistence; + +import fr.uca.iut.clfreville2.model.SensorRegistry; + +@FunctionalInterface +public interface SensorRegistryLoader { + + /** + * Load the registry. + * + * @return The loaded registry. + */ + SensorRegistry load(); +} diff --git a/src/fr/uca/iut/clfreville2/persistence/SensorRegistrySaver.java b/src/fr/uca/iut/clfreville2/persistence/SensorRegistrySaver.java new file mode 100644 index 0000000..0be5566 --- /dev/null +++ b/src/fr/uca/iut/clfreville2/persistence/SensorRegistrySaver.java @@ -0,0 +1,14 @@ +package fr.uca.iut.clfreville2.persistence; + +import fr.uca.iut.clfreville2.model.SensorRegistry; + +@FunctionalInterface +public interface SensorRegistrySaver { + + /** + * Save the registry. + * + * @param registry The registry to save. + */ + void save(SensorRegistry registry); +} diff --git a/src/fr/uca/iut/clfreville2/persistence/StubSensorRegistryLoader.java b/src/fr/uca/iut/clfreville2/persistence/StubSensorRegistryLoader.java new file mode 100644 index 0000000..f910142 --- /dev/null +++ b/src/fr/uca/iut/clfreville2/persistence/StubSensorRegistryLoader.java @@ -0,0 +1,14 @@ +package fr.uca.iut.clfreville2.persistence; + +import fr.uca.iut.clfreville2.model.SensorRegistry; + +public class StubSensorRegistryLoader implements SensorRegistryLoader { + @Override + public SensorRegistry load() { + SensorRegistry registry = new SensorRegistry(); + registry.createManual("Sensor 1"); + registry.createManual("Sensor 2"); + registry.createManual("Sensor 3"); + return registry; + } +}