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<T> extends ListTable<CheckListTable.Wrapper<T>> {
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<T> itemComparator, ListTableColumn... columns) {
super(itemComparator == null ? null : new Comparator<Wrapper<T>>() {
@Override
public int compare(Wrapper<T> o1, Wrapper<T> 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<T> row, ListTableColumn column) {
if (column == COL_CHECKBOX && newValue != null && newValue.getClass() == Boolean.class) {
row.isChecked = (Boolean)newValue;
}
}
@Override
protected final Object getValueAtInternal(Wrapper<T> 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<T> 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<T> data, Set<T> preChecked, boolean sort) {
List<Wrapper<T>> list = new ArrayList<>(data.size());
for (T item : data) {
list.add(new Wrapper<T>(item, preChecked != null && preChecked.contains(item)));
}
super.setData(list, sort);
}
protected abstract boolean isItemCheckable(T item);
public T getSelectedItem2() {
Wrapper<T> ret = getSelectedItem();
if (ret == null)
return null;
return ret.item;
}
public static class Wrapper<S> {
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;
}
}
}