summaryrefslogblamecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/gui/changemonitor/TableWrapper.java
blob: 6bff2671ac886b93b769787daf9066d88405ae83 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11










                                             



































                                                                                                           

                                                                    














































                                                                                                      
                                                                                   



















































                                                                                
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");
	}
	
}