From 56df3191ee03cacdd8b188a1461c05f23f4bd218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Thu, 4 Apr 2024 18:08:02 +0200 Subject: [PATCH] Add object factories to ISelection interface Currently creating a IStructuredSelection requires to reference a concrete implementing class, also handling null is explicitly required and only List or Array are supported. This adds some new object factory methods similar to what users are used to with the Optional.of(...) / List.of(...) and similar and adds some usages of the new methods. --- .../jface/preference/PreferenceDialog.java | 5 +- .../eclipse/jface/viewers/ColumnViewer.java | 4 +- .../viewers/ComboBoxViewerCellEditor.java | 6 +- .../jface/viewers/IStructuredSelection.java | 72 ++++++++++++++++++- .../jface/viewers/StructuredSelection.java | 12 +++- .../jface/viewers/StructuredViewer.java | 2 +- 6 files changed, 87 insertions(+), 14 deletions(-) diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/preference/PreferenceDialog.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/preference/PreferenceDialog.java index ec746812c48..eea3d2c95f6 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/preference/PreferenceDialog.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/preference/PreferenceDialog.java @@ -47,7 +47,6 @@ import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.jface.viewers.ViewerFilter; @@ -953,7 +952,7 @@ void selectCurrentPageAgain() { if (lastSuccessfulNode == null) { return; } - getTreeViewer().setSelection(new StructuredSelection(lastSuccessfulNode)); + getTreeViewer().setSelection(IStructuredSelection.of(lastSuccessfulNode)); currentPage.setVisible(true); } @@ -987,7 +986,7 @@ protected void selectSavedItem() { } } if (node != null) { - getTreeViewer().setSelection(new StructuredSelection(node), true); + getTreeViewer().setSelection(IStructuredSelection.of(node), true); // Keep focus in tree. See bugs 2692, 2621, and 6775. getTreeViewer().getControl().setFocus(); } diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewer.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewer.java index 17344c49efd..9df2eec985c 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewer.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewer.java @@ -410,7 +410,7 @@ public void editElement(Object element, int column) { getControl().setRedraw(false); // Set the selection at first because in Tree's // the element might not be materialized - setSelection(new StructuredSelection(element), true); + setSelection(IStructuredSelection.of(element), true); Widget item = findItem(element); if (item != null) { @@ -1082,7 +1082,7 @@ ISelection getUpdatedSelection(ISelection selection) { } } if (found) { - return new StructuredSelection(list); + return IStructuredSelection.of(list); } } // by default return given selection. diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ComboBoxViewerCellEditor.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ComboBoxViewerCellEditor.java index 8d9c527a53b..db59d0f9262 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ComboBoxViewerCellEditor.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ComboBoxViewerCellEditor.java @@ -173,11 +173,7 @@ public LayoutData getLayoutData() { protected void doSetValue(Object value) { Assert.isTrue(viewer != null); selectedValue = value; - if (value == null) { - viewer.setSelection(StructuredSelection.EMPTY); - } else { - viewer.setSelection(new StructuredSelection(value)); - } + viewer.setSelection(IStructuredSelection.ofNullable(value)); } /** diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/IStructuredSelection.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/IStructuredSelection.java index 29f20e651dc..cc75ce4091e 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/IStructuredSelection.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/IStructuredSelection.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2023 IBM Corporation and others. + * Copyright (c) 2000, 2024 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -11,9 +11,11 @@ * Contributors: * IBM Corporation - initial API and implementation * Christoph Läubrich - add support for stream() method + * - add support for factory methods *******************************************************************************/ package org.eclipse.jface.viewers; +import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.stream.Stream; @@ -71,4 +73,72 @@ public interface IStructuredSelection extends ISelection, Iterable { default Stream stream() { return StreamSupport.stream(spliterator(), false); } + + /** + * Creates a new {@link IStructuredSelection} wrapping the possibly + * null object. + * + * @param obj the element (might be null) to create a + * {@link IStructuredSelection} from. + * @return a {@link IStructuredSelection} with this single element, or an empty + * selection if the object is null + */ + static IStructuredSelection ofNullable(E obj) { + if (obj == null) { + return StructuredSelection.EMPTY; + } + return new StructuredSelection(obj); + + } + + /** + * Creates a new {@link IStructuredSelection} wrapping the given object. + * + * @param obj the element (must not be null) to create a single + * element {@link IStructuredSelection} from it. + * @return a {@link IStructuredSelection} with this single element + */ + static IStructuredSelection of(E obj) { + return new StructuredSelection(obj); + } + + /** + * Created a new {@link IStructuredSelection} containing the given object + * + * @param objects the object to contain in the selection + * @return a {@link IStructuredSelection} containing the given elements + */ + @SafeVarargs + static IStructuredSelection of(E... objects) { + if (objects.length == 0) { + return StructuredSelection.EMPTY; + } + return new StructuredSelection(objects); + } + + /** + * create a new {@link IStructuredSelection} using the given collection + * + * @param collection + * @return a {@link IStructuredSelection} containing the elements of the + * collection + */ + static IStructuredSelection of(Collection collection) { + if (collection.isEmpty()) { + return StructuredSelection.EMPTY; + } + if (collection instanceof List list) { + return new StructuredSelection(list); + } + return new StructuredSelection(collection.toArray(), false); + } + + /** + * Returns an empty {@link IStructuredSelection} + * + * @return a {@link IStructuredSelection} that is empty. + */ + static IStructuredSelection empty() { + return StructuredSelection.EMPTY; + } } diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredSelection.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredSelection.java index 86db52c2bca..4e52ed851ee 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredSelection.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredSelection.java @@ -68,9 +68,17 @@ public StructuredSelection() { * @param elements an array of elements */ public StructuredSelection(Object[] elements) { + this(elements, true); + } + + StructuredSelection(Object[] elements, boolean copy) { Assert.isNotNull(elements); - this.elements = new Object[elements.length]; - System.arraycopy(elements, 0, this.elements, 0, elements.length); + if (copy) { + this.elements = new Object[elements.length]; + System.arraycopy(elements, 0, this.elements, 0, elements.length); + } else { + this.elements = elements; + } this.comparer = null; } diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredViewer.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredViewer.java index 64fcfc60110..b641207583d 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredViewer.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredViewer.java @@ -1083,7 +1083,7 @@ protected void handleDoubleSelect(SelectionEvent event) { // For details, see bug 90161 [Navigator] DefaultSelecting folders shouldn't always expand first one ISelection selection; if (event.item != null && event.item.getData() != null) { - selection = new StructuredSelection(event.item.getData()); + selection = IStructuredSelection.of(event.item.getData()); } else { selection = getSelection();