Use a tree view
This commit is contained in:
BIN
resources/images/captor_icon.png
Normal file
BIN
resources/images/captor_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
BIN
resources/images/multi_captor_icon.png
Normal file
BIN
resources/images/multi_captor_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
@@ -1,7 +1,6 @@
|
||||
<?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?>
|
||||
@@ -13,10 +12,11 @@
|
||||
<?import javafx.scene.control.Spinner?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TreeView?>
|
||||
<BorderPane xmlns:fx="http://javafx.com/fxml" prefHeight="400.0" prefWidth="600.0">
|
||||
<center>
|
||||
<SplitPane>
|
||||
<ListView fx:id="sensorsList" />
|
||||
<TreeView fx:id="sensorTree" />
|
||||
<VBox alignment="TOP_CENTER">
|
||||
<padding>
|
||||
<Insets bottom="8.0" left="8.0" right="8.0" top="8.0"/>
|
||||
@@ -34,6 +34,7 @@
|
||||
<TableView fx:id="sourcesView">
|
||||
<columns>
|
||||
<TableColumn fx:id="sourceWeight" text="Weight" />
|
||||
<TableColumn fx:id="sourceIcon" text="Icon" />
|
||||
<TableColumn fx:id="sourceId" text="Id" />
|
||||
</columns>
|
||||
</TableView>
|
||||
|
@@ -1,10 +1,12 @@
|
||||
package fr.uca.iut.clfreville2.gui;
|
||||
|
||||
import fr.uca.iut.clfreville2.gui.image.ImageSupplier;
|
||||
import fr.uca.iut.clfreville2.gui.image.SensorTypeImageSupplier;
|
||||
import fr.uca.iut.clfreville2.gui.image.StandardImageSupplier;
|
||||
import fr.uca.iut.clfreville2.gui.list.NameableListCell;
|
||||
import fr.uca.iut.clfreville2.gui.table.WeightSpinnerTableCell;
|
||||
import fr.uca.iut.clfreville2.gui.thread.Ticker;
|
||||
import fr.uca.iut.clfreville2.gui.tree.SensorTreeCell;
|
||||
import fr.uca.iut.clfreville2.gui.tree.SensorTreeItemBridge;
|
||||
import fr.uca.iut.clfreville2.model.SensorRegistry;
|
||||
import fr.uca.iut.clfreville2.model.binding.ToBooleanBinding;
|
||||
import fr.uca.iut.clfreville2.model.sensor.ManualSensor;
|
||||
@@ -16,12 +18,15 @@ import javafx.collections.FXCollections;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.control.Slider;
|
||||
import javafx.scene.control.Spinner;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.TreeItem;
|
||||
import javafx.scene.control.TreeView;
|
||||
import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.stage.Stage;
|
||||
@@ -30,11 +35,12 @@ public class MainWindows {
|
||||
|
||||
private final SensorRegistry registry = new StubSensorRegistryLoader().load();
|
||||
private final ImageSupplier imageSupplier = new StandardImageSupplier();
|
||||
private final ImageSupplier imageTypeSupplier = new SensorTypeImageSupplier();
|
||||
private final Ticker ticker;
|
||||
private final ModalFactory modalFactory;
|
||||
|
||||
@FXML
|
||||
private ListView<Sensor> sensorsList;
|
||||
private TreeView<Sensor> sensorTree;
|
||||
|
||||
@FXML
|
||||
private Text sensorId;
|
||||
@@ -51,6 +57,9 @@ public class MainWindows {
|
||||
@FXML
|
||||
private TableView<VirtualSensor.DataSource> sourcesView;
|
||||
|
||||
@FXML
|
||||
private TableColumn<VirtualSensor.DataSource, Sensor> sourceIcon;
|
||||
|
||||
@FXML
|
||||
private TableColumn<VirtualSensor.DataSource, VirtualSensor.DataSource> sourceWeight;
|
||||
|
||||
@@ -105,26 +114,26 @@ public class MainWindows {
|
||||
|
||||
@FXML
|
||||
private void initialize() {
|
||||
bindSensorList();
|
||||
bindSensorTree();
|
||||
bindActiveButtons();
|
||||
bindSources();
|
||||
bindUpdate();
|
||||
}
|
||||
|
||||
@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());
|
||||
private void bindSensorTree() {
|
||||
sensorTree.setCellFactory(tree -> new SensorTreeCell(imageTypeSupplier));
|
||||
sensorTree.setRoot(SensorTreeItemBridge.create(registry));
|
||||
sensorTree.getSelectionModel().selectedItemProperty().addListener((list, oldValue, newValue) -> {
|
||||
if (oldValue != null && oldValue.getValue() != null) {
|
||||
sensorName.textProperty().unbindBidirectional(oldValue.getValue().nameProperty());
|
||||
sourcesView.itemsProperty().unbind();
|
||||
sourcesView.setItems(FXCollections.emptyObservableList());
|
||||
}
|
||||
if (newValue != null) {
|
||||
sensorId.textProperty().bind(newValue.displayNameExpression());
|
||||
sensorName.textProperty().bindBidirectional(newValue.nameProperty());
|
||||
if (newValue instanceof VirtualSensor virtual) {
|
||||
if (newValue != null && newValue.getValue() != null) {
|
||||
sensorId.textProperty().bind(newValue.getValue().displayNameExpression());
|
||||
sensorName.textProperty().bindBidirectional(newValue.getValue().nameProperty());
|
||||
if (newValue.getValue() instanceof VirtualSensor virtual) {
|
||||
sourcesView.itemsProperty().bind(virtual.sourcesProperty());
|
||||
}
|
||||
} else {
|
||||
@@ -137,16 +146,28 @@ public class MainWindows {
|
||||
@FXML
|
||||
private void bindActiveButtons() {
|
||||
changeBtn.visibleProperty().bind(new ToBooleanBinding<>(
|
||||
sensorsList.getSelectionModel().selectedItemProperty(),
|
||||
treeItem -> treeItem instanceof ManualSensor
|
||||
sensorTree.getSelectionModel().selectedItemProperty(),
|
||||
treeItem -> treeItem != null && treeItem.getValue() instanceof ManualSensor
|
||||
));
|
||||
visualizeBtn.visibleProperty().bind(sensorsList.getSelectionModel().selectedItemProperty().isNotNull());
|
||||
visualizeBtn.visibleProperty().bind(sensorTree.getSelectionModel().selectedItemProperty().isNotNull());
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void bindSources() {
|
||||
sourceWeight.setCellValueFactory(cell -> new SimpleObjectProperty<>(cell.getValue()));
|
||||
sourceWeight.setCellFactory(cell -> new WeightSpinnerTableCell());
|
||||
sourceIcon.setCellValueFactory(cell -> new SimpleObjectProperty<>(cell.getValue().sensor()));
|
||||
sourceIcon.setCellFactory(cell -> new TableCell<>() {
|
||||
@Override
|
||||
protected void updateItem(Sensor item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (empty) {
|
||||
setGraphic(null);
|
||||
} else {
|
||||
setGraphic(new ImageView(imageTypeSupplier.apply(item)));
|
||||
}
|
||||
}
|
||||
});
|
||||
sourceId.setCellValueFactory(cell -> cell.getValue().sensor().idProperty().asString());
|
||||
}
|
||||
|
||||
@@ -157,6 +178,10 @@ public class MainWindows {
|
||||
}
|
||||
|
||||
private Sensor getSelectedSensor() {
|
||||
return sensorsList.getSelectionModel().getSelectedItem();
|
||||
TreeItem<Sensor> selected = sensorTree.getSelectionModel().getSelectedItem();
|
||||
if (selected == null) {
|
||||
return null;
|
||||
}
|
||||
return selected.getValue();
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,24 @@
|
||||
package fr.uca.iut.clfreville2.gui.image;
|
||||
|
||||
import fr.uca.iut.clfreville2.model.sensor.Sensor;
|
||||
import fr.uca.iut.clfreville2.model.sensor.VirtualSensor;
|
||||
import javafx.scene.image.Image;
|
||||
|
||||
public class SensorTypeImageSupplier implements ImageSupplier {
|
||||
|
||||
private final Image simpleIcon;
|
||||
private final Image multiIcon;
|
||||
|
||||
public SensorTypeImageSupplier() {
|
||||
simpleIcon = new Image("/images/captor_icon.png");
|
||||
multiIcon = new Image("/images/multi_captor_icon.png");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image apply(Sensor sensor) {
|
||||
if (sensor instanceof VirtualSensor) {
|
||||
return multiIcon;
|
||||
}
|
||||
return simpleIcon;
|
||||
}
|
||||
}
|
31
src/fr/uca/iut/clfreville2/gui/tree/SensorTreeCell.java
Normal file
31
src/fr/uca/iut/clfreville2/gui/tree/SensorTreeCell.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package fr.uca.iut.clfreville2.gui.tree;
|
||||
|
||||
import fr.uca.iut.clfreville2.gui.image.ImageSupplier;
|
||||
import fr.uca.iut.clfreville2.model.sensor.Sensor;
|
||||
import javafx.scene.control.TreeCell;
|
||||
import javafx.scene.image.ImageView;
|
||||
|
||||
public class SensorTreeCell extends TreeCell<Sensor> {
|
||||
|
||||
private final ImageView imageView = new ImageView();
|
||||
|
||||
private final ImageSupplier imageSupplier;
|
||||
|
||||
public SensorTreeCell(ImageSupplier imageSupplier) {
|
||||
this.imageSupplier = imageSupplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateItem(Sensor item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (empty || item == null) {
|
||||
textProperty().unbind();
|
||||
textProperty().setValue(null);
|
||||
setGraphic(null);
|
||||
} else {
|
||||
imageView.setImage(imageSupplier.apply(item));
|
||||
textProperty().bind(item.displayNameExpression());
|
||||
setGraphic(imageView);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,82 @@
|
||||
package fr.uca.iut.clfreville2.gui.tree;
|
||||
|
||||
import fr.uca.iut.clfreville2.model.SensorRegistry;
|
||||
import fr.uca.iut.clfreville2.model.sensor.Sensor;
|
||||
import fr.uca.iut.clfreville2.model.sensor.VirtualSensor;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.scene.control.TreeItem;
|
||||
|
||||
public final class SensorTreeItemBridge {
|
||||
|
||||
private SensorTreeItemBridge() {}
|
||||
|
||||
public static TreeItem<Sensor> create(Sensor sensor) {
|
||||
TreeItem<Sensor> item = new TreeItem<>(sensor);
|
||||
if (sensor instanceof VirtualSensor virtual) {
|
||||
addChildren(virtual.sourcesProperty(), item);
|
||||
virtual.sourcesProperty().addListener(new ListChangeListener<VirtualSensor.DataSource>() {
|
||||
@Override
|
||||
public void onChanged(Change<? extends VirtualSensor.DataSource> change) {
|
||||
while (change.next()) {
|
||||
if (change.wasPermutated()) {
|
||||
throw new UnsupportedOperationException();
|
||||
} else if (change.wasUpdated()) {
|
||||
throw new UnsupportedOperationException();
|
||||
} else {
|
||||
addChildren(change.getAddedSubList(), item);
|
||||
removeChildren(change.getRemoved(), item);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
public static TreeItem<Sensor> create(SensorRegistry registry) {
|
||||
TreeItem<Sensor> root = new TreeItem<>();
|
||||
for (Sensor sensor : registry) {
|
||||
root.getChildren().add(create(sensor));
|
||||
}
|
||||
registry.sensorsProperty().addListener(new ListChangeListener<Sensor>() {
|
||||
@Override
|
||||
public void onChanged(Change<? extends Sensor> change) {
|
||||
while (change.next()) {
|
||||
if (change.wasPermutated()) {
|
||||
throw new UnsupportedOperationException();
|
||||
} else if (change.wasUpdated()) {
|
||||
throw new UnsupportedOperationException();
|
||||
} else {
|
||||
addSensors(change.getAddedSubList(), root);
|
||||
removeSensors(change.getRemoved(), root);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return root;
|
||||
}
|
||||
|
||||
private static void addSensors(Iterable<? extends Sensor> sensors, TreeItem<Sensor> item) {
|
||||
for (Sensor sensor : sensors) {
|
||||
item.getChildren().add(create(sensor));
|
||||
}
|
||||
}
|
||||
|
||||
private static void addChildren(Iterable<? extends VirtualSensor.DataSource> sources, TreeItem<Sensor> item) {
|
||||
for (VirtualSensor.DataSource source : sources) {
|
||||
item.getChildren().add(create(source.sensor()));
|
||||
}
|
||||
}
|
||||
|
||||
private static void removeChildren(Iterable<? extends VirtualSensor.DataSource> sources, TreeItem<Sensor> item) {
|
||||
for (VirtualSensor.DataSource source : sources) {
|
||||
item.getChildren().removeIf(child -> child.getValue().equals(source.sensor()));
|
||||
}
|
||||
}
|
||||
|
||||
private static void removeSensors(Iterable<? extends Sensor> sensors, TreeItem<Sensor> item) {
|
||||
for (Sensor sensor : sensors) {
|
||||
item.getChildren().removeIf(child -> child.getValue().equals(sensor));
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user