/* * Copyright [2014] [Christian Loehnert, krampenschiesser@gmail.com] * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.ks.idnadrev.tag; import de.ks.BaseController; import de.ks.activity.ActivityLoadFinishedEvent; import de.ks.application.fxml.DefaultLoader; import de.ks.idnadrev.entity.Tag; import de.ks.idnadrev.entity.Tagged; import de.ks.persistence.PersistentWork; import de.ks.selection.NamedPersistentObjectSelection; import javafx.collections.FXCollections; import javafx.collections.ObservableSet; import javafx.collections.SetChangeListener; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.scene.Node; import javafx.scene.control.TextField; import javafx.scene.layout.FlowPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.StackPane; import java.net.URL; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; public class TagContainer extends BaseController<Tagged> { @FXML protected NamedPersistentObjectSelection<Tag> tagAddController; @FXML protected StackPane tagSelectionContainer; @FXML protected FlowPane tagPane; protected final ObservableSet<String> currentTags = FXCollections.observableSet(new TreeSet<String>()); protected boolean readOnly = false; @Override public void initialize(URL location, ResourceBundle resources) { tagAddController.from(Tag.class); tagAddController.setHideOnSingleClick(true); tagAddController.setOnAction(e -> { TextField input = tagAddController.getInput(); addTag(input.getText()); input.clear(); }); currentTags.addListener(this::onTagsChanged); } private void onTagsChanged(SetChangeListener.Change<? extends String> change) { String addedTag = change.getElementAdded(); if (addedTag != null) { CompletableFuture.supplyAsync(() -> { DefaultLoader<GridPane, TagInfo> loader = new DefaultLoader<>(TagInfo.class); loader.load(); return loader; }, controller.getExecutorService()).thenAcceptAsync((loader) -> { // currentTags.add(addedTag); TagInfo ctrl = loader.getController(); ctrl.getName().setText(addedTag); GridPane view = loader.getView(); view.setId(addedTag); ctrl.getRemove().setOnAction((e) -> { currentTags.remove(addedTag); tagPane.getChildren().remove(view); }); tagPane.getChildren().add(view); }, controller.getJavaFXExecutor()); } String removedTag = change.getElementRemoved(); if (removedTag != null) { Optional<Node> first = tagPane.getChildren().stream().filter(n -> removedTag.equals(n.getId())).findFirst(); if (first.isPresent()) { tagPane.getChildren().remove(first.get()); } } } public void addTag(String tag) { currentTags.add(tag); } public void removeTag(String tag) { currentTags.remove(tag); } @Override public void duringSave(Tagged model) { if (!readOnly) { tagPane.getChildren().stream().filter(c -> c.getId() != null).map(c -> new Tag(c.getId())).forEach(tag -> { Tag readTag = PersistentWork.forName(Tag.class, tag.getName()); readTag = readTag == null ? tag : readTag; model.addTag(readTag); }); } } @Override public void duringLoad(Tagged model) { super.duringLoad(model); if (!readOnly) { model.getTags().forEach(t -> t.getName()); } } @Override protected void onRefresh(Tagged model) { super.onRefresh(model); if (!readOnly) { currentTags.clear(); List<String> tags = model.getTags().stream().map(t -> t.getName()).collect(Collectors.toList()); Collections.sort(tags); currentTags.addAll(tags); } } @Override protected Tagged extractFromEvent(ActivityLoadFinishedEvent e) { if (readOnly) { return null; } else { return super.extractFromEvent(e); } } public TextField getInput() { return tagAddController.getInput(); } public EventHandler<ActionEvent> getOnAction() { return tagAddController.getOnAction(); } public boolean isReadOnly() { return readOnly; } public void setReadOnly(boolean readOnly) { this.readOnly = readOnly; } public ObservableSet<String> getCurrentTags() { return currentTags; } }