package org.openslx.dozmod.gui.control.table; import java.awt.Component; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Set; import javax.swing.Box; import org.apache.log4j.Logger; public abstract class CheckListTable extends ListTable> { private static final long serialVersionUID = 5667297891670398732L; private static final Logger LOGGER = Logger.getLogger(CheckListTable.class); public static final ListTableColumn COL_CHECKBOX = new ListTableColumn("", Boolean.class, null, true); private static final Component LBL_EMPTY_CELL = Box.createHorizontalGlue(); public CheckListTable(ListTableColumn... columns) { this(null, columns); } public CheckListTable(final Comparator itemComparator, ListTableColumn... columns) { super(itemComparator == null ? null : new Comparator>() { @Override public int compare(Wrapper o1, Wrapper o2) { if (o1 == null && o2 == null) return 0; if (o1 == null) return -1; if (o2 == null) return 1; return itemComparator.compare(o1.item, o2.item); } }, copyColumns(columns)); } private static ListTableColumn[] copyColumns(ListTableColumn[] columns) { final ListTableColumn ncolumns[] = new ListTableColumn[columns.length + 1]; ncolumns[0] = COL_CHECKBOX; System.arraycopy(columns, 0, ncolumns, 1, columns.length); return ncolumns; } @Override public void setValueAt(Object newValue, Wrapper row, ListTableColumn column) { if (column == COL_CHECKBOX && newValue != null && newValue.getClass() == Boolean.class) { row.isChecked = (Boolean)newValue; } } @Override protected final Object getValueAtInternal(Wrapper row, ListTableColumn columnIndex) { if (row.item == null) return null; if (columnIndex == COL_CHECKBOX) { return row.isChecked; } return getValueAtInternal2(row.item, columnIndex); } protected abstract Object getValueAtInternal2(T row, ListTableColumn columnIndex); @Override public final Component prepareRenderHook(Component component, Wrapper row, ListTableColumn listTableColumn, boolean isSelected) { if (listTableColumn == COL_CHECKBOX) { if (row == null || row.item == null || !isItemCheckable(row.item)) { return LBL_EMPTY_CELL; } } else if (row.item != null) { component = prepareRenderHook2(component, row.item, listTableColumn, isSelected); } return component; } public Component prepareRenderHook2(Component component, T row, ListTableColumn listTableColumn, boolean isSelected) { // Nothing return component; } public void setData(List data, Set preChecked, boolean sort) { List> list = new ArrayList<>(data.size()); for (T item : data) { list.add(new Wrapper(item, preChecked != null && preChecked.contains(item))); } super.setData(list, sort); } protected abstract boolean isItemCheckable(T item); public T getSelectedItem2() { Wrapper ret = getSelectedItem(); if (ret == null) return null; return ret.item; } public static class Wrapper { protected boolean isChecked; public final S item; public Wrapper(S item, boolean checked) { this.item = item; this.isChecked = checked; } @Override public boolean equals(Object obj) { if (obj == null) return false; if (obj instanceof Wrapper) return item.equals(((Wrapper)obj).item); return false; } @Override public int hashCode() { return item.hashCode(); } @Override public String toString() { return "(" + item.hashCode() + "=" + isChecked + ")"; } public boolean isChecked() { return isChecked; } } }