From ef2f3b3aa4921892d925dd4d4d54cce508630161 Mon Sep 17 00:00:00 2001 From: Simon Barner <barner@fortiss.org> Date: Thu, 28 Sep 2023 09:26:19 +0200 Subject: [PATCH] Move TreeContextMenuItem to DynamicTreeUIProviderBase * Context menus are generally applicable, not only for ModelElementTreeViewers Issue-Ref: 4322 Issue-URL: https://git.fortiss.org/af3/af3/-/issues/4322 Signed-off-by: Simon Barner <barner@fortiss.org> --- .../ui/javafx/control/treetableview/.ratings | 2 +- .../treetableview/ModelElementTreeViewer.java | 85 --------------- .../ui/javafx/control/treetableview/.ratings | 2 +- .../DynamicTreeUIProviderBase.java | 100 +++++++++++++++++- 4 files changed, 97 insertions(+), 92 deletions(-) diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/javafx/control/treetableview/.ratings b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/javafx/control/treetableview/.ratings index 316c66d44..f6028344d 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/javafx/control/treetableview/.ratings +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/javafx/control/treetableview/.ratings @@ -1,2 +1,2 @@ DynamicTreeTableNameProvider.java 3ca45f24b94e97b02313e80b16ba8b370f541541 GREEN -ModelElementTreeViewer.java af87b0aa1780f3b02a60d09db9676b4e54903be5 YELLOW +ModelElementTreeViewer.java 83a3693cf820161e42e7d84a697a3cd0d55f8c1f YELLOW diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/javafx/control/treetableview/ModelElementTreeViewer.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/javafx/control/treetableview/ModelElementTreeViewer.java index af87b0aa1..83a3693cf 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/javafx/control/treetableview/ModelElementTreeViewer.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/javafx/control/treetableview/ModelElementTreeViewer.java @@ -18,10 +18,6 @@ package org.fortiss.tooling.base.ui.javafx.control.treetableview; import static javafx.embed.swt.SWTFXUtils.toFXImage; import static org.fortiss.tooling.kernel.ui.util.KernelUIUtils.getName; -import java.lang.reflect.Constructor; -import java.util.ArrayList; -import java.util.List; - import org.fortiss.tooling.base.model.element.IHierarchicElement; import org.fortiss.tooling.base.model.element.IModelElement; import org.fortiss.tooling.common.ui.javafx.AF3FXViewPart; @@ -32,11 +28,7 @@ import org.fortiss.tooling.common.ui.javafx.control.treetableview.DynamicTreeVie import org.fortiss.tooling.kernel.model.INamedElement; import org.fortiss.tooling.kernel.ui.service.IModelElementHandlerService; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; import javafx.scene.Node; -import javafx.scene.control.ContextMenu; -import javafx.scene.control.MenuItem; import javafx.scene.control.TreeView; import javafx.scene.image.Image; import javafx.scene.image.ImageView; @@ -77,80 +69,11 @@ public class ModelElementTreeViewer<T extends INamedElement> { } return null; } - - /** {@inheritDoc} */ - @Override - public final ContextMenu createContextMenu(T element) { - ContextMenu menu = new ContextMenu(); - for(Class<? extends TreeContextMenuItem> entryType : contextMenuEntryTypes) { - - try { - Constructor<? extends TreeContextMenuItem> ctr = - entryType.getConstructor(INamedElement.class); - TreeContextMenuItem entry = ctr.newInstance(element); - if(!entry.isHidden()) { - menu.getItems().add(entry); - entry.setDisable(entry.isDisabled()); - } - } catch(Exception e) { - e.printStackTrace(); - } - } - return menu; - } - } - - /** Base class for {@link MenuItem}s used by {@link ModelElementTreeViewer}s. */ - protected static abstract class TreeContextMenuItem extends MenuItem { - - /** The model element on which the context menu operates. */ - private INamedElement element; - - /** Constructor. */ - public TreeContextMenuItem(INamedElement element, String label) { - super(label); - init(element); - } - - /** Constructor. */ - public TreeContextMenuItem(INamedElement element, String label, Node graphic) { - super(label, graphic); - init(element); - } - - /** Helper for constructors. */ - private void init(INamedElement element) { - this.element = element; - setOnAction(createOnActionHandler()); - } - - /** Getter for {@link #element}. */ - protected INamedElement getElement() { - return element; - } - - /** Predicate iff this {@link TreeContextMenuItem} is hidden. */ - public abstract boolean isHidden(); - - /** Predicate when this {@link TreeContextMenuItem} is disabled. */ - public abstract boolean isDisabled(); - - /** - * Factory method for {@link EventHandler} that implements the action triggered by the - * context menu. - */ - protected abstract EventHandler<ActionEvent> createOnActionHandler(); } /** References the constructed {@link DynamicTreeViewer} "controller". */ protected DynamicTreeViewer<T> dynTreeViewer; - /** - * List of context menu entries types that supplied by clients - * (see{@link #addContextMenuEntry(Class)}). - */ - protected List<Class<? extends TreeContextMenuItem>> contextMenuEntryTypes = new ArrayList<>(); - /** Constructor. */ public ModelElementTreeViewer(TreeView<T> treeView, T modelRoot, DynamicTreeContentProviderBase<T> contentProvider) { @@ -170,14 +93,6 @@ public class ModelElementTreeViewer<T extends INamedElement> { return new ModelElementUIProvider(); } - /** - * Method to define context {@link TreeContextMenuItem}s. Depending on the selected content, the - * editor will show and enable the context menu. - */ - public void addContextMenuEntry(Class<? extends TreeContextMenuItem> menuItemType) { - contextMenuEntryTypes.add(menuItemType); - } - /** Update the internal viewer. */ public void update() { dynTreeViewer.update(); diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings index 0994db332..3aa6ebc49 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings @@ -7,7 +7,7 @@ DynamicTreeItem.java 7e81ea98038b5eca90df583e0268d4e8f37aaf25 GREEN DynamicTreeItemBase.java d883066ecc181120302ca32f328538de7a45b093 GREEN DynamicTreeTableUIProviderBase.java c52a1f9598de25874f83c133a8cbbcddc86442e9 GREEN DynamicTreeTableViewer.java 77e9995a3bee37d57578dad9434a53c702128efa YELLOW -DynamicTreeUIProviderBase.java 82d3c051213f0147f4c67ad247a08696cee73110 GREEN +DynamicTreeUIProviderBase.java 3688498020e322174d222d433220ee56c4549fbb YELLOW DynamicTreeViewer.java b0d8cc4b3e11aa970446af12d1e54c750713b297 YELLOW DynamicTreeViewerBase.java a2013538b62d86f6a09efdf2cd78babac2072484 GREEN EmptyChildrenContentProvider.java 51b4468f9df8423abeea5ac6aa2f6cf99c2eb512 GREEN diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeUIProviderBase.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeUIProviderBase.java index 82d3c0512..368849802 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeUIProviderBase.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeUIProviderBase.java @@ -13,8 +13,15 @@ *******************************************************************************/ package org.fortiss.tooling.common.ui.javafx.control.treetableview; +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.List; + +import javafx.event.ActionEvent; +import javafx.event.EventHandler; import javafx.scene.Node; import javafx.scene.control.ContextMenu; +import javafx.scene.control.MenuItem; import javafx.scene.control.TreeItem; import javafx.scene.input.ClipboardContent; import javafx.scene.input.Dragboard; @@ -55,12 +62,95 @@ public abstract class DynamicTreeUIProviderBase<T> { } /** - * @param element - * the displayed element - * @return the context menu + * Base class for {@link MenuItem}s used by {@link DynamicTreeViewer}s. Subclasses must provide + * exactly one public constructor that takes the underlying tree element as single argument. */ - public ContextMenu createContextMenu(T element) { - return null; + public static abstract class TreeContextMenuItem<T> extends MenuItem { + + /** The model element on which the context menu operates. */ + private T element; + + /** Constructor. */ + public TreeContextMenuItem(T element, String label) { + super(label); + init(element); + } + + /** Constructor. */ + public TreeContextMenuItem(T element, String label, Node graphic) { + super(label, graphic); + init(element); + } + + /** Helper for constructors. */ + private void init(T element) { + this.element = element; + setOnAction(createOnActionHandler()); + } + + /** Getter for {@link #element}. */ + protected T getElement() { + return element; + } + + /** Predicate iff this {@link TreeContextMenuItem} is hidden. */ + public abstract boolean isHidden(); + + /** Predicate when this {@link TreeContextMenuItem} is disabled. */ + public abstract boolean isDisabled(); + + /** + * Factory method for {@link EventHandler} that implements the action triggered by the + * context menu. + */ + protected abstract EventHandler<ActionEvent> createOnActionHandler(); + } + + /** + * List of context menu entries types that supplied by clients + * (see{@link #addContextMenuEntry(Class)}). + */ + private List<Class<? extends TreeContextMenuItem<T>>> contextMenuEntryTypes = new ArrayList<>(); + + /** + * Method to define context {@link TreeContextMenuItem}s. Depending on the selected content, the + * editor will show and enable the context menu. + */ + protected void addContextMenuEntry(Class<? extends TreeContextMenuItem<T>> menuItemType) { + contextMenuEntryTypes.add(menuItemType); + } + + /** + * Creates a context menu based on the the {@link TreeContextMenuItem} types registered via + * {@link #addContextMenuEntry(Class)}. + */ + public final ContextMenu createContextMenu(T element) { + ContextMenu menu = new ContextMenu(); + for(Class<? extends TreeContextMenuItem<T>> entryType : contextMenuEntryTypes) { + + try { + Constructor<?>[] ctrs = entryType.getConstructors(); + if(ctrs.length != 1) { + throw new RuntimeException( + "Subclasses of TreeContextMenuItem must provide exactly one public constructor"); + } + @SuppressWarnings("unchecked") Constructor<? extends TreeContextMenuItem<T>> ctr = + (Constructor<? extends TreeContextMenuItem<T>>)ctrs[0]; + if(ctr.getParameterCount() != 1) { + throw new RuntimeException( + "The constructor of subclasses of TreeContextMenuItem must take the tree element for which the context menu is created as single argument."); + } + + TreeContextMenuItem<T> entry = ctr.newInstance(element); + if(!entry.isHidden()) { + menu.getItems().add(entry); + entry.setDisable(entry.isDisabled()); + } + } catch(Exception e) { + e.printStackTrace(); + } + } + return menu; } /** -- GitLab