From 85ff3d541f1e1e4d40d7efc6ea444c35a6198627 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Fri, 1 Mar 2019 19:47:24 +0300 Subject: [PATCH] EA-138425 - CCE: FilteringListModel.remove Also ListUtil cleanup, generics and more extension methods --- .../src/com/intellij/ui/ListUtil.java | 238 ++++++++---------- .../ui/speedSearch/FilteringListModel.java | 10 +- .../ui/speedSearch/ListWithFilter.java | 6 +- .../speedSearch/NameFilteringListModel.java | 6 +- 4 files changed, 118 insertions(+), 142 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/ListUtil.java b/platform/platform-api/src/com/intellij/ui/ListUtil.java index 5492a49eb323..ef86a3d6153e 100644 --- a/platform/platform-api/src/com/intellij/ui/ListUtil.java +++ b/platform/platform-api/src/com/intellij/ui/ListUtil.java @@ -15,7 +15,6 @@ */ package com.intellij.ui; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Condition; import com.intellij.ui.speedSearch.FilteringListModel; import com.intellij.util.ui.UIUtil; @@ -28,13 +27,13 @@ import javax.swing.event.ListSelectionListener; import java.awt.*; import java.awt.event.*; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class ListUtil { public static final String SELECTED_BY_MOUSE_EVENT = "byMouseEvent"; - private static final Logger LOG = Logger.getInstance("#com.intellij.ui.ListUtil"); - public static MouseMotionListener installAutoSelectOnMouseMove(final JList list) { + public static MouseMotionListener installAutoSelectOnMouseMove(@NotNull JList list) { final MouseMotionAdapter listener = new MouseMotionAdapter() { boolean myIsEngaged = false; @@ -77,34 +76,50 @@ public class ListUtil { protected abstract void update(); } - public static List removeSelectedItems(JList list) { + @NotNull + public static List removeSelectedItems(@NotNull JList list) { return removeSelectedItems(list, null); } - public static List removeIndices(JList list, int[] indices) { + @NotNull + public static List removeIndices(@NotNull JList list, int[] indices) { return removeIndices(list, indices, null); } - public static List removeSelectedItems(JList list, Condition condition) { - int[] idxs = list.getSelectedIndices(); - return removeIndices(list, idxs, condition); + @NotNull + public static List removeSelectedItems(@NotNull JList list, @Nullable Condition condition) { + int[] indices = list.getSelectedIndices(); + return removeIndices(list, indices, condition); } - private static List removeIndices(JList list, int[] idxs, Condition condition) { - if (idxs.length == 0) { + public static void removeItem(@NotNull ListModel model, int index) { + getExtension(model).remove(model, index); + } + + public static void removeAllItems(@NotNull ListModel model) { + getExtension(model).removeAll(model); + } + + public static void addAllItems(@NotNull ListModel model, @NotNull List items) { + getExtension(model).addAll(model, items); + } + + private static List removeIndices(@NotNull JList list, @NotNull int[] indices, @Nullable Condition condition) { + if (indices.length == 0) { return new ArrayList<>(0); } - ListModel model = list.getModel(); - int firstSelectedIndex = idxs[0]; + ListModel model = list.getModel(); + ListModelExtension> extension = getExtension(model); + int firstSelectedIndex = indices[0]; ArrayList removedItems = new ArrayList<>(); int deletedCount = 0; - for (int idx1 : idxs) { + for (int idx1 : indices) { int index = idx1 - deletedCount; if (index < 0 || index >= model.getSize()) continue; - T obj = (T)get(model, index); + T obj = extension.get(model, index); if (condition == null || condition.value(obj)) { removedItems.add(obj); - remove(model, index); + extension.remove(model, index); deletedCount++; } } @@ -113,31 +128,31 @@ public class ListUtil { } else if (list.getSelectedValue() == null) { // if nothing remains selected, set selected row - if (firstSelectedIndex >= model.getSize()){ + if (firstSelectedIndex >= model.getSize()) { list.setSelectedIndex(model.getSize() - 1); } - else{ + else { list.setSelectedIndex(firstSelectedIndex); } } return removedItems; } - public static boolean canRemoveSelectedItems(JList list){ + public static boolean canRemoveSelectedItems(@NotNull JList list) { return canRemoveSelectedItems(list, null); } - public static boolean canRemoveSelectedItems(JList list, Condition applyable){ - ListModel model = list.getModel(); - int[] idxs = list.getSelectedIndices(); - if (idxs.length == 0) { + public static boolean canRemoveSelectedItems(@NotNull JList list, @Nullable Condition condition) { + int[] indices = list.getSelectedIndices(); + if (indices.length == 0) { return false; } - - for (int index : idxs) { + ListModel model = list.getModel(); + ListModelExtension> extension = getExtension(model); + for (int index : indices) { if (index < 0 || index >= model.getSize()) continue; - Object obj = getExtensions(model).get(model, index); - if (applyable == null || applyable.value(obj)) { + T obj = extension.get(model, index); + if (condition == null || condition.value(obj)) { return true; } } @@ -145,77 +160,51 @@ public class ListUtil { return false; } - public static int moveSelectedItemsUp(JList list) { - DefaultListModel model = getModel(list); + public static int moveSelectedItemsUp(@NotNull JList list) { + ListModel model = list.getModel(); + ListModelExtension> extension = getExtension(model); int[] indices = list.getSelectedIndices(); if (!canMoveSelectedItemsUp(list)) return 0; for (int index : indices) { - Object temp = model.get(index); - model.set(index, model.get(index - 1)); - model.set(index - 1, temp); + T temp = extension.get(model, index); + extension.set(model, index, extension.get(model, index - 1)); + extension.set(model, index - 1, temp); list.removeSelectionInterval(index, index); list.addSelectionInterval(index - 1, index - 1); } Rectangle cellBounds = list.getCellBounds(indices[0] - 1, indices[indices.length - 1] - 1); - if (cellBounds != null){ + if (cellBounds != null) { list.scrollRectToVisible(cellBounds); } return indices.length; } - public static boolean canMoveSelectedItemsUp(JList list) { + public static boolean canMoveSelectedItemsUp(@NotNull JList list) { int[] indices = list.getSelectedIndices(); return indices.length > 0 && indices[0] > 0; } - public static int moveSelectedItemsDown(JList list) { - DefaultListModel model = getModel(list); + public static int moveSelectedItemsDown(@NotNull JList list) { + ListModel model = list.getModel(); + ListModelExtension> extension = getExtension(model); int[] indices = list.getSelectedIndices(); if (!canMoveSelectedItemsDown(list)) return 0; - for(int i = indices.length - 1; i >= 0 ; i--){ + for (int i = indices.length - 1; i >= 0; i--) { int index = indices[i]; - Object temp = model.get(index); - model.set(index, model.get(index + 1)); - model.set(index + 1, temp); + T temp = extension.get(model, index); + extension.set(model, index, extension.get(model, index + 1)); + extension.set(model, index + 1, temp); list.removeSelectionInterval(index, index); list.addSelectionInterval(index + 1, index + 1); } Rectangle cellBounds = list.getCellBounds(indices[0] + 1, indices[indices.length - 1] + 1); - if (cellBounds != null){ + if (cellBounds != null) { list.scrollRectToVisible(cellBounds); } return indices.length; } - private static DefaultListModel getModel(JList list) { - final ListModel model = list.getModel(); - if (model instanceof FilteringListModel) { - return (DefaultListModel)((FilteringListModel)model).getOriginalModel(); - } - if (model instanceof CollectionListModel) { - return getWrapperModel(((CollectionListModel)model)); - } - return (DefaultListModel)model; - } - - private static DefaultListModel getWrapperModel(final CollectionListModel source) { - DefaultListModel model = new DefaultListModel() { - @Override - public Object set(int index, Object element) { - Object o = source.getElementAt(index); - source.setElementAt(element, index); - return o; - } - - @Override - public Object get(int index) { - return source.getElementAt(index); - } - }; - return model; - } - - public static boolean isPointOnSelection(@NotNull JList list, int x, int y) { + public static boolean isPointOnSelection(@NotNull JList list, int x, int y) { int row = list.locationToIndex(new Point(x, y)); if (row < 0) return false; return list.isSelectedIndex(row); @@ -241,13 +230,13 @@ public class ListUtil { return UIUtil.getDeepestComponentAt(rendererComponent, rendererRelativeX, rendererRelativeY); } - public static boolean canMoveSelectedItemsDown(JList list) { + public static boolean canMoveSelectedItemsDown(@NotNull JList list) { ListModel model = list.getModel(); int[] indices = list.getSelectedIndices(); return indices.length > 0 && indices[indices.length - 1] < model.getSize() - 1; } - public static Updatable addMoveUpListener(JButton button, final JList list) { + public static Updatable addMoveUpListener(@NotNull JButton button, @NotNull JList list) { button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -259,7 +248,7 @@ public class ListUtil { } - public static Updatable addMoveDownListener(JButton button, final JList list) { + public static Updatable addMoveDownListener(@NotNull JButton button, @NotNull JList list) { button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -270,17 +259,20 @@ public class ListUtil { return disableWhenNoSelection(button, list); } - public static Updatable addRemoveListener(final JButton button, final JList list) { + public static Updatable addRemoveListener(@NotNull JButton button, @NotNull JList list) { return addRemoveListener(button, list, null); } - public static Updatable addRemoveListener(final JButton button, final JList list, final RemoveNotification notification) { + public static Updatable addRemoveListener(@NotNull JButton button, + @NotNull JList list, + @Nullable RemoveNotification notification) { button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - final List items = removeSelectedItems(list); - if (notification != null) + List items = removeSelectedItems(list); + if (notification != null) { notification.itemsRemoved(items); + } list.requestFocusInWindow(); } }); @@ -305,15 +297,7 @@ public class ListUtil { return listener; } - private static Object get(ListModel model, int index) { - return getExtensions(model).get(model, index); - } - - private static void remove(ListModel model, int index) { - getExtensions(model).remove(model, index); - } - - public static Updatable disableWhenNoSelection(final JButton button, final JList list) { + public static Updatable disableWhenNoSelection(@NotNull JButton button, @NotNull JList list) { class MyListSelectionListener extends Updatable implements ListSelectionListener { MyListSelectionListener(JButton button) { super(button); @@ -339,67 +323,57 @@ public class ListUtil { void itemsRemoved(List items); } - private static ListModelExtension getExtensions(ListModel model) { + /** + * @noinspection unchecked + */ + @NotNull + private static > ListModelExtension getExtension(@NotNull ModelType model) { if (model instanceof DefaultListModel) return DEFAULT_MODEL; if (model instanceof SortedListModel) return SORTED_MODEL; if (model instanceof FilteringListModel) return FILTERED_MODEL; if (model instanceof CollectionListModel) return COLLECTION_MODEL; - - if (model == null) LOG.assertTrue(false); - else LOG.error("Unknown model class: " + model.getClass().getName()); - return null; + throw new AssertionError("Unknown model class: " + model.getClass().getName()); } - private interface ListModelExtension { - Object get(ModelType model, int index); + //@formatter:off + private interface ListModelExtension> { + T get(ModelType model, int index); + void set(ModelType model, int index, T item); void remove(ModelType model, int index); + void removeAll(ModelType model); + void addAll(ModelType model, List item); } - private static final ListModelExtension DEFAULT_MODEL = new ListModelExtension() { - @Override - public Object get(DefaultListModel model, int index) { - return model.get(index); - } - - @Override - public void remove(DefaultListModel model, int index) { - model.remove(index); - } + private static final ListModelExtension DEFAULT_MODEL = new ListModelExtension>() { + @Override public Object get(DefaultListModel model, int index) { return model.get(index);} + @Override public void set(DefaultListModel model, int index, Object item) { model.set(index, item);} + @Override public void remove(DefaultListModel model, int index) { model.remove(index);} + @Override public void removeAll(DefaultListModel model) { model.removeAllElements();} + @Override public void addAll(DefaultListModel model, List item) { model.addElement(item);} }; - private static final ListModelExtension COLLECTION_MODEL = new ListModelExtension() { - @Override - public Object get(CollectionListModel model, int index) { - return model.getElementAt(index); - } - - @Override - public void remove(CollectionListModel model, int index) { - model.remove(index); - } + private static final ListModelExtension COLLECTION_MODEL = new ListModelExtension>() { + @Override public Object get(CollectionListModel model, int index) { return model.getElementAt(index);} + @Override public void set(CollectionListModel model, int index, Object item) { model.setElementAt(item, index);} + @Override public void remove(CollectionListModel model, int index) { model.remove(index);} + @Override public void removeAll(CollectionListModel model) { model.removeAll();} + @Override public void addAll(CollectionListModel model, List items) { model.addAll(model.getSize(), items);} }; - private static final ListModelExtension SORTED_MODEL = new ListModelExtension() { - @Override - public Object get(SortedListModel model, int index) { - return model.get(index); - } - - @Override - public void remove(SortedListModel model, int index) { - model.remove(index); - } + private static final ListModelExtension SORTED_MODEL = new ListModelExtension>() { + @Override public Object get(SortedListModel model, int index) { return model.get(index);} + @Override public void set(SortedListModel model, int index, Object item) { model.remove(index); model.add(item);} + @Override public void remove(SortedListModel model, int index) { model.remove(index);} + @Override public void removeAll(SortedListModel model) { model.clear();} + @Override public void addAll(SortedListModel model, List items) { model.addAll(items);} }; - private static final ListModelExtension FILTERED_MODEL = new ListModelExtension() { - @Override - public Object get(FilteringListModel model, int index) { - return model.getElementAt(index); - } - - @Override - public void remove(FilteringListModel model, int index) { - model.remove(index); - } + private static final ListModelExtension FILTERED_MODEL = new ListModelExtension>() { + @Override public Object get(FilteringListModel model, int index) { return model.getElementAt(index);} + @Override public void set(FilteringListModel model, int index, Object item) { getExtension(model.getOriginalModel()).set(model, index, item);} + @Override public void remove(FilteringListModel model, int index) { model.remove(index);} + @Override public void removeAll(FilteringListModel model) { model.replaceAll(Collections.emptyList());} + @Override public void addAll(FilteringListModel model, List items) { model.addAll(items);} }; + //@formatter:on } diff --git a/platform/platform-api/src/com/intellij/ui/speedSearch/FilteringListModel.java b/platform/platform-api/src/com/intellij/ui/speedSearch/FilteringListModel.java index 61039abb7061..d80e3d24ba01 100644 --- a/platform/platform-api/src/com/intellij/ui/speedSearch/FilteringListModel.java +++ b/platform/platform-api/src/com/intellij/ui/speedSearch/FilteringListModel.java @@ -21,6 +21,8 @@ package com.intellij.ui.speedSearch; import com.intellij.openapi.util.Condition; import com.intellij.ui.CollectionListModel; +import com.intellij.ui.ListUtil; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.event.ListDataEvent; @@ -123,13 +125,13 @@ public class FilteringListModel extends AbstractListModel { return myData.contains(value); } - public ListModel getOriginalModel() { + @NotNull + public ListModel getOriginalModel() { return myOriginalModel; } public void addAll(List elements) { - myData.addAll(elements); - ((CollectionListModel)myOriginalModel).add(elements); + ListUtil.addAllItems(myOriginalModel, elements); } public void replaceAll(List elements) { @@ -139,6 +141,6 @@ public class FilteringListModel extends AbstractListModel { } public void remove(int index) { - ((CollectionListModel)myOriginalModel).remove(myData.get(index)); + ListUtil.removeItem(myOriginalModel, index); } } diff --git a/platform/platform-api/src/com/intellij/ui/speedSearch/ListWithFilter.java b/platform/platform-api/src/com/intellij/ui/speedSearch/ListWithFilter.java index 9a108a1ca697..21b73232bc7b 100644 --- a/platform/platform-api/src/com/intellij/ui/speedSearch/ListWithFilter.java +++ b/platform/platform-api/src/com/intellij/ui/speedSearch/ListWithFilter.java @@ -26,7 +26,7 @@ import java.awt.*; import java.awt.event.FocusEvent; public class ListWithFilter extends JPanel implements DataProvider { - private final JList myList; + private final JList myList; private final SearchTextField mySearchField = new SearchTextField(false); private final NameFilteringListModel myModel; private final JScrollPane myScrollPane; @@ -52,7 +52,7 @@ public class ListWithFilter extends JPanel implements DataProvider { return new ListWithFilter<>(list, scrollPane, namer, highlightAllOccurrences); } - private ListWithFilter(@NotNull JList list, + private ListWithFilter(@NotNull JList list, @NotNull JScrollPane scrollPane, @Nullable Function namer, boolean highlightAllOccurrences) { @@ -77,7 +77,7 @@ public class ListWithFilter extends JPanel implements DataProvider { myList.addKeyListener(mySpeedSearch); int selectedIndex = myList.getSelectedIndex(); int modelSize = myList.getModel().getSize(); - myModel = new NameFilteringListModel(myList, namer, mySpeedSearch::shouldBeShowing, mySpeedSearch); + myModel = new NameFilteringListModel<>(myList, namer, mySpeedSearch::shouldBeShowing, mySpeedSearch); if (myModel.getSize() == modelSize) { myList.setSelectedIndex(selectedIndex); } diff --git a/platform/platform-api/src/com/intellij/ui/speedSearch/NameFilteringListModel.java b/platform/platform-api/src/com/intellij/ui/speedSearch/NameFilteringListModel.java index 76bb79cd4240..6959fd4caff1 100644 --- a/platform/platform-api/src/com/intellij/ui/speedSearch/NameFilteringListModel.java +++ b/platform/platform-api/src/com/intellij/ui/speedSearch/NameFilteringListModel.java @@ -45,15 +45,15 @@ public class NameFilteringListModel extends FilteringListModel { this(list, namer, filter, () -> speedSearch.getFilter()); } - public NameFilteringListModel(JList list, final Function namer, final Condition filter, final SpeedSearchSupply speedSearch) { + public NameFilteringListModel(JList list, final Function namer, final Condition filter, final SpeedSearchSupply speedSearch) { this(list, namer, filter, () -> { final String prefix = speedSearch.getEnteredPrefix(); return prefix == null ? "" : prefix; }); } - public NameFilteringListModel(JList list, final Function namer, final Condition filter, Computable pattern) { - super(list); + public NameFilteringListModel(JList list, final Function namer, final Condition filter, Computable pattern) { + super(list.getModel()); myPattern = pattern; myNamer = namer; setFilter(namer != null ? (Condition)t -> filter.value(namer.fun(t)) : null);