package jrex.ui.model; import com.google.common.collect.HashBasedTable; import com.google.common.collect.Table; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.swing.table.AbstractTableModel; /** * A mutable table model backed by a Guava table. * * @author Mark George <mark.george@otago.ac.nz> */ public final class MutableTableModel extends AbstractTableModel { private Table<Integer, Integer, String> table = HashBasedTable.create(); private List<String> headers; public MutableTableModel() { this.headers = null; } public MutableTableModel(List<String> headers) { this.headers = headers; } @Override public int getRowCount() { return table.rowKeySet().size(); } @Override public int getColumnCount() { return table.columnKeySet().size(); } @Override public String getColumnName(int columnIndex) { return headers.get(columnIndex); } @Override public Class<?> getColumnClass(int columnIndex) { return String.class; } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return true; } @Override public Object getValueAt(int rowIndex, int columnIndex) { return table.get(rowIndex, columnIndex); } @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { table.put(rowIndex, columnIndex, aValue.toString()); fireTableCellUpdated(rowIndex, columnIndex); } public void addRow(List<String> values) { int rowCount = getRowCount(); for (int i = 0; i < values.size(); i++) { table.put(rowCount, i, values.get(i)); } fireTableRowsInserted(rowCount, rowCount); } public void addRow(String[] values) { addRow(Arrays.asList(values)); } public void deleteRow(int rowIndex) { // this gets messy no matter what backend we use since we need to reorder the row indexes // delete the row table.row(rowIndex).clear(); Set<Integer> rowKeySet = table.rowKeySet(); // create a new table Table<Integer, Integer, String> newTable = HashBasedTable.create(); int idx = 0; for (Integer key : rowKeySet) { Map<Integer, String> row = table.row(key); newTable.put(idx, 0, row.get(0)); newTable.put(idx, 1, row.get(1)); idx++; } table = newTable; fireTableDataChanged(); } public Table<Integer, Integer, String> getTable() { return table; } public void moveUp(int rowIndex) { if (rowIndex < 0 || rowIndex == 0) { return; } Map<Integer, String> selected = table.row(rowIndex); Map<Integer, String> previous = table.row(rowIndex - 1); Map<Integer, String> clone = new HashMap<>(selected); selected.put(0, previous.get(0)); selected.put(1, previous.get(1)); previous.put(0, clone.get(0)); previous.put(1, clone.get(1)); fireTableDataChanged(); } public void moveDown(int rowIndex) { if (rowIndex < 0 || rowIndex == getRowCount() - 1) { return; } Map<Integer, String> selected = table.row(rowIndex); Map<Integer, String> next = table.row(rowIndex + 1); Map<Integer, String> clone = new HashMap<>(selected); selected.put(0, next.get(0)); selected.put(1, next.get(1)); next.put(0, clone.get(0)); next.put(1, clone.get(1)); fireTableDataChanged(); } public List<String> getHeaders() { return headers; } public void setHeaders(List<String> headers) { this.headers = headers; } public List<List<String>> getRows() { List<List<String>> rows = new ArrayList<>(); Map<Integer, Map<Integer, String>> rowMap = table.rowMap(); for (Map.Entry<Integer, Map<Integer, String>> entry : rowMap.entrySet()) { rows.add(new ArrayList(entry.getValue().values())); } return rows; } }