org.nuiton.jaxx.runtime.swing.JAXXList Maven / Gradle / Ivy
The newest version!
/*
* #%L
* JAXX :: Runtime
* %%
* Copyright (C) 2008 - 2024 Code Lutin, Ultreia.io
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
package org.nuiton.jaxx.runtime.swing;
import javax.swing.AbstractListModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JList;
import javax.swing.ListModel;
import java.awt.Component;
import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class JAXXList extends JList- {
private static final long serialVersionUID = 1L;
public class JAXXListModel extends AbstractListModel
- {
private final List
- items;
private static final long serialVersionUID = -1598924187490122036L;
public JAXXListModel(List
- items) {
this.items = items;
PropertyChangeListener listener = e -> {
if (e.getPropertyName().equals(Item.SELECTED_PROPERTY)) {
Item item = (Item) e.getSource();
int itemIndex = JAXXListModel.this.items.indexOf(item);
int[] oldSelection = getSelectedIndices();
int[] newSelection;
int index = -1;
for (int i = 0; i < oldSelection.length; i++) {
if (oldSelection[i] == itemIndex) {
index = i;
break;
}
}
if (item.isSelected()) {
if (index != -1) // it was already selected
{
return;
}
newSelection = new int[oldSelection.length + 1];
System.arraycopy(oldSelection, 0, newSelection, 0, oldSelection.length);
newSelection[newSelection.length - 1] = itemIndex;
} else {
if (index == -1) // it already wasn't selected
{
return;
}
newSelection = new int[oldSelection.length - 1];
System.arraycopy(oldSelection, 0, newSelection, 0, index);
System.arraycopy(oldSelection, index + 1, newSelection, index, oldSelection.length - 1 - index);
}
setSelectedIndices(newSelection);
} else {
for (int i = 0; i < getSize(); i++) {
if (getElementAt(i) == ((Item) e.getSource()).getValue()) {
fireContentsChanged(JAXXListModel.this, i, i);
if (isSelectedIndex(i)) {
fireSelectionValueChanged(i, i, false);
}
return;
}
}
}
};
for (Item item : items) {
item.addPropertyChangeListener(listener);
}
}
public List
- getItems() {
return items;
}
@Override
public Item getElementAt(int i) {
return items.get(i);
}
@Override
public int getSize() {
return items.size();
}
}
public JAXXList() {
setCellRenderer(new DefaultListCellRenderer() {
private static final long serialVersionUID = 1L;
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
ListModel model = list.getModel();
if (model instanceof JAXXListModel) {
Item item = ((JAXXListModel) model).items.get(index);
String label = item.getLabel();
if (label != null) {
value = label;
}
}
return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
}
});
addListSelectionListener(e -> {
ListModel model = getModel();
if (model instanceof JAXXListModel) {
List
- items = ((JAXXListModel) model).items;
for (int i = items.size() - 1; i >= 0; i--) {
boolean selected = isSelectedIndex(i);
Item item = items.get(i);
if (selected != item.isSelected()) {
item.setSelected(selected);
}
}
}
});
}
// this way we can keep it marked protected and still allow code in this file to call it
@Override
protected void fireSelectionValueChanged(int firstIndex, int lastIndex, boolean isAdjusting) {
super.fireSelectionValueChanged(firstIndex, lastIndex, isAdjusting);
}
public void setItems(List
- items) {
setModel(new JAXXListModel(items));
List
selectedIndexList = new ArrayList<>();
for (int i = 0; i < items.size(); i++) {
if (items.get(i).isSelected()) {
selectedIndexList.add(i);
}
}
int[] selectedIndices = new int[selectedIndexList.size()];
for (int i = 0; i < selectedIndexList.size(); i++) {
selectedIndices[i] = selectedIndexList.get(i);
}
setSelectedIndices(selectedIndices);
}
public List- getItems() {
if (getModel() instanceof JAXXListModel) {
return ((JAXXListModel) getModel()).getItems();
}
return null;
}
public void setSelectedValue(Object value) {
super.setSelectedValue(value, true);
}
/**
* Set the selected Objects
*
* @param values Objects must be selected in the list
*/
public void setSelectedValues(Object[] values) {
if (values != null) {
List
selectedIndices = new ArrayList<>();
ListModel model = getModel();
for (int i = 0; i < model.getSize(); i++) {
Object o = model.getElementAt(i);
for (Object value : values) {
if (o.equals(value)) {
selectedIndices.add(i);
break;
}
}
}
int[] ints = new int[selectedIndices.size()];
for (int i = 0; i < ints.length; i++) {
ints[i] = selectedIndices.get(i);
}
setSelectedIndices(ints);
} else {
// No selection if values is null
setSelectedIndex(-1);
}
}
public void setSelectedItem(Item item) {
super.setSelectedValue(item.getValue(), true);
}
public void setSelectedItems(List- itemsToSelect) {
if (itemsToSelect != null) {
List
- items = getItems();
int[] indices = new int[itemsToSelect.size()];
int i = 0;
for (Item item : itemsToSelect) {
indices[i] = items.indexOf(item);
i++;
}
super.setSelectedIndices(indices);
}
}
public Item getSelectedItem() {
Object selected = super.getSelectedValue();
return findItem(selected);
}
public List
- getSelectedItems() {
List
- selected = super.getSelectedValuesList();
java.util.List
- itemsSelected = new ArrayList<>();
for (Object s : selected) {
itemsSelected.add(findItem(s));
}
return itemsSelected;
}
public Item findItem(Object value) {
List
- items = getItems();
if (items != null) {
for (Item i : items) {
if (i.getValue().equals(value)) {
return i;
}
}
}
return null;
}
public void addItem(Item item) {
List
- items = getItems();
if (items != null) {
items.add(item);
setItems(items);
}
}
public void addAllItems(Collection
- itemsToAdd) {
List
- items = getItems();
if (items != null) {
items.addAll(itemsToAdd);
setItems(items);
}
}
public void removeItem(Item item) {
List
- items = getItems();
if (items != null) {
items.remove(item);
setItems(items);
}
}
public void removeAllItems(Collection
- itemsToRemove) {
List
- items = getItems();
if (items != null) {
items.removeAll(itemsToRemove);
setItems(items);
}
}
/**
* Fill a list model with some datas, and select after all the given object
*
* @param data data ot inject in combo
* @param selects the objects to select in list after reflling his model
*/
public void fillList(Collection> data, Collection> selects) {
if (selects == null) {
selects = java.util.Collections.EMPTY_LIST;
}
List
- items = new ArrayList<>();
for (Object o : data) {
boolean selected = false;
for (Object select : selects) {
if (selected = o.equals(select)) {
break;
}
}
items.add(new Item(o.toString(), o.toString(), o, selected));
}
setItems(items);
}
/**
* Fill a list model with some datas, and select after all the given object
*
* @param data data ot inject in combo
* @param select object to select in list after reflling his model
*/
public void fillList(Collection> data, Object select) {
List
- items = new ArrayList<>();
for (Object o : data) {
boolean selected = o.equals(select);
items.add(new Item(o.toString(), o.toString(), o, selected));
}
setItems(items);
}
/**
* Fill a list model with some datas, and select after all the given object
*
* @param data data ot inject in combo
* @param select object to select in list after reflling his model
* @param methodName method to invoke to display data's name
*/
public void fillList(Collection> data, Object select, String methodName) {
// prepare method to use
Method m = null;
List
- items = new ArrayList<>();
for (Object o : data) {
boolean selected = o.equals(select);
if (m == null) {
try {
m = o.getClass().getMethod(methodName);
m.setAccessible(true);
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException("could not find method " + methodName + " on " + o.getClass());
}
}
try {
items.add(new Item(o.toString(), (String) m.invoke(o), o, selected));
} catch (SecurityException | InvocationTargetException | IllegalArgumentException | IllegalAccessException e) {
// shoudl never happen ?
throw new RuntimeException(e);
}
}
setItems(items);
}
/**
* Fill a list model with some datas, and select after all the given object
*
* @param data data ot inject in combo
* @param selects the objects to select in list after reflling his model
* @param methodName method to invoke to display data's name
*/
public void fillList(Collection> data, Collection> selects, String methodName) {
// prepare method to use
Method m = null;
List
- items = new ArrayList<>();
for (Object o : data) {
boolean selected = selects.contains(o);
if (m == null) {
try {
m = o.getClass().getMethod(methodName);
m.setAccessible(true);
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException("could not find method " + methodName + " on " + o.getClass());
}
}
try {
items.add(new Item(o.toString(), (String) m.invoke(o), o, selected));
} catch (SecurityException | InvocationTargetException | IllegalArgumentException | IllegalAccessException e) {
// shoudl never happen ?
throw new RuntimeException(e);
}
}
setItems(items);
}
}