package bluej.utility.javafx;

import java.util.ArrayList;
import java.util.List;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Region;

import threadchecker.OnThread;
import threadchecker.Tag;


| Created by neil on 11/06/2016. | @OnThread(Tag.FXPlatform) public class GrowableList<T extends Node>{ private final FXPlatformSupplier<T> newNodeFactory; private final List<T> items = new ArrayList<T>(); private final ObservableList<Node> inclButtons = FXCollections.observableArrayList(); public GrowableList(FXPlatformSupplier<T> newNodeFactory) { this.newNodeFactory = newNodeFactory; inclButtons.setAll(makePlusButton()); addNewItem(0); } private Node makeCrossButton() { Button button = JavaFXUtil.withStyleClass(new Button(), "growable-remove"); button.setGraphic(JavaFXUtil.withStyleClass(new Region(), "growable-remove-graphic")); button.setOnAction(e -> { int index = inclButtons.indexOf(button); removeItem((index - 2) / 3); }); button.addEventFilter(MouseEvent.MOUSE_ENTERED, e -> { setRemoveHighlight(button, true /*Always turn on ; }); button.addEventFilter(MouseEvent.MOUSE_EXITED, e -> { setRemoveHighlight(button, button.isFocused() | Keep only if focused | ; }); JavaFXUtil.addFocusListener(button, focus -> setRemoveHighlight(button, focus)); HangingFlowPane.setBreakBefore(button, false); return button; } private void setRemoveHighlight(Button button, boolean on) { int index = inclButtons.indexOf(button); if (index != -1) JavaFXUtil.setPseudoclass("bj-growable-remove-highlight", on, inclButtons.get(index - 1)); } private void removeItem(int index) { items.remove(index); inclButtons.remove(index * 3 + 3); inclButtons.remove(index * 3 + 2); inclButtons.remove(index * 3 + 1); } private Node makePlusButton() { Button button = JavaFXUtil.withStyleClass(new Button(), "growable-add"); button.setGraphic(JavaFXUtil.withStyleClass(new Region(), "growable-add-graphic")); button.setOnAction(e -> { int index = inclButtons.indexOf(button); addNewItem(index / 3); }); HangingFlowPane.setBreakBefore(button, true); HangingFlowPane.setMargin(button, new Insets(0, 0, 0, 8)); return button; } private void addNewItem(int itemIndex) { T newItem = newNodeFactory.get(); HangingFlowPane.setBreakBefore(newItem, false); items.add(itemIndex, newItem); inclButtons.add(itemIndex * 3 + 1, newItem); inclButtons.add(itemIndex * 3 + 2, makeCrossButton()); inclButtons.add(itemIndex * 3 + 3, makePlusButton()); } public T getItem(int index) { return items.get(index); } public ObservableList getNodes() { return inclButtons; } public int size() { return items.size(); } }

.   GrowableList
.   makeCrossButton
.   setRemoveHighlight
.   removeItem
.   makePlusButton
.   addNewItem
.   getItem
.   getNodes
.   size




129 neLoCode + 3 LoComm