Adding TreeView Implementation

master
Corentin RICHARD 2 years ago
parent 09f8b96d7c
commit 841ee2f43f

@ -0,0 +1,75 @@
/*
* Copyright (c) 2012, 2014 Oracle and/or its affiliates.
* All rights reserved. Use is subject to license terms.
*
* This file is available and licensed under the following license:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the distribution.
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
root {
display: block;
}
.root {
-fx-background-image: url("https://www.francetvinfo.fr/pictures/zwzFc6PU5JuzL2NA0BwMqhCrvo0/1200x900/2016/08/23/shrek-5.jpg");
}
.label {
-fx-font-size: 12px;
-fx-font-weight: bold;
-fx-text-fill: #333333;
-fx-effect: dropshadow( gaussian , rgba(255,255,255,0.5) , 0,0,0,1 );
}
#welcome {
-fx-font-size: 75px;
-fx-font-family: "Arial Black";
-fx-fill: #818181;
-fx-effect: innershadow( three-pass-box , rgba(0,0,0,0.7) , 6, 0.0 , 0 , 2 );
}
#left{
-fx-text-fill: red;
}
.button {
-fx-text-fill: white;
-fx-font-family: "Arial Narrow";
-fx-font-weight: bold;
-fx-background-color: #B0E0E6;
-fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0 , 1 );
}
.button:hover {
-fx-background-color: linear-gradient(#2A5058, #61a2b1);
}
#rectangle{
-fx-background-image: url("https://i-mom.unimedias.fr/2020/09/16/gingy-shrek.jpg?auto=format,compress&cs=tinysrgb");
}

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Text?>
<BorderPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
prefHeight="400.0" prefWidth="600.0">
<Text fx:id="temp"/>
</BorderPane>

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Text?>
<SplitPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
prefHeight="400.0" prefWidth="600.0">
<items>
<TreeView fx:id="tree"/>
<VBox fx:id="vBox">
<TextField fx:id="name"/>
<Text fx:id="id"/>
<TextField fx:id="temperature"/>
</VBox>
</items>
</SplitPane>

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.text.Text?>
<?import javafx.scene.image.ImageView?>
<SplitPane dividerPositions="0.3"
xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
prefWidth="550" prefHeight="350">
<items>
<Text fx:id="temperature"/>
<ImageView fx:id="image" fitHeight="350" fitWidth="500"/>
</items>
</SplitPane>

@ -1,13 +1,16 @@
package Launcher;
import Model.ImageSensor;
import Model.StubLib;
import View.TreeViewController;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.stage.Stage;
import Model.Sensor;
import View.ImageSensorController;
import Model.ImageSensor;
import java.io.IOException;
@ -15,17 +18,21 @@ public class Launch extends Application {
@Override
public void start(Stage primaryStage) throws IOException {
ImageSensor imgSens = new ImageSensor(1,"ImageSensor");
ObservableList<Sensor> list = StubLib.genList();
TreeViewController tree = new TreeViewController(list,"/FXML/TreeView.fxml","S1");
Thread t = new Thread(()->{
while (true){
try{
Thread.sleep(1000);
Platform.runLater(()-> {
try{
imgSens.getTemperature();
}catch (Exception e){
throw new RuntimeException(e);
for (Sensor s : list){
try{
s.genTemp();
}catch (Exception e){
throw new RuntimeException(e);
}
}
});
@ -37,6 +44,8 @@ public class Launch extends Application {
t.start();
}
public static void main(String args[]) {
Application.launch(args);
}

@ -0,0 +1,13 @@
package Model;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class CpuGenerator implements IGenStrategy{
@Override
public float generate() throws IOException{
return Float.parseFloat(Files.readString(Path.of("/sys/class/thermal/thermal_zone2/temp")));
}
}

@ -0,0 +1,19 @@
package Model;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class CpuSensor extends SimpleSensor{
public CpuSensor(float t,String n){
super(t,n,new CpuGenerator());
}
public CpuSensor(Sensor s){
super(s);
}
@Override
public void genTemp()throws IOException {
setTemperature(Float.parseFloat(Files.readString(Path.of("/sys/class/thermal/thermal_zone2/temp"))));
}
}

@ -1,5 +1,7 @@
package Model;
import java.io.IOException;
public interface IGenStrategy {
abstract int generate();
abstract float generate() throws IOException;
}

@ -0,0 +1,6 @@
package Model;
public interface IVisitor<T> {
T visit(SimpleSensor sens);
T visit(VirtualSensor sens);
}

@ -6,14 +6,19 @@ import javafx.scene.image.Image;
import java.util.Random;
@Deprecated
public class ImageSensor extends SimpleSensor{
private final ObjectProperty<Image> image = new SimpleObjectProperty<>();
public ObjectProperty<Image> getImage(){return image;}
public void setImage(Image image){this.image.set(image);}
public ImageSensor(float t, String n) {
super(t, n, new RandomGenerator());
super(t, n, new CpuGenerator());
}
public ImageSensor(Sensor s){
super(s);
}
@Override

@ -4,7 +4,7 @@ import java.util.Random;
public class RandomGenerator implements IGenStrategy{
@Override
public int generate() {
public float generate() {
Random rand = new Random();
return rand.nextInt(50);
}

@ -0,0 +1,19 @@
package Model;
import java.util.Random;
@Deprecated
public class RandomSensor extends SimpleSensor {
public RandomSensor(float t,String n){
super(t,n,new RandomGenerator());
}
public RandomSensor(Sensor s){
super(s);
}
@Override
public void genTemp(){
Random random = new Random();
setTemperature((random.nextFloat(50)));
}
}

@ -5,6 +5,7 @@ import javafx.beans.property.SimpleFloatProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import java.io.IOException;
import java.util.UUID;
public abstract class Sensor {
@ -26,7 +27,16 @@ public abstract class Sensor {
this.name.set(n);
}
public abstract void genTemp();
public Sensor(Sensor s){
this.temperature.set(s.getTemperature());
this.name.set(s.getName());
this.id.set(s.getId());
}
public abstract void genTemp() throws IOException;
public abstract <T> T accept(IVisitor<T> v);
@Override
public boolean equals(Object sens){
return getId().equals(((Sensor)sens).getId());
}
}

@ -1,5 +1,9 @@
package Model;
import javafx.scene.control.TreeItem;
import java.io.IOException;
public class SimpleSensor extends Sensor{
private IGenStrategy gen;
@ -8,12 +12,23 @@ public class SimpleSensor extends Sensor{
this.gen = genStrat;
}
private void setStrategy(IGenStrategy g){
public void setStrategy(IGenStrategy g){
gen = g;
}
public SimpleSensor(Sensor s){
super(s);
}
@Override
public void genTemp() {
public void genTemp() throws IOException {
setTemperature(gen.generate());
}
@Override
public TreeItem<Sensor> accept(IVisitor v){
return (TreeItem<Sensor>) v.visit(this);
}
}

@ -0,0 +1,35 @@
package Model;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import java.util.ArrayList;
import java.util.List;
public class StubLib {
public static Sensor genSensor(){
VirtualSensor s = new VirtualSensor(1,"Sensor n°1");
s.addSensor(new CpuSensor(56,"Cpu n°1"),5F);
s.addSensor(new CpuSensor(92,"Cpu n°2"),9F);
s.addSensor(new RandomSensor(6,"Rand n°1"),25F);
s.addSensor(new RandomSensor(45,"Rand n°2"),12F);
s.addSensor(new RandomSensor(78,"Rand n°3"),14F);
return s;
}
public static ObservableList<Sensor> genList() {
List<Sensor> s = new ArrayList<>();
VirtualSensor v = new VirtualSensor(84, "Sensor n°2");
v.addSensor(new SimpleSensor(9, "Simple n°1", new CpuGenerator()), 8F);
v.addSensor(new SimpleSensor(10, "Simple n°2", new RandomGenerator()), 4F);
VirtualSensor c = new VirtualSensor(7, "Virtual");
c.addSensor(new SimpleSensor(8, "Simple n°3", new CpuGenerator()), 8F);
v.addSensor(c, 7F);
s.add(v);
s.add(new SimpleSensor(7, "Simple n°4", new RandomGenerator()));
s.add(new SimpleSensor(7, "Simple n°5", new CpuGenerator()));
return FXCollections.observableList(s);
}
}

@ -0,0 +1,19 @@
package Model;
import com.sun.javafx.print.Units;
import javafx.scene.control.TreeItem;
public class TreeViewV implements IVisitor<TreeItem<Sensor>>{
@Override
public TreeItem<Sensor> visit(SimpleSensor s){
return new TreeItem<>(s);
}
@Override
public TreeItem<Sensor> visit(VirtualSensor s){
TreeItem<Sensor> item = new TreeItem<>(s);
for (Sensor sensor: s.getSensors().values()){
item.getChildren().add(sensor.accept(this));
}return item;
}
}

@ -0,0 +1,47 @@
package Model;
import javafx.beans.property.ListProperty;
import javafx.beans.property.MapProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleMapProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.ObservableMap;
import javafx.scene.control.TreeItem;
public class VirtualSensor extends Sensor {
public VirtualSensor(float t,String n){
super(t,n);
}
private ObservableMap<Float, Sensor> oSensor = FXCollections.observableHashMap();
private final MapProperty<Float, Sensor> sensors = new SimpleMapProperty<>(oSensor);
public ObservableMap<Float, Sensor> getSensors() {return sensors.getValue();}
public void addSensor(Sensor s, Float w) {
oSensor.put(w, s);
}
@Override
public void genTemp() {
float total=0;
if (getSensors().size()==0){
setTemperature(0);
return;
}
for (ObservableMap.Entry<Float, Sensor> map : oSensor.entrySet()) {
total+=map.getValue().getTemperature()*map.getKey();
}
if (getSensors().size()==0) return;
total=total/getSensors().size();
setTemperature(total);
}
@Override
public TreeItem<Sensor> accept(IVisitor v){
return (TreeItem<Sensor>) v.visit(this);
}
}

@ -1,18 +1,19 @@
package View;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.SubScene;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URL;
public class FXMLWindow extends Stage {
public FXMLWindow(String title,String url)throws IOException{
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getClassLoader().getResource(url));
public FXMLWindow(String url,String title)throws IOException{
FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource(url));
fxmlLoader.setController(this);
Parent group = fxmlLoader.load();
this.setScene(new Scene(group));
setScene(new Scene(fxmlLoader.load()));
this.show();
}
}

@ -1,13 +1,15 @@
package View;
import Model.ImageSensor;
import Model.Sensor;
import javafx.fxml.FXML;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.text.Text;
import javafx.util.converter.NumberStringConverter;
import java.io.IOException;
import Model.ImageSensor;
public class ImageSensorController extends FXMLWindow{
@FXML
@ -16,9 +18,17 @@ public class ImageSensorController extends FXMLWindow{
@FXML
private ImageView img;
public ImageSensorController(ImageSensor sens,String title, String url) throws IOException {
super(title, url);
temp.textProperty().bindBidirectional(sens.temperatureProperty(),new NumberStringConverter());
img.imageProperty().bindBidirectional(sens.getImage());
public ImageSensorController(Sensor s,String url,String title) throws IOException{
super(url,title);
temp.textProperty().bindBidirectional(s.temperatureProperty(),new NumberStringConverter());
if(s.getTemperature()<0){
img.setImage(new Image("Img/snow-1674382959288-6329.jpg"));
}
else if(s.getTemperature()>=0 && s.getTemperature()<20){
img.setImage(new Image("Img/Warm-Green-Landscape-Mountains-Wallpaper-1920x1200-1387564693.jpg"));
}else{
img.setImage(new Image("Img/videoblocks-panoramic-view-sand-dunes-and-hills-in-hot-desert-wilderness-desert-landscape_h0eyeniim_thumbnail-1080_01.png"));
}
}
}

@ -0,0 +1,19 @@
package View;
import Model.Sensor;
import javafx.fxml.FXML;
import javafx.scene.text.Text;
import javafx.util.converter.NumberStringConverter;
import java.io.IOException;
public class TextSensorController extends FXMLWindow{
@FXML
private Text temp;
public TextSensorController(Sensor s,String url,String title)throws IOException{
super(url,title);
temp.textProperty().bindBidirectional(s.temperatureProperty(),new NumberStringConverter());
}
}

@ -0,0 +1,147 @@
package View;
import Model.*;
import javafx.beans.property.ListProperty;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.util.converter.NumberStringConverter;
import java.io.IOException;
public class TreeViewController extends FXMLWindow{
@FXML
private TreeView<Sensor> tree;
@FXML
private TextField name;
@FXML
private Text id;
@FXML
private TextField temperature;
@FXML
private VBox vBox;
private Button textView;
private Button imageView;
private TableView<Sensor> tableView;
private Button changeToCpu;
private Button changeToRandom;
private ObservableList<Sensor> sensorsList;
public TreeViewController(ObservableList<Sensor> sensorsList, String url, String title) throws IOException, IOException {
super(url, title);
this.sensorsList = sensorsList;
changeToCpu = new Button("Change to CPU");
changeToRandom = new Button("Change to Random");
textView = new Button("See In Text View");
imageView = new Button("See In Image View");
TreeItem<Sensor> root = new TreeItem<>();
tree.setRoot(root);
tree.setShowRoot(false);
tree.setCellFactory(capteurTreeView -> new TreeCell<>(){
@Override
protected void updateItem(Sensor item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
textProperty().bind(item.nameProperty());
} else {
textProperty().unbind();
setText("");
}
}
});
for (Sensor s : sensorsList) {
root.getChildren().add(s.accept(new TreeViewV()));
}
tableView = new TableView<>();
TableColumn<Sensor, String> nameCol = new TableColumn<>("Nom");
TableColumn<Sensor, Float> tempCol = new TableColumn<>("Température");
nameCol.setCellValueFactory(new PropertyValueFactory<>("nom"));
tempCol.setCellValueFactory(new PropertyValueFactory<>("temperature"));
tableView.getColumns().addAll(nameCol, tempCol);
}
public void initialize() {
tree.getSelectionModel().selectedItemProperty().addListener((observableValue, old, newV) -> {
if (old != null) {
name.textProperty().unbindBidirectional(old.getValue().nameProperty());
id.textProperty().unbindBidirectional(old.getValue().idProperty());
temperature.textProperty().unbindBidirectional(old.getValue().temperatureProperty());
textView.setOnAction(null);
imageView.setOnAction(null);
vBox.getChildren().removeAll(textView, imageView);
if (old.getValue() instanceof VirtualSensor) {
tableView.getItems().removeAll(((VirtualSensor) old.getValue()).getSensors().values());
vBox.getChildren().remove(tableView);
} else {
changeToCpu.setOnAction(null);
changeToRandom.setOnAction(null);
vBox.getChildren().removeAll(changeToCpu, changeToRandom);
}
}
if (newV != null) {
name.textProperty().bindBidirectional(newV.getValue().nameProperty());
id.textProperty().bindBidirectional(newV.getValue().idProperty());
temperature.textProperty().bindBidirectional(newV.getValue().temperatureProperty(), new NumberStringConverter());
EventHandler<ActionEvent> eventTextView = e -> {
try {
new TextSensorController(newV.getValue(), "/fxml/Capteur.fxml", "TextView");
} catch (IOException ex) {
throw new RuntimeException(ex);
}
};
EventHandler<ActionEvent> eventImageView = e -> {
try {
new TextSensorController(newV.getValue(), "/fxml/ImageCapteur.fxml", "TextView");
} catch (IOException ex) {
throw new RuntimeException(ex);
}
};
textView.setOnAction(eventTextView);
imageView.setOnAction(eventImageView);
vBox.getChildren().addAll(textView, imageView);
if (newV.getValue() instanceof VirtualSensor) {
tableView.getItems().addAll(((VirtualSensor) newV.getValue()).getSensors().values());
vBox.getChildren().add(tableView);
} else {
EventHandler<ActionEvent> eventCpu = e -> {
((SimpleSensor) newV.getValue()).setStrategy(new CpuGenerator());
};
EventHandler<ActionEvent> eventRandom = e -> {
((SimpleSensor) newV.getValue()).setStrategy(new RandomGenerator());
};
changeToCpu.setOnAction(eventCpu);
changeToRandom.setOnAction(eventRandom);
vBox.getChildren().addAll(changeToCpu, changeToRandom);
}
}
});
}
}

@ -0,0 +1,61 @@
package View;
import Model.Sensor;
import Model.VirtualSensor;
import javafx.beans.property.ListProperty;
import javafx.beans.property.*;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextArea;
import javafx.fxml.FXML;
import javafx.util.converter.NumberStringConverter;
import java.io.IOException;
import java.util.ArrayList;
public class VirtualSensorController extends FXMLWindow{
@FXML
private ListView<Sensor> SensorList;
@FXML
private TextArea temp;
@FXML
private TextArea vTemp;
private Sensor sensor;
public VirtualSensorController(VirtualSensor v,String url,String title) throws IOException{
super(url,title);
this.sensor = v;
ListProperty<Sensor> sensors = new SimpleListProperty<>(FXCollections.observableList(new ArrayList<>(v.getSensors().values())));
SensorList.itemsProperty().bind(sensors);
vTemp.textProperty().bindBidirectional(v.temperatureProperty(),new NumberStringConverter());
}
public void initialize(){
SensorList.setCellFactory((param) ->
new ListCell<>(){
@Override
protected void updateItem(Sensor item, boolean empty){
super.updateItem(item,empty);
if(!empty){
textProperty().bind(item.temperatureProperty().asString());
}else {
textProperty().unbind();
setText("");
}
}
});
SensorList.getSelectionModel().selectedItemProperty().addListener((__,old,newV)->{
if (old != null) {
temp.textProperty().unbindBidirectional(old.temperatureProperty());
}
if(newV != null){
temp.textProperty().bindBidirectional((Property<String>)newV.temperatureProperty().asString());
}
});
}
}
Loading…
Cancel
Save