package com.github.pfichtner.jrunalyser.ui.table.renderers; import java.awt.Component; import java.util.List; import javax.swing.JTable; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableModel; import com.google.common.base.Throwables; import com.google.common.collect.Lists; import com.google.common.collect.Ordering; // TODO We should cache the column data but then we would have to implement TableModelListener for dropping these cached values public abstract class PositionRendererDecorator implements TableCellRenderer, Cloneable { private final TableCellRenderer delegate; private static final Ordering<Comparable<?>> N = Ordering .<Comparable<?>> natural().reverse().nullsLast(); private static final Ordering<Object> S = Ordering.usingToString() .reverse().nullsLast(); private Ordering<Comparable<?>> natural = N; private Ordering<Object> string = S; public PositionRendererDecorator(TableCellRenderer delegate) { this.delegate = delegate; } public PositionRendererDecorator reverse() { try { PositionRendererDecorator clone = (PositionRendererDecorator) clone(); clone.natural = this.natural.reverse().nullsLast(); clone.string = this.string.reverse().nullsLast(); return clone; } catch (CloneNotSupportedException e) { throw Throwables.propagate(e); } } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component c = this.delegate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); if (value != null && !isSelected && getRowCount(table.getModel()) > 1) { renderPos(table, c, getPos(table, row, column)); } return c; } protected abstract void renderPos(JTable table, Component c, int pos); private int getPos(JTable table, int row, int column) { int cnt = 0; Object value = table.getModel().getValueAt( table.convertRowIndexToModel(row), table.convertColumnIndexToModel(column)); List<?> sorted = getSorted(table, column); for (Object object : sorted) { if (object == value || object.equals(value)) { return cnt; } cnt++; } return -1; } @SuppressWarnings("unchecked") private List<?> getSorted(JTable table, int col) { return (Comparable.class.isAssignableFrom(table.getColumnClass(col)) ? this.natural : this.string).sortedCopy(getValues(table, col)); } @SuppressWarnings("rawtypes") private List getValues(JTable table, int col) { TableModel tm = table.getModel(); int modelCol = table.convertColumnIndexToModel(col); int rowCount = getRowCount(tm); List<Object> rowValues = Lists.newArrayListWithCapacity(rowCount); for (int row = 0; row < rowCount; row++) { rowValues.add(tm.getValueAt(row, modelCol)); } return rowValues; } public int getRowCount(TableModel tm) { return tm.getRowCount(); } }