mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
EA-138425 - CCE: FilteringListModel.remove
Also ListUtil cleanup, generics and more extension methods
This commit is contained in:
@@ -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 <T> MouseMotionListener installAutoSelectOnMouseMove(@NotNull JList<T> 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 <T> List<T> removeSelectedItems(@NotNull JList<T> list) {
|
||||
return removeSelectedItems(list, null);
|
||||
}
|
||||
|
||||
public static <T> List<T> removeIndices(JList<T> list, int[] indices) {
|
||||
@NotNull
|
||||
public static <T> List<T> removeIndices(@NotNull JList<T> list, int[] indices) {
|
||||
return removeIndices(list, indices, null);
|
||||
}
|
||||
|
||||
public static <T> List<T> removeSelectedItems(JList list, Condition<? super T> condition) {
|
||||
int[] idxs = list.getSelectedIndices();
|
||||
return removeIndices(list, idxs, condition);
|
||||
@NotNull
|
||||
public static <T> List<T> removeSelectedItems(@NotNull JList<T> list, @Nullable Condition<? super T> condition) {
|
||||
int[] indices = list.getSelectedIndices();
|
||||
return removeIndices(list, indices, condition);
|
||||
}
|
||||
|
||||
private static <T> List<T> removeIndices(JList list, int[] idxs, Condition<? super T> condition) {
|
||||
if (idxs.length == 0) {
|
||||
public static <T> void removeItem(@NotNull ListModel<T> model, int index) {
|
||||
getExtension(model).remove(model, index);
|
||||
}
|
||||
|
||||
public static <T> void removeAllItems(@NotNull ListModel<T> model) {
|
||||
getExtension(model).removeAll(model);
|
||||
}
|
||||
|
||||
public static <T> void addAllItems(@NotNull ListModel<T> model, @NotNull List<T> items) {
|
||||
getExtension(model).addAll(model, items);
|
||||
}
|
||||
|
||||
private static <T> List<T> removeIndices(@NotNull JList<T> list, @NotNull int[] indices, @Nullable Condition<? super T> condition) {
|
||||
if (indices.length == 0) {
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
ListModel model = list.getModel();
|
||||
int firstSelectedIndex = idxs[0];
|
||||
ListModel<T> model = list.getModel();
|
||||
ListModelExtension<T, ListModel<T>> extension = getExtension(model);
|
||||
int firstSelectedIndex = indices[0];
|
||||
ArrayList<T> 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 <T> boolean canRemoveSelectedItems(@NotNull JList<T> 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 <T> boolean canRemoveSelectedItems(@NotNull JList<T> list, @Nullable Condition<? super T> condition) {
|
||||
int[] indices = list.getSelectedIndices();
|
||||
if (indices.length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int index : idxs) {
|
||||
ListModel<T> model = list.getModel();
|
||||
ListModelExtension<T, ListModel<T>> 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 <T> int moveSelectedItemsUp(@NotNull JList<T> list) {
|
||||
ListModel<T> model = list.getModel();
|
||||
ListModelExtension<T, ListModel<T>> 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 <T> boolean canMoveSelectedItemsUp(@NotNull JList<T> list) {
|
||||
int[] indices = list.getSelectedIndices();
|
||||
return indices.length > 0 && indices[0] > 0;
|
||||
}
|
||||
|
||||
public static int moveSelectedItemsDown(JList list) {
|
||||
DefaultListModel model = getModel(list);
|
||||
public static <T> int moveSelectedItemsDown(@NotNull JList<T> list) {
|
||||
ListModel<T> model = list.getModel();
|
||||
ListModelExtension<T, ListModel<T>> 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 <T> boolean isPointOnSelection(@NotNull JList<T> 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 <T> boolean canMoveSelectedItemsDown(@NotNull JList<T> 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 <T> Updatable addMoveUpListener(@NotNull JButton button, @NotNull JList<T> 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 <T> Updatable addMoveDownListener(@NotNull JButton button, @NotNull JList<T> 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 <T> Updatable addRemoveListener(@NotNull JButton button, @NotNull JList<T> list) {
|
||||
return addRemoveListener(button, list, null);
|
||||
}
|
||||
|
||||
public static Updatable addRemoveListener(final JButton button, final JList list, final RemoveNotification<String> notification) {
|
||||
public static <T> Updatable addRemoveListener(@NotNull JButton button,
|
||||
@NotNull JList<T> list,
|
||||
@Nullable RemoveNotification<T> notification) {
|
||||
button.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final List<String> items = removeSelectedItems(list);
|
||||
if (notification != null)
|
||||
List<T> 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 <T> Updatable disableWhenNoSelection(@NotNull JButton button, @NotNull JList<T> list) {
|
||||
class MyListSelectionListener extends Updatable implements ListSelectionListener {
|
||||
MyListSelectionListener(JButton button) {
|
||||
super(button);
|
||||
@@ -339,67 +323,57 @@ public class ListUtil {
|
||||
void itemsRemoved(List<ItemType> items);
|
||||
}
|
||||
|
||||
private static ListModelExtension getExtensions(ListModel model) {
|
||||
/**
|
||||
* @noinspection unchecked
|
||||
*/
|
||||
@NotNull
|
||||
private static <T, ModelType extends ListModel<T>> ListModelExtension<T, ModelType> 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<ModelType extends ListModel> {
|
||||
Object get(ModelType model, int index);
|
||||
//@formatter:off
|
||||
private interface ListModelExtension<T, ModelType extends ListModel<T>> {
|
||||
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<T> item);
|
||||
}
|
||||
|
||||
private static final ListModelExtension DEFAULT_MODEL = new ListModelExtension<DefaultListModel>() {
|
||||
@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<Object, DefaultListModel<Object>>() {
|
||||
@Override public Object get(DefaultListModel<Object> model, int index) { return model.get(index);}
|
||||
@Override public void set(DefaultListModel<Object> model, int index, Object item) { model.set(index, item);}
|
||||
@Override public void remove(DefaultListModel<Object> model, int index) { model.remove(index);}
|
||||
@Override public void removeAll(DefaultListModel<Object> model) { model.removeAllElements();}
|
||||
@Override public void addAll(DefaultListModel<Object> model, List<Object> item) { model.addElement(item);}
|
||||
};
|
||||
|
||||
private static final ListModelExtension COLLECTION_MODEL = new ListModelExtension<CollectionListModel>() {
|
||||
@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<Object, CollectionListModel<Object>>() {
|
||||
@Override public Object get(CollectionListModel<Object> model, int index) { return model.getElementAt(index);}
|
||||
@Override public void set(CollectionListModel<Object> model, int index, Object item) { model.setElementAt(item, index);}
|
||||
@Override public void remove(CollectionListModel<Object> model, int index) { model.remove(index);}
|
||||
@Override public void removeAll(CollectionListModel<Object> model) { model.removeAll();}
|
||||
@Override public void addAll(CollectionListModel<Object> model, List<Object> items) { model.addAll(model.getSize(), items);}
|
||||
};
|
||||
|
||||
private static final ListModelExtension SORTED_MODEL = new ListModelExtension<SortedListModel>() {
|
||||
@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<Object, SortedListModel<Object>>() {
|
||||
@Override public Object get(SortedListModel<Object> model, int index) { return model.get(index);}
|
||||
@Override public void set(SortedListModel<Object> model, int index, Object item) { model.remove(index); model.add(item);}
|
||||
@Override public void remove(SortedListModel<Object> model, int index) { model.remove(index);}
|
||||
@Override public void removeAll(SortedListModel<Object> model) { model.clear();}
|
||||
@Override public void addAll(SortedListModel<Object> model, List<Object> items) { model.addAll(items);}
|
||||
};
|
||||
|
||||
private static final ListModelExtension FILTERED_MODEL = new ListModelExtension<FilteringListModel>() {
|
||||
@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<Object, FilteringListModel<Object>>() {
|
||||
@Override public Object get(FilteringListModel<Object> model, int index) { return model.getElementAt(index);}
|
||||
@Override public void set(FilteringListModel<Object> model, int index, Object item) { getExtension(model.getOriginalModel()).set(model, index, item);}
|
||||
@Override public void remove(FilteringListModel<Object> model, int index) { model.remove(index);}
|
||||
@Override public void removeAll(FilteringListModel<Object> model) { model.replaceAll(Collections.emptyList());}
|
||||
@Override public void addAll(FilteringListModel<Object> model, List<Object> items) { model.addAll(items);}
|
||||
};
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@@ -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<T> extends AbstractListModel<T> {
|
||||
return myData.contains(value);
|
||||
}
|
||||
|
||||
public ListModel getOriginalModel() {
|
||||
@NotNull
|
||||
public ListModel<T> getOriginalModel() {
|
||||
return myOriginalModel;
|
||||
}
|
||||
|
||||
public void addAll(List<T> elements) {
|
||||
myData.addAll(elements);
|
||||
((CollectionListModel<T>)myOriginalModel).add(elements);
|
||||
ListUtil.addAllItems(myOriginalModel, elements);
|
||||
}
|
||||
|
||||
public void replaceAll(List<T> elements) {
|
||||
@@ -139,6 +141,6 @@ public class FilteringListModel<T> extends AbstractListModel<T> {
|
||||
}
|
||||
|
||||
public void remove(int index) {
|
||||
((CollectionListModel<T>)myOriginalModel).remove(myData.get(index));
|
||||
ListUtil.removeItem(myOriginalModel, index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.awt.*;
|
||||
import java.awt.event.FocusEvent;
|
||||
|
||||
public class ListWithFilter<T> extends JPanel implements DataProvider {
|
||||
private final JList<? extends T> myList;
|
||||
private final JList<T> myList;
|
||||
private final SearchTextField mySearchField = new SearchTextField(false);
|
||||
private final NameFilteringListModel<T> myModel;
|
||||
private final JScrollPane myScrollPane;
|
||||
@@ -52,7 +52,7 @@ public class ListWithFilter<T> extends JPanel implements DataProvider {
|
||||
return new ListWithFilter<>(list, scrollPane, namer, highlightAllOccurrences);
|
||||
}
|
||||
|
||||
private ListWithFilter(@NotNull JList<? extends T> list,
|
||||
private ListWithFilter(@NotNull JList<T> list,
|
||||
@NotNull JScrollPane scrollPane,
|
||||
@Nullable Function<? super T, String> namer,
|
||||
boolean highlightAllOccurrences) {
|
||||
@@ -77,7 +77,7 @@ public class ListWithFilter<T> extends JPanel implements DataProvider {
|
||||
myList.addKeyListener(mySpeedSearch);
|
||||
int selectedIndex = myList.getSelectedIndex();
|
||||
int modelSize = myList.getModel().getSize();
|
||||
myModel = new NameFilteringListModel<T>(myList, namer, mySpeedSearch::shouldBeShowing, mySpeedSearch);
|
||||
myModel = new NameFilteringListModel<>(myList, namer, mySpeedSearch::shouldBeShowing, mySpeedSearch);
|
||||
if (myModel.getSize() == modelSize) {
|
||||
myList.setSelectedIndex(selectedIndex);
|
||||
}
|
||||
|
||||
@@ -45,15 +45,15 @@ public class NameFilteringListModel<T> extends FilteringListModel<T> {
|
||||
this(list, namer, filter, () -> speedSearch.getFilter());
|
||||
}
|
||||
|
||||
public NameFilteringListModel(JList list, final Function<? super T, String> namer, final Condition<? super String> filter, final SpeedSearchSupply speedSearch) {
|
||||
public NameFilteringListModel(JList<T> list, final Function<? super T, String> namer, final Condition<? super String> filter, final SpeedSearchSupply speedSearch) {
|
||||
this(list, namer, filter, () -> {
|
||||
final String prefix = speedSearch.getEnteredPrefix();
|
||||
return prefix == null ? "" : prefix;
|
||||
});
|
||||
}
|
||||
|
||||
public NameFilteringListModel(JList list, final Function<? super T, String> namer, final Condition<? super String> filter, Computable<String> pattern) {
|
||||
super(list);
|
||||
public NameFilteringListModel(JList<T> list, final Function<? super T, String> namer, final Condition<? super String> filter, Computable<String> pattern) {
|
||||
super(list.getModel());
|
||||
myPattern = pattern;
|
||||
myNamer = namer;
|
||||
setFilter(namer != null ? (Condition<T>)t -> filter.value(namer.fun(t)) : null);
|
||||
|
||||
Reference in New Issue
Block a user