Skip to content

Package: TreeItemDelegateSupport

TreeItemDelegateSupport

nameinstructionbranchcomplexitylinemethod
TreeItemDelegateSupport(Executor)
M: 0 C: 16
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
bindSelectionListener(ReadOnlyObjectProperty)
M: 0 C: 11
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
createTreeItem(PresentationModel, int)
M: 0 C: 24
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
createTreeItems(ObservableList, int)
M: 0 C: 11
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
lambda$createTreeItem$3(TreeItem, int)
M: 13 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
lambda$createTreeItem$4(TreeItem, int, PropertyChangeEvent)
M: 6 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$createTreeItem$5(TreeItem, int, ObservableValue, Boolean, Boolean)
M: 0 C: 10
100%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 0 C: 3
100%
M: 0 C: 1
100%
lambda$createTreeItems$2(int, PresentationModel)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$setChildren$0(TreeItem, int)
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$setChildren$1(TreeItem, int, ObservableList)
M: 0 C: 9
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
setChildren(TreeItem, int)
M: 0 C: 11
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
setRootProperty(PresentationModel, ObjectProperty)
M: 0 C: 15
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
shouldShowRoot(PresentationModel)
M: 0 C: 10
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
static {...}
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%

Coverage

1: /*
2: * *************************************************************************************************************************************************************
3: *
4: * SteelBlue: DCI User Interfaces
5: * http://tidalwave.it/projects/steelblue
6: *
7: * Copyright (C) 2015 - 2025 by Tidalwave s.a.s. (http://tidalwave.it)
8: *
9: * *************************************************************************************************************************************************************
10: *
11: * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
12: * You may obtain a copy of the License at
13: *
14: * http://www.apache.org/licenses/LICENSE-2.0
15: *
16: * 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
17: * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
18: *
19: * *************************************************************************************************************************************************************
20: *
21: * git clone https://bitbucket.org/tidalwave/steelblue-src
22: * git clone https://github.com/tidalwave-it/steelblue-src
23: *
24: * *************************************************************************************************************************************************************
25: */
26: package it.tidalwave.ui.javafx.impl.common;
27:
28: import jakarta.annotation.Nonnull;
29: import java.beans.PropertyChangeListener;
30: import java.util.List;
31: import java.util.concurrent.Executor;
32: import javafx.beans.property.ObjectProperty;
33: import javafx.beans.property.ReadOnlyObjectProperty;
34: import javafx.collections.ObservableList;
35: import javafx.scene.control.TreeItem;
36: import javafx.application.Platform;
37: import it.tidalwave.ui.core.role.PresentationModel;
38: import it.tidalwave.ui.core.role.Visibility;
39: import it.tidalwave.ui.javafx.impl.tree.ObsoletePresentationModelDisposer;
40: import lombok.Getter;
41: import lombok.extern.slf4j.Slf4j;
42: import static java.util.stream.Collectors.*;
43: import static it.tidalwave.ui.core.role.Visibility._Visibility_;
44: import static it.tidalwave.ui.javafx.impl.DefaultJavaFXBinder.enforceFxApplicationThread;
45: import static it.tidalwave.ui.javafx.impl.common.JavaFXWorker.childrenPm;
46:
47: /***************************************************************************************************************************************************************
48: *
49: * Some common stuff for both {@code TreeView} and {@code TreeTableView}.
50: *
51: * @author Fabrizio Giudici
52: *
53: **************************************************************************************************************************************************************/
54: @Slf4j
55: public class TreeItemDelegateSupport extends DelegateSupport
56: {
57: @Getter // for testing
58: private final ChangeListenerSelectableAdapter selectionListener = new ChangeListenerSelectableAdapter(executor);
59:
60: private final ObsoletePresentationModelDisposer presentationModelDisposer = new ObsoletePresentationModelDisposer();
61:
62: /***********************************************************************************************************************************************************
63: *
64: **********************************************************************************************************************************************************/
65: public TreeItemDelegateSupport (@Nonnull final Executor executor)
66: {
67: super(executor);
68: }
69:
70: /***********************************************************************************************************************************************************
71: * Sets the children for a {@link TreeItem}.
72: * @param parentItem the {@code TreeItem}
73: * @param depth the depth level (used only for logging)
74: **********************************************************************************************************************************************************/
75: protected void setChildren (@Nonnull final TreeItem<PresentationModel> parentItem, final int depth)
76: {
77: JavaFXWorker.run(executor,
78: () -> childrenPm(parentItem.getValue(), depth),
79: items -> parentItem.getChildren().setAll(createTreeItems(items, depth)));
80: }
81:
82: /***********************************************************************************************************************************************************
83: * {@return a list of {@link TreeItem}s populated with the given items}.
84: * @param depth the depth level (used only for logging)
85: **********************************************************************************************************************************************************/
86: @Nonnull
87: private List<TreeItem<PresentationModel>> createTreeItems (@Nonnull final ObservableList<PresentationModel> items, final int depth)
88: {
89: enforceFxApplicationThread();
90: return items.stream().map(childPm -> createTreeItem(childPm, depth)).collect(toList());
91: }
92:
93: /***********************************************************************************************************************************************************
94: * Creates a single {@link TreeItem} for the given the {@link PresentationModel}. When the {@code PresentationModel} fires the
95: * {@link PresentationModel#PROPERTY_CHILDREN} property change event, children are recreated.
96: * @param pm the {@code PresentationModel}
97: * @param depth the depth level (used only for logging)
98: * @return the
99: **********************************************************************************************************************************************************/
100: @Nonnull
101: protected TreeItem<PresentationModel> createTreeItem (@Nonnull final PresentationModel pm, final int depth)
102: {
103: enforceFxApplicationThread();
104: final TreeItem<PresentationModel> item = new PresentationModelTreeItem(pm);
105:
106: final PropertyChangeListener recreateChildrenOnUpdateListener = ignored -> Platform.runLater(() ->
107: {
108: log.debug("On recreateChildrenOnUpdateListener");
109: setChildren(item, depth + 1);
110: item.setExpanded(true);
111: });
112:
113: pm.addPropertyChangeListener(PresentationModel.PROPERTY_CHILDREN, recreateChildrenOnUpdateListener);
114:
115: item.expandedProperty().addListener((observable, oldValue, newValue) ->
116: {
117:• if (newValue)
118: {
119: setChildren(item, depth + 1);
120: }
121: });
122:
123: return item;
124: }
125:
126: /***********************************************************************************************************************************************************
127: *
128: **********************************************************************************************************************************************************/
129: protected void setRootProperty (@Nonnull final PresentationModel pm, @Nonnull final ObjectProperty<TreeItem<PresentationModel>> rootProperty)
130: {
131: rootProperty.removeListener(presentationModelDisposer);
132: rootProperty.addListener(presentationModelDisposer);
133: rootProperty.set(createTreeItem(pm, 0));
134: }
135:
136: /***********************************************************************************************************************************************************
137: *
138: **********************************************************************************************************************************************************/
139: protected void bindSelectionListener (@Nonnull final ReadOnlyObjectProperty<TreeItem<PresentationModel>> selectedItemProperty)
140: {
141: selectedItemProperty.removeListener(selectionListener.asTreeItemChangeListener());
142: selectedItemProperty.addListener(selectionListener.asTreeItemChangeListener());
143: }
144:
145: /***********************************************************************************************************************************************************
146: *
147: **********************************************************************************************************************************************************/
148: protected static Boolean shouldShowRoot (@Nonnull final PresentationModel pm)
149: {
150: return pm.maybeAs(_Visibility_).map(Visibility::isVisible).orElse(true);
151: }
152: }