package com.megatim.fdxconvert.views.jsonstructure; import com.megatim.dynamicjsonparser.enums.TypeDonnee; import com.megatim.fdxconvert.App; import com.megatim.fdxconvert.pojo.Delimiteur; import com.megatim.fdxconvert.viewmodel.JsonStructureViewModel; import javafx.application.Platform; import javafx.beans.property.BooleanProperty; import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; import javafx.geometry.Pos; import javafx.scene.Parent; import javafx.scene.control.*; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.util.converter.NumberStringConverter; import java.io.IOException; import java.net.URL; import java.util.List; import java.util.ResourceBundle; import java.util.stream.Collectors; public class JsonStructureController implements Initializable { @FXML private VBox mainContainer; @FXML private HBox fieldContainer; @FXML private HBox formatFieldContainer; @FXML private HBox delimitorFieldContainer; @FXML private TextField nameField; @FXML private ComboBox typeField; @FXML private ComboBox formatField; @FXML private ComboBox delimitorField; @FXML private CheckBox requiredField; @FXML private CheckBox collectionField; @FXML private TextField tailleField; @FXML private Button removeBtn; @FXML private VBox objectContainer; @FXML private HBox objectContainerleft; @FXML private HBox objectContainerRight; @FXML private Label objectSquareBracketLeft; @FXML private Label objectSquareBracketRight; @FXML private HBox formFieldContainer; @FXML private Label squareBracketLeft; @FXML private Label squareBracketRight; @FXML private Button addButton; @FXML private VBox nestedContainer; private final JsonStructureViewModel viewModel; public JsonStructureController(JsonStructureViewModel viewModel) { this.viewModel = viewModel; } @Override public void initialize(URL location, ResourceBundle resources) { viewModel.init(); typeField.setItems(FXCollections.observableArrayList(TypeDonnee.values())); tailleField.textProperty().addListener((observable, oldValue, newValue) -> { if (!newValue.matches("\\d*")) { tailleField.setText(newValue.replaceAll("[^\\d]", "")); } }); formatField.setPromptText("Sélectionnez le format de la date"); formatField.setItems(FXCollections.observableArrayList(App.FORMATS_DATE)); delimitorField.setPromptText("Sélectionnez le délimiteur de la date"); delimitorField.setItems(FXCollections.observableArrayList(App.SEPARATEURS_DATE.values())); nameField.textProperty().bindBidirectional(viewModel.nameProperty()); typeField.valueProperty().bindBidirectional(viewModel.typeProperty()); formatField.valueProperty().bindBidirectional(viewModel.formatProperty()); delimitorField.valueProperty().bindBidirectional(viewModel.delimitorProperty()); requiredField.selectedProperty().bindBidirectional(viewModel.requiredProperty()); collectionField.selectedProperty().bindBidirectional(viewModel.collectionProperty()); tailleField.textProperty().bindBidirectional(viewModel.tailleProperty(), new NumberStringConverter()); nameField.setDisable(viewModel.isRoot()); tailleField.setDisable(viewModel.isRoot()); collectionField.setDisable(viewModel.isRoot()); requiredField.setDisable(viewModel.isRoot()); typeField.setDisable(viewModel.isRoot()); tailleField.disableProperty().bind(viewModel.hasChildProperty()); toggleObjectContainer(viewModel.hasChildProperty().get()); viewModel.hasChildProperty().addListener((observable, oldValue, newValue) -> { toggleObjectContainer(newValue); }); toggleDateFieldContainers(viewModel.hasDateTypeProperty().get()); viewModel.hasDateTypeProperty().addListener((observable, oldValue, newValue) -> { toggleDateFieldContainers(newValue); }); toggleSquareBrackets(viewModel.hasSquareBracketProperty().get()); viewModel.hasSquareBracketProperty().addListener((observable, oldValue, newValue) -> { toggleSquareBrackets(newValue); }); toggleObjectSquareBrackets(viewModel.hasObjectSquareBracketProperty().get()); viewModel.hasObjectSquareBracketProperty().addListener((observable, oldValue, newValue) -> { toggleObjectSquareBrackets(newValue); }); addButton.setOnAction(event -> { viewModel.addNewChild(); }); addChildrenViews(viewModel.getChildren()); viewModel.getChildren().addListener((ListChangeListener) c -> { while (c.next()) { if (c.wasAdded()) { Platform.runLater(() -> { addChildrenViews(c.getAddedSubList().stream().collect(Collectors.toList())); }); } if (c.wasRemoved()) { Platform.runLater(() -> { for (JsonStructureViewModel child : c.getRemoved()) { nestedContainer.getChildren().removeIf(node -> node.getId().equals(child.getId())); } }); } } }); } public BooleanProperty validProperty() { return viewModel.validProperty(); } public NestedJsonStructure nestedJsonStructure() { return viewModel.nestedJsonStructure(); } public void setRootStructureName(String name) { if (viewModel.isRoot()) { viewModel.nameProperty().setValue(name); } } private void addChildrenViews(List children) { for (JsonStructureViewModel child : children) { addChildView(child); } } private void addChildView(JsonStructureViewModel child) { try { FXMLLoader loader = new FXMLLoader(JsonStructureController.class.getResource("JsonStructureView.fxml")); loader.setController(new JsonStructureController(child)); Parent root = loader.load(); Button removeButton = new Button("-"); HBox hbox = new HBox(removeButton, root); hbox.setId(child.getId()); hbox.setSpacing(15); hbox.setAlignment(Pos.TOP_LEFT); nestedContainer.getChildren().add(hbox); removeButton.setOnAction(event1 -> viewModel.removeChild(child.getId())); } catch (IOException e) { throw new RuntimeException(e); } } private void toggleObjectContainer(Boolean hasChild) { if (hasChild) { if (!mainContainer.getChildren().contains(objectContainer)) { mainContainer.getChildren().add(objectContainer); } } else { viewModel.removeAllChild(); mainContainer.getChildren().remove(objectContainer); } } private void toggleDateFieldContainers(Boolean hasDateType) { if (hasDateType) { if (!fieldContainer.getChildren().contains(formatFieldContainer)) { fieldContainer.getChildren().add(2, formatFieldContainer); } if (!fieldContainer.getChildren().contains(delimitorFieldContainer)) { fieldContainer.getChildren().add(3, delimitorFieldContainer); } } else { fieldContainer.getChildren().remove(formatFieldContainer); fieldContainer.getChildren().remove(delimitorFieldContainer); } } private void toggleSquareBrackets(Boolean hasSquareBracket) { if (hasSquareBracket) { if (!formFieldContainer.getChildren().contains(squareBracketLeft)) { formFieldContainer.getChildren().add(0, squareBracketLeft); } if (!formFieldContainer.getChildren().contains(squareBracketRight)) { formFieldContainer.getChildren().add(squareBracketRight); } } else { formFieldContainer.getChildren().remove(squareBracketLeft); formFieldContainer.getChildren().remove(squareBracketRight); } } private void toggleObjectSquareBrackets(Boolean hasObjectSquareBracket) { if (hasObjectSquareBracket) { if (!objectContainerleft.getChildren().contains(objectSquareBracketLeft)) { objectContainerleft.getChildren().add(0, objectSquareBracketLeft); } if (!objectContainerRight.getChildren().contains(objectSquareBracketRight)) { objectContainerRight.getChildren().add(objectSquareBracketRight); } } else { objectContainerleft.getChildren().remove(objectSquareBracketLeft); objectContainerRight.getChildren().remove(objectSquareBracketRight); } } }