package com.revolsys.swing.table.record; import java.awt.event.MouseEvent; import java.util.Map.Entry; import javax.swing.RowSorter; import javax.swing.SortOrder; import javax.swing.SwingUtilities; import javax.swing.event.TableModelEvent; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; import javax.swing.table.TableModel; import org.jdesktop.swingx.sort.SortController; import com.revolsys.geometry.model.Geometry; import com.revolsys.record.Record; import com.revolsys.record.schema.FieldDefinition; import com.revolsys.record.schema.RecordDefinition; import com.revolsys.swing.listener.BaseMouseListener; import com.revolsys.swing.map.layer.record.LayerRecord; import com.revolsys.swing.map.layer.record.table.model.RecordLayerTableModel; import com.revolsys.swing.map.layer.record.table.predicate.ErrorPredicate; import com.revolsys.swing.map.layer.record.table.predicate.ModifiedFieldPredicate; import com.revolsys.swing.parallel.Invoke; import com.revolsys.swing.table.BaseColumnFactory; import com.revolsys.swing.table.BaseJTable; import com.revolsys.swing.table.TablePanel; import com.revolsys.swing.table.record.editor.RecordTableCellEditor; import com.revolsys.swing.table.record.model.RecordRowTableModel; import com.revolsys.swing.table.record.renderer.RecordRowTableCellRenderer; public class RecordRowTable extends BaseJTable implements BaseMouseListener { private static final long serialVersionUID = 1L; public static <V extends Record> V getEventRecord() { final BaseJTable eventTable = TablePanel.getEventTable(); if (eventTable instanceof RecordRowTable) { final RecordRowTable table = (RecordRowTable)eventTable; if (table != null) { final int eventRow = TablePanel.getEventRow(); if (eventRow != -1) { final RecordRowTableModel model = table.getTableModel(); final V record = model.getRecord(eventRow); return record; } } } return null; } private TableCellRenderer cellRenderer; private RecordTableCellEditor tableCellEditor; public RecordRowTable(final RecordRowTableModel model) { this(model, new RecordRowTableCellRenderer()); } public RecordRowTable(final RecordRowTableModel model, final TableCellRenderer cellRenderer) { super(model); setColumnFactory(new BaseColumnFactory()); this.cellRenderer = cellRenderer; setSortable(false); setShowHorizontalLines(false); setRowMargin(0); final JTableHeader tableHeader = getTableHeader(); final TableColumnModel columnModel = getColumnModel(); this.tableCellEditor = newTableCellEditor(); this.tableCellEditor.addCellEditorListener(model); for (int columnIndex = 0; columnIndex < columnModel.getColumnCount(); columnIndex++) { try { final TableColumn column = columnModel.getColumn(columnIndex); if (columnIndex >= model.getColumnFieldsOffset()) { column.setCellEditor(this.tableCellEditor); } column.setCellRenderer(cellRenderer); } catch (final ArrayIndexOutOfBoundsException e) { } } tableHeader.addMouseListener(this); addNewRecordHighlighter(); addModifiedRecordHighlighter(); addDeletedRecordHighlighter(); ModifiedFieldPredicate.add(this); ErrorPredicate.add(this); } protected void addDeletedRecordHighlighter() { } protected void addModifiedRecordHighlighter() { } protected void addNewRecordHighlighter() { } @Override public void dispose() { super.dispose(); this.tableCellEditor = null; this.cellRenderer = null; } public FieldDefinition getColumnFieldDefinition(final int columnIndex) { final RecordRowTableModel model = getModel(); return model.getColumnFieldDefinition(columnIndex); } public String getColumnFieldName(final int columnIndex) { final RecordRowTableModel model = getModel(); return model.getColumnFieldName(columnIndex); } @Override public RecordRowTableModel getModel() { return (RecordRowTableModel)super.getModel(); } public LayerRecord getRecord(final int row) { final RecordLayerTableModel model = getTableModel(); if (model == null) { return null; } else { return model.getRecord(row); } } public RecordDefinition getRecordDefinition() { final RecordRowTableModel model = getModel(); return model.getRecordDefinition(); } public Record getSelectedRecord() { final int row = getSelectedRow(); if (row == -1) { return null; } else { final RecordRowTableModel tableModel = getTableModel(); return tableModel.getRecord(row); } } public RecordTableCellEditor getTableCellEditor() { return this.tableCellEditor; } @Override protected void initializeColumnPreferredWidth(final TableColumn column) { super.initializeColumnPreferredWidth(column); final RecordRowTableModel model = getTableModel(); final int columnIndex = column.getModelIndex(); final FieldDefinition fieldDefinition = model.getColumnFieldDefinition(columnIndex); if (fieldDefinition != null) { Integer columnWidth = fieldDefinition.getProperty("tableColumnWidth"); final String columnName = fieldDefinition.getTitle(); if (columnWidth == null) { columnWidth = fieldDefinition.getMaxStringLength() * 7; columnWidth = Math.min(columnWidth, 200); fieldDefinition.setProperty("tableColumnWidth", columnWidth); } final int nameWidth = columnName.length() * 8 + 15; column.setPreferredWidth(Math.max(nameWidth, columnWidth)); } } @Override public void mouseClicked(final MouseEvent e) { final Object source = e.getSource(); if (source == getTableHeader()) { final RecordRowTableModel model = getModel(); final int columnIndex = columnAtPoint(e.getPoint()); if (columnIndex > -1 && SwingUtilities.isLeftMouseButton(e)) { final Class<?> fieldClass = model.getColumnClass(columnIndex); if (!Geometry.class.isAssignableFrom(fieldClass)) { model.setSortOrder(columnIndex); } } } } protected RecordTableCellEditor newTableCellEditor() { return new RecordTableCellEditor(this); } @Override public void setRowSorter(final RowSorter<? extends TableModel> sorter) { super.setRowSorter(sorter); if (sorter != null) { final SortController<?> sortController = getSortController(); if (sortController != null) { final RecordRowTableModel model = getTableModel(); sortController.resetSortOrders(); for (final Entry<Integer, SortOrder> entry : model.getSortedColumns().entrySet()) { final int index = entry.getKey(); if (index < model.getColumnCount()) { final SortOrder sortOrder = entry.getValue(); sortController.setSortOrder(index, sortOrder); } } } } } @Override public void tableChanged(final TableModelEvent event) { Invoke.later(() -> { final RecordRowTableModel model = getModel(); final int fieldsOffset = model.getColumnFieldsOffset(); tableChangedDo(event); final int type = event.getType(); final int eventColumn = event.getColumn(); final int row = event.getFirstRow(); if (type == TableModelEvent.UPDATE && eventColumn == TableModelEvent.ALL_COLUMNS && row == TableModelEvent.HEADER_ROW) { createDefaultColumnsFromModel(); final TableColumnModel columnModel = getColumnModel(); for (int columnIndex = 0; columnIndex < model.getColumnCount(); columnIndex++) { final TableColumn column = columnModel.getColumn(columnIndex); if (columnIndex >= fieldsOffset) { column.setCellEditor(this.tableCellEditor); } column.setCellRenderer(this.cellRenderer); } initializeColumnWidths(); } if (this.tableHeader != null) { this.tableHeader.resizeAndRepaint(); } }); } protected void tableChangedDo(final TableModelEvent event) { try { super.tableChanged(event); } catch (final Throwable t) { } } @Override public String toString() { return getRecordDefinition().getPath(); } }