Initial commit
This commit is contained in:
30
.gitignore
vendored
Normal file
30
.gitignore
vendored
Normal file
@@ -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
|
13
Ebullition.iml
Normal file
13
Ebullition.iml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="library" name="OpenJFX" level="application" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
BIN
resources/images/visualizer/cold.jpg
Normal file
BIN
resources/images/visualizer/cold.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
BIN
resources/images/visualizer/hot.jpg
Normal file
BIN
resources/images/visualizer/hot.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
BIN
resources/images/visualizer/warm.jpg
Normal file
BIN
resources/images/visualizer/warm.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
29
resources/windows/MainWindows.fxml
Normal file
29
resources/windows/MainWindows.fxml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.scene.control.SplitPane?>
|
||||||
|
<?import javafx.scene.control.ListView?>
|
||||||
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
<?import javafx.scene.text.Text?>
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.control.TextField?>
|
||||||
|
<?import javafx.scene.layout.BorderPane?>
|
||||||
|
<?import javafx.scene.control.Button?>
|
||||||
|
<SplitPane xmlns:fx="http://javafx.com/fxml" prefHeight="400.0" prefWidth="600.0"
|
||||||
|
fx:controller="fr.uca.iut.clfreville2.gui.MainWindows">
|
||||||
|
<ListView fx:id="sensorsList" />
|
||||||
|
<VBox alignment="TOP_CENTER">
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="8.0" left="8.0" right="8.0" top="8.0"/>
|
||||||
|
</padding>
|
||||||
|
<Text fx:id="sensorId" text="Details" />
|
||||||
|
<TextField fx:id="sensorName" />
|
||||||
|
<BorderPane>
|
||||||
|
<left>
|
||||||
|
<Button fx:id="changeBtn" onAction="#onChangeClick" visible="false">Change</Button>
|
||||||
|
</left>
|
||||||
|
<right>
|
||||||
|
<Button fx:id="visualizeBtn" onAction="#onVisualizeClick">Visualize</Button>
|
||||||
|
</right>
|
||||||
|
</BorderPane>
|
||||||
|
</VBox>
|
||||||
|
</SplitPane>
|
18
src/fr/uca/iut/clfreville2/MainApplication.java
Normal file
18
src/fr/uca/iut/clfreville2/MainApplication.java
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
121
src/fr/uca/iut/clfreville2/gui/MainWindows.java
Normal file
121
src/fr/uca/iut/clfreville2/gui/MainWindows.java
Normal file
@@ -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<Sensor> 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;
|
||||||
|
}
|
||||||
|
}
|
44
src/fr/uca/iut/clfreville2/gui/ModalFactory.java
Normal file
44
src/fr/uca/iut/clfreville2/gui/ModalFactory.java
Normal file
@@ -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<Pane> 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<Pane> 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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
12
src/fr/uca/iut/clfreville2/gui/image/ImageSupplier.java
Normal file
12
src/fr/uca/iut/clfreville2/gui/image/ImageSupplier.java
Normal file
@@ -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<Sensor, Image> {
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
17
src/fr/uca/iut/clfreville2/gui/list/NameableListCell.java
Normal file
17
src/fr/uca/iut/clfreville2/gui/list/NameableListCell.java
Normal file
@@ -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<T extends ObservableIdentifiable> extends ListCell<T> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateItem(T item, boolean empty) {
|
||||||
|
super.updateItem(item, empty);
|
||||||
|
if (empty || item == null) {
|
||||||
|
textProperty().unbind();
|
||||||
|
} else {
|
||||||
|
textProperty().bind(item.displayNameExpression());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
67
src/fr/uca/iut/clfreville2/model/SensorRegistry.java
Normal file
67
src/fr/uca/iut/clfreville2/model/SensorRegistry.java
Normal file
@@ -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<Sensor> {
|
||||||
|
|
||||||
|
private final IntSupplier nextIdSupplier = new SequenceIntSupplier();
|
||||||
|
private final ObservableList<Sensor> sensors = FXCollections.observableArrayList();
|
||||||
|
private final ListProperty<Sensor> 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 <T> The type of sensor.
|
||||||
|
*/
|
||||||
|
protected <T extends Sensor> 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<Sensor> getSensors() {
|
||||||
|
return FXCollections.unmodifiableObservableList(sensors);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the read-only list property of sensors.
|
||||||
|
*
|
||||||
|
* @return The list property of sensors.
|
||||||
|
*/
|
||||||
|
public ReadOnlyListProperty<Sensor> sensorsProperty() {
|
||||||
|
return sensorsList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Sensor> iterator() {
|
||||||
|
return getSensors().iterator();
|
||||||
|
}
|
||||||
|
}
|
18
src/fr/uca/iut/clfreville2/model/SequenceIntSupplier.java
Normal file
18
src/fr/uca/iut/clfreville2/model/SequenceIntSupplier.java
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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 <T> 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<T> extends BooleanBinding {
|
||||||
|
|
||||||
|
private final ObservableObjectValue<T> target;
|
||||||
|
private final Predicate<T> predicate;
|
||||||
|
|
||||||
|
public ToBooleanBinding(ObservableObjectValue<T> target, Predicate<T> 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);
|
||||||
|
}
|
||||||
|
}
|
20
src/fr/uca/iut/clfreville2/model/sensor/ManualSensor.java
Normal file
20
src/fr/uca/iut/clfreville2/model/sensor/ManualSensor.java
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
73
src/fr/uca/iut/clfreville2/model/sensor/Sensor.java
Normal file
73
src/fr/uca/iut/clfreville2/model/sensor/Sensor.java
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,4 @@
|
|||||||
|
/**
|
||||||
|
* Represent different types of sensors.
|
||||||
|
*/
|
||||||
|
package fr.uca.iut.clfreville2.model.sensor;
|
21
src/fr/uca/iut/clfreville2/model/shared/Identifiable.java
Normal file
21
src/fr/uca/iut/clfreville2/model/shared/Identifiable.java
Normal file
@@ -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);
|
||||||
|
}
|
26
src/fr/uca/iut/clfreville2/model/shared/Nameable.java
Normal file
26
src/fr/uca/iut/clfreville2/model/shared/Nameable.java
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package fr.uca.iut.clfreville2.model.shared;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Something that has a human-friendly name.
|
||||||
|
* <p>
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
}
|
@@ -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();
|
||||||
|
}
|
@@ -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();
|
||||||
|
}
|
@@ -0,0 +1,4 @@
|
|||||||
|
/**
|
||||||
|
* Group commons interfaces and classes.
|
||||||
|
*/
|
||||||
|
package fr.uca.iut.clfreville2.model.shared;
|
@@ -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();
|
||||||
|
}
|
@@ -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);
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user