blob: 6bff2671ac886b93b769787daf9066d88405ae83 (
plain) (
tree)
|
|
package org.openslx.dozmod.gui.changemonitor;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Comparator;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
/**
* Monitoring a JTable etc.
*/
class TableWrapper extends AbstractControlWrapper<ClonedTableModel> {
private static final Comparator<ClonedTableModel> COMPARATOR = new Comparator<ClonedTableModel>() {
public int compare(ClonedTableModel o1, ClonedTableModel o2) {
if (o1 == null && o2 == null)
return 0;
if (o1 == null)
return -o2.rowCount;
if (o2 == null)
return o1.rowCount;
if (o1.rowCount != o2.rowCount)
return o2.rowCount - o1.rowCount;
if (o1.columnCount != o2.columnCount)
return o2.columnCount - o1.columnCount;
for (int i = 0; i < o1.grid.length; ++i) {
Object c1 = o1.grid[i];
Object c2 = o2.grid[i];
if (c1 == c2)
continue;
if (c1 == null)
return c2.hashCode();
if (c2 == null)
return c1.hashCode();
if (c1.equals(c2))
continue;
return c1.hashCode() - c2.hashCode();
}
return 0;
}
};
private final JTable component;
public TableWrapper(DialogChangeMonitor dcm, JTable table) {
super(dcm, COMPARATOR);
this.component = table;
final TableModelListener changeListener = new TableModelListener() {
public void tableChanged(TableModelEvent e) {
contentChanged();
}
};
// Make sure we notice when the whole model changes
table.addPropertyChangeListener("model", new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
Object o = evt.getOldValue();
Object n = evt.getNewValue();
if (o != null && o instanceof TableModel) {
((TableModel)o).removeTableModelListener(changeListener);
}
if (n != null && n instanceof TableModel) {
((TableModel)n).addTableModelListener(changeListener);
}
}
});
// Add listener to the current model
if (table.getModel() != null) {
table.getModel().addTableModelListener(changeListener);
}
}
ClonedTableModel getCurrentValue() {
TableModel model = component.getModel();
if (model == null)
return null;
return new ClonedTableModel(model);
}
}
class ClonedTableModel implements TableModel {
protected final Object[] grid;
protected final int columnCount, rowCount;
protected ClonedTableModel(TableModel other) {
columnCount = other.getColumnCount();
rowCount = other.getRowCount();
grid = new Object[columnCount * rowCount];
for (int y = 0; y < rowCount; ++y) {
for (int x = 0; x < columnCount; ++x) {
// Hopefully we mostly deal with imutable types so we don't need clone
grid[y * columnCount + x] = other.getValueAt(y, x);
}
}
}
@Override
public int getRowCount() {
return rowCount;
}
@Override
public int getColumnCount() {
return columnCount;
}
@Override
public String getColumnName(int columnIndex) {
return null;
}
@Override
public Class<?> getColumnClass(int columnIndex) {
if (grid[columnIndex] == null)
return Object.class;
return grid[columnIndex].getClass();
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return grid[rowIndex * rowCount + columnCount];
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
throw new RuntimeException("A cloned table model is read only");
}
@Override
public void addTableModelListener(TableModelListener l) {
throw new RuntimeException("A cloned table model is read only");
}
@Override
public void removeTableModelListener(TableModelListener l) {
throw new RuntimeException("A cloned table model is read only");
}
}
|