Use a tree view

main
Clément FRÉVILLE 2 years ago
parent 1972d81aa1
commit ded77eeb66

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

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;
}
}

@ -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));
}
}
}
Loading…
Cancel
Save