1 package net.argius.stew.ui.window;
3 import static java.awt.event.InputEvent.SHIFT_DOWN_MASK;
4 import static java.awt.event.KeyEvent.*;
5 import static java.awt.event.MouseEvent.MOUSE_DRAGGED;
6 import static java.awt.event.MouseEvent.MOUSE_PRESSED;
7 import static javax.swing.KeyStroke.getKeyStroke;
8 import static net.argius.stew.ui.window.AnyActionKey.*;
9 import static net.argius.stew.ui.window.ResultSetTable.ActionKey.*;
12 import java.awt.event.*;
17 import java.util.List;
20 import javax.swing.event.*;
21 import javax.swing.table.*;
22 import javax.swing.text.*;
24 import net.argius.stew.*;
25 import net.argius.stew.io.*;
26 import net.argius.stew.text.*;
29 * Table for Result Set.
31 final class ResultSetTable extends JTable implements AnyActionListener, TextSearch {
35 clearSelectedCellValue,
49 static final String TAB = "\t";
51 private static final Logger log = Logger.getLogger(ResultSetTable.class);
52 private static final TableCellRenderer nullRenderer = new NullValueRenderer();
53 private static final boolean[] booleans = {false, true};
55 private final AnyActionListener anyActionListener;
56 private final ColumnHeaderCellRenderer columnHeaderRenderer;
57 private final RowHeader rowHeader;
58 private final Point mousePositionForColumnHeader = new Point();
60 private int lastSortedIndex;
61 private boolean lastSortedIsReverse;
62 private String autoAdjustMode;
64 // It is used by the process that has no key-event.
65 private volatile KeyEvent lastKeyEvent;
70 ResultSetTable(AnyActionListener anyActionListener) {
71 this.anyActionListener = anyActionListener;
72 JTableHeader columnHeader = getTableHeader();
73 TableCellRenderer columnHeaderDefaultRenderer = columnHeader.getDefaultRenderer();
74 final RowHeader rowHeader = new RowHeader(this);
75 this.columnHeaderRenderer = new ColumnHeaderCellRenderer(columnHeaderDefaultRenderer);
76 this.rowHeader = rowHeader;
77 setColumnSelectionAllowed(true);
78 setAutoResizeMode(AUTO_RESIZE_OFF);
79 columnHeader.setDefaultRenderer(columnHeaderRenderer);
80 columnHeader.setReorderingAllowed(false);
83 MouseInputListener colHeaderMouseListener = new ColumnHeaderMouseInputListener();
84 columnHeader.addMouseListener(colHeaderMouseListener);
85 columnHeader.addMouseMotionListener(colHeaderMouseListener);
87 MouseInputListener rowHeaderMouseListener = new RowHeaderMouseInputListener(rowHeader);
88 rowHeader.addMouseListener(rowHeaderMouseListener);
89 rowHeader.addMouseMotionListener(rowHeaderMouseListener);
91 for (final boolean withSelect : booleans) {
92 bindJumpAction("home", VK_HOME, withSelect);
93 bindJumpAction("end", VK_END, withSelect);
94 bindJumpAction("top", VK_UP, withSelect);
95 bindJumpAction("bottom", VK_DOWN, withSelect);
96 bindJumpAction("leftmost", VK_LEFT, withSelect);
97 bindJumpAction("rightmost", VK_RIGHT, withSelect);
100 final int shortcutKey = Utilities.getMenuShortcutKeyMask();
101 AnyAction aa = new AnyAction(this);
102 aa.bindSelf(copyWithEscape, getKeyStroke(VK_C, shortcutKey | InputEvent.SHIFT_DOWN_MASK));
103 aa.bindSelf(paste, getKeyStroke(VK_V, shortcutKey));
104 aa.bindSelf(clearSelectedCellValue, getKeyStroke(VK_DELETE, 0));
105 aa.bindSelf(deleteRows, getKeyStroke(VK_MINUS, shortcutKey | InputEvent.SHIFT_DOWN_MASK));
106 aa.bindKeyStroke(true, adjustColumnWidth, getKeyStroke(VK_SLASH, shortcutKey));
107 aa.bindKeyStroke(false, doNothing, getKeyStroke(VK_ESCAPE, 0));
110 private final class RowHeaderMouseInputListener extends MouseInputAdapter {
112 @SuppressWarnings("hiding")
113 private final RowHeader rowHeader;
114 private int dragStartRow;
116 RowHeaderMouseInputListener(RowHeader rowHeader) {
117 this.rowHeader = rowHeader;
121 public void mousePressed(MouseEvent e) {
126 public void mouseDragged(MouseEvent e) {
130 private void changeSelection(MouseEvent e) {
131 Point p = new Point(e.getX(), e.getY());
132 if (SwingUtilities.isLeftMouseButton(e)) {
134 boolean isMousePressed = (id == MOUSE_PRESSED);
135 boolean isMouseDragged = (id == MOUSE_DRAGGED);
136 if (isMousePressed || isMouseDragged) {
137 if (p.y >= rowHeader.getBounds().height) {
140 if (!e.isControlDown() && !e.isShiftDown()) {
143 int rowIndex = rowAtPoint(p);
144 if (rowIndex < 0 || getRowCount() < rowIndex) {
149 if (isMousePressed) {
150 if (e.isShiftDown()) {
151 index0 = dragStartRow;
154 dragStartRow = rowIndex;
158 } else if (isMouseDragged) {
159 index0 = dragStartRow;
164 addRowSelectionInterval(index0, index1);
165 addColumnSelectionInterval(getColumnCount() - 1, 0);
167 // justify a position between table and its row header
168 JViewport tableView = (JViewport)getParent();
169 Point viewPosition = tableView.getViewPosition();
170 viewPosition.y = ((JViewport)rowHeader.getParent()).getViewPosition().y;
171 tableView.setViewPosition(viewPosition);
177 private final class ColumnHeaderMouseInputListener extends MouseInputAdapter {
179 private int dragStartColumn;
181 ColumnHeaderMouseInputListener() {
184 @SuppressWarnings("synthetic-access")
186 public void mousePressed(MouseEvent e) {
187 if (SwingUtilities.isLeftMouseButton(e)) {
190 mousePositionForColumnHeader.setLocation(e.getPoint());
194 public void mouseDragged(MouseEvent e) {
195 if (SwingUtilities.isLeftMouseButton(e)) {
200 private void changeSelection(MouseEvent e) {
201 final Point p = e.getPoint();
203 boolean isMousePressed = (id == MOUSE_PRESSED);
204 boolean isMouseDragged = (id == MOUSE_DRAGGED);
205 if (isMousePressed || isMouseDragged) {
206 if (!e.isControlDown() && !e.isShiftDown()) {
209 int columnIndex = columnAtPoint(p);
210 if (columnIndex < 0 || getColumnCount() <= columnIndex) {
215 if (isMousePressed) {
216 if (e.isShiftDown()) {
217 index0 = dragStartColumn;
218 index1 = columnIndex;
220 dragStartColumn = columnIndex;
221 index0 = columnIndex;
222 index1 = columnIndex;
224 } else if (isMouseDragged) {
225 index0 = dragStartColumn;
226 index1 = columnIndex;
230 selectColumn(index0, index1);
237 protected void processKeyEvent(KeyEvent e) {
238 super.processKeyEvent(e);
243 public void anyActionPerformed(AnyActionEvent ev) {
245 processAnyActionEvent(ev);
246 } catch (Exception ex) {
247 WindowOutputProcessor.showErrorDialog(this, ex);
251 public void processAnyActionEvent(AnyActionEvent ev) throws Exception {
252 if (ev.isAnyOf(copy, selectAll)) {
253 final String cmd = ev.getActionCommand();
254 getActionMap().get(cmd).actionPerformed(new ActionEvent(this, 0, cmd));
255 } else if (ev.isAnyOf(copyWithEscape)) {
256 List<String> rows = new ArrayList<String>();
257 for (int rowIndex : getSelectedRows()) {
258 List<Object> row = new ArrayList<Object>();
259 for (int columnIndex : getSelectedColumns()) {
260 final Object o = getValueAt(rowIndex, columnIndex);
261 row.add(CsvFormatter.AUTO.format(o == null ? "" : String.valueOf(o)));
263 rows.add(TextUtilities.join(TAB, row));
265 ClipboardHelper.setStrings(rows);
266 } else if (ev.isAnyOf(paste)) {
268 InputStream is = new ByteArrayInputStream(ClipboardHelper.getString().getBytes());
269 Importer importer = new SmartImporter(is, TAB);
271 int[] selectedColumns = getSelectedColumns();
272 for (int rowIndex : getSelectedRows()) {
273 Object[] values = importer.nextRow();
274 final int limit = Math.min(selectedColumns.length, values.length);
275 for (int x = 0; x < limit; x++) {
276 setValueAt(values[x], rowIndex, selectedColumns[x]);
284 editingCanceled(new ChangeEvent(ev.getSource()));
286 } else if (ev.isAnyOf(clearSelectedCellValue)) {
288 setValueAtSelectedCells(null);
291 editingCanceled(new ChangeEvent(ev.getSource()));
293 } else if (ev.isAnyOf(setCurrentTimeValue)) {
295 setValueAtSelectedCells(new Timestamp(System.currentTimeMillis()));
298 editingCanceled(new ChangeEvent(ev.getSource()));
300 } else if (ev.isAnyOf(copyColumnName)) {
301 List<String> a = new ArrayList<String>();
302 ResultSetTableModel m = getResultSetTableModel();
303 if (ev.getModifiers() == 0) {
304 for (int i = 0, n = m.getColumnCount(); i < n; i++) {
305 a.add(m.getColumnName(i));
308 for (final int i : getSelectedColumns()) {
309 a.add(m.getColumnName(i));
312 ClipboardHelper.setString(TextUtilities.join(TAB, a));
313 } else if (ev.isAnyOf(findColumnName)) {
314 anyActionListener.anyActionPerformed(ev);
315 } else if (ev.isAnyOf(addEmptyRow)) {
316 ResultSetTableModel m = getResultSetTableModel();
317 int[] selectedRows = getSelectedRows();
318 if (selectedRows.length > 0) {
319 final int nextRow = selectedRows[selectedRows.length - 1] + 1;
320 for (int i = 0; i < selectedRows.length; i++) {
321 m.insertUnlinkedRow(nextRow, new Object[m.getColumnCount()]);
324 m.addUnlinkedRow(new Object[m.getColumnCount()]);
326 } else if (ev.isAnyOf(insertFromClipboard)) {
328 Importer importer = new SmartImporter(ClipboardHelper.getReaderForText(), TAB);
330 ResultSetTableModel m = getResultSetTableModel();
332 Object[] row = importer.nextRow();
333 if (row.length == 0) {
336 m.addUnlinkedRow(row);
337 m.linkRow(m.getRowCount() - 1);
339 repaintRowHeader("model");
344 editingCanceled(new ChangeEvent(ev.getSource()));
346 } else if (ev.isAnyOf(duplicateRows)) {
347 ResultSetTableModel m = getResultSetTableModel();
348 List<?> rows = m.getDataVector();
349 int[] selectedRows = getSelectedRows();
350 int index = selectedRows[selectedRows.length - 1];
351 for (int rowIndex : selectedRows) {
352 m.insertUnlinkedRow(++index, (Vector<?>)((Vector<?>)rows.get(rowIndex)).clone());
355 repaintRowHeader("model");
356 } else if (ev.isAnyOf(linkRowsToDatabase)) {
357 ResultSetTableModel m = getResultSetTableModel();
359 for (int rowIndex : getSelectedRows()) {
363 repaintRowHeader("unlinkedRowStatus");
365 } else if (ev.isAnyOf(deleteRows)) {
367 ResultSetTableModel m = getResultSetTableModel();
369 final int selectedRow = getSelectedRow();
370 if (selectedRow < 0) {
373 if (m.isLinkedRow(selectedRow)) {
374 final boolean removed = m.removeLinkedRow(selectedRow);
377 m.removeRow(selectedRow);
381 repaintRowHeader("model");
383 } else if (ev.isAnyOf(adjustColumnWidth)) {
385 } else if (ev.isAnyOf(widenColumnWidth)) {
386 changeTableColumnWidth(1.5f);
387 } else if (ev.isAnyOf(narrowColumnWidth)) {
388 changeTableColumnWidth(1 / 1.5f);
389 } else if (ev.isAnyOf(sort)) {
390 doSort(getTableHeader().columnAtPoint(mousePositionForColumnHeader));
391 } else if (ev.isAnyOf(jumpToColumn)) {
392 Object[] args = ev.getArgs();
393 if (args != null && args.length > 0) {
394 jumpToColumn(String.valueOf(args[0]));
396 } else if (ev.isAnyOf(showColumnNumber)) {
397 setShowColumnNumber(!columnHeaderRenderer.fixesColumnNumber);
400 log.warn("not expected: Event=%s", ev);
405 public void editingStopped(ChangeEvent e) {
407 super.editingStopped(e);
408 } catch (Exception ex) {
409 WindowOutputProcessor.showErrorDialog(getParent(), ex);
414 public boolean editCellAt(int row, int column, EventObject e) {
415 boolean succeeded = super.editCellAt(row, column, e);
417 if (editorComp instanceof JTextField) {
418 // make it selected when starting edit-mode
419 if (lastKeyEvent != null && lastKeyEvent.getKeyCode() != VK_F2) {
420 JTextField editor = (JTextField)editorComp;
421 initializeEditorComponent(editor);
422 editor.requestFocus();
431 public TableCellEditor getCellEditor() {
432 TableCellEditor editor = super.getCellEditor();
433 if (editor instanceof DefaultCellEditor) {
434 DefaultCellEditor d = (DefaultCellEditor)editor;
435 initializeEditorComponent(d.getComponent());
440 private void initializeEditorComponent(Component c) {
441 final Color bgColor = Color.ORANGE;
442 if (c != null && c.getBackground() != bgColor) {
443 // determines initialized state by bgcolor
444 if (!c.isEnabled()) {
447 c.setFont(getFont());
448 c.setBackground(bgColor);
449 if (c instanceof JTextComponent) {
450 final JTextComponent text = (JTextComponent)c;
451 AnyAction aa = new AnyAction(text);
453 c.addFocusListener(new FocusAdapter() {
455 public void focusLost(FocusEvent e) {
456 editingCanceled(new ChangeEvent(e.getSource()));
464 public TableCellRenderer getCellRenderer(int row, int column) {
465 final Object v = getValueAt(row, column);
469 return super.getCellRenderer(row, column);
473 public void updateUI() {
475 adjustRowHeight(this);
478 static void adjustRowHeight(JTable table) {
479 Component c = new JLabel("0");
480 final int height = c.getPreferredSize().height;
482 table.setRowHeight(height);
487 protected void configureEnclosingScrollPane() {
488 super.configureEnclosingScrollPane();
489 Container p = getParent();
490 if (p instanceof JViewport) {
491 Container gp = p.getParent();
492 if (gp instanceof JScrollPane) {
493 JScrollPane scrollPane = (JScrollPane)gp;
494 JViewport viewport = scrollPane.getViewport();
495 if (viewport == null || viewport.getView() != this) {
498 scrollPane.setRowHeaderView(rowHeader);
504 public void setModel(TableModel dataModel) {
505 dataModel.addTableModelListener(rowHeader);
506 super.setModel(dataModel);
511 * @param index0 index of start
512 * @param index1 index of end
514 void selectColumn(int index0, int index1) {
515 if (getRowCount() > 0) {
516 addColumnSelectionInterval(index0, index1);
517 addRowSelectionInterval(getRowCount() - 1, 0);
522 * Jumps to specified column.
524 * @return whether the column exists or not
526 boolean jumpToColumn(int index) {
527 final int columnCount = getColumnCount();
528 if (0 <= index && index < columnCount) {
529 if (getSelectedRowCount() == 0) {
530 changeSelection(-1, index, false, false);
532 int[] selectedRows = getSelectedRows();
533 changeSelection(getSelectedRow(), index, false, false);
534 for (final int selectedRow : selectedRows) {
535 changeSelection(selectedRow, index, false, true);
544 * Jumps to specified column.
546 * @return whether the column exists or not
548 boolean jumpToColumn(String name) {
549 TableColumnModel columnModel = getColumnModel();
550 for (int i = 0, n = columnModel.getColumnCount(); i < n; i++) {
551 if (name.equals(String.valueOf(columnModel.getColumn(i).getHeaderValue()))) {
559 RowHeader getRowHeader() {
563 ResultSetTableModel getResultSetTableModel() {
564 return (ResultSetTableModel)getModel();
567 boolean isShowColumnNumber() {
568 return columnHeaderRenderer.fixesColumnNumber;
571 void setShowColumnNumber(boolean showColumnNumber) {
572 final boolean oldValue = this.columnHeaderRenderer.fixesColumnNumber;
573 this.columnHeaderRenderer.fixesColumnNumber = showColumnNumber;
574 firePropertyChange("showNumber", oldValue, showColumnNumber);
577 void repaintRowHeader(String propName) {
578 if (rowHeader != null) {
579 rowHeader.propertyChange(new PropertyChangeEvent(this, propName, null, null));
583 String getAutoAdjustMode() {
584 return autoAdjustMode;
587 void setAutoAdjustMode(String autoAdjustMode) {
588 final String oldValue = this.autoAdjustMode;
589 this.autoAdjustMode = autoAdjustMode;
590 firePropertyChange("autoAdjustMode", oldValue, autoAdjustMode);
593 private void bindJumpAction(String suffix, int key, boolean withSelect) {
594 final String actionKey = String.format("%s-to-%s", (withSelect) ? "select" : "jump", suffix);
595 final CellCursor c = new CellCursor(this, withSelect);
596 final int modifiers = Utilities.getMenuShortcutKeyMask()
597 | (withSelect ? SHIFT_DOWN_MASK : 0);
598 KeyStroke[] keyStrokes = {getKeyStroke(key, modifiers)};
599 c.putValue(Action.ACTION_COMMAND_KEY, actionKey);
600 InputMap im = this.getInputMap();
601 for (KeyStroke ks : keyStrokes) {
602 im.put(ks, actionKey);
604 this.getActionMap().put(actionKey, c);
607 private static final class CellCursor extends AbstractAction {
609 private final JTable table;
610 private final boolean extend;
612 CellCursor(JTable table, boolean extend) {
614 this.extend = extend;
617 int getColumnPosition() {
618 int[] a = table.getSelectedColumns();
619 if (a == null || a.length == 0) {
622 ListSelectionModel csm = table.getColumnModel().getSelectionModel();
623 return (a[0] == csm.getAnchorSelectionIndex()) ? a[a.length - 1] : a[0];
626 int getRowPosition() {
627 int[] a = table.getSelectedRows();
628 if (a == null || a.length == 0) {
631 ListSelectionModel rsm = table.getSelectionModel();
632 return (a[0] == rsm.getAnchorSelectionIndex()) ? a[a.length - 1] : a[0];
636 public void actionPerformed(ActionEvent e) {
637 final String cmd = e.getActionCommand();
641 assert false : "command is null";
643 } else if (cmd.endsWith("-to-home")) {
646 } else if (cmd.endsWith("-to-end")) {
647 ri = table.getRowCount() - 1;
648 ci = table.getColumnCount() - 1;
649 } else if (cmd.endsWith("-to-top")) {
651 ci = getColumnPosition();
652 } else if (cmd.endsWith("-to-bottom")) {
653 ri = table.getRowCount() - 1;
654 ci = getColumnPosition();
655 } else if (cmd.endsWith("-to-leftmost")) {
656 ri = getRowPosition();
658 } else if (cmd.endsWith("-to-rightmost")) {
659 ri = getRowPosition();
660 ci = table.getColumnCount() - 1;
662 assert false : "unknown command: " + cmd;
665 table.changeSelection(ri, ci, false, extend);
670 private static final class NullValueRenderer extends DefaultTableCellRenderer {
672 NullValueRenderer() {
676 public Component getTableCellRendererComponent(JTable table,
682 Component c = super.getTableCellRendererComponent(table,
688 c.setForeground(new Color(63, 63, 192, 192));
689 Font font = c.getFont();
690 c.setFont(font.deriveFont(font.getSize() * 0.8f));
696 private static final class ColumnHeaderCellRenderer implements TableCellRenderer {
698 TableCellRenderer renderer;
699 boolean fixesColumnNumber;
701 ColumnHeaderCellRenderer(TableCellRenderer renderer) {
702 this.renderer = renderer;
703 this.fixesColumnNumber = false;
707 public Component getTableCellRendererComponent(JTable table,
713 Object o = fixesColumnNumber ? String.format("%d %s", column + 1, value) : value;
714 return renderer.getTableCellRendererComponent(table,
724 private static final class RowHeader extends JTable implements PropertyChangeListener {
726 private static final int DEFAULT_WIDTH = 40;
728 private DefaultTableModel model;
729 private TableCellRenderer renderer;
731 RowHeader(JTable table) {
732 this.model = new DefaultTableModel(0, 1) {
734 public boolean isCellEditable(int row, int column) {
738 final ResultSetTable t = (ResultSetTable)table;
739 this.renderer = new DefaultTableCellRenderer() {
741 public Component getTableCellRendererComponent(JTable table,
747 assert t.getModel() instanceof ResultSetTableModel;
748 final boolean rowLinked = t.getResultSetTableModel().isLinkedRow(row);
749 JLabel label = new JLabel(String.format("%s ", rowLinked ? row + 1 : "+"));
750 label.setHorizontalAlignment(RIGHT);
751 label.setFont(table.getFont());
752 label.setOpaque(true);
759 table.addPropertyChangeListener(this);
763 public void propertyChange(PropertyChangeEvent e) {
764 JTable table = (JTable)e.getSource();
768 String propertyName = e.getPropertyName();
769 if (propertyName.equals("enabled")) {
770 boolean isEnabled = table.isEnabled();
771 setVisible(isEnabled);
774 resetViewPosition(table);
776 } else if (propertyName.equals("font")) {
777 setFont(table.getFont());
778 } else if (propertyName.equals("rowHeight")) {
779 setRowHeight(table.getRowHeight());
780 } else if (propertyName.equals("model")) {
781 model.setRowCount(table.getRowCount());
782 } else if (propertyName.equals("unlinkedRowStatus")) {
784 } else if (propertyName.equals("ancestor")) {
793 public void tableChanged(TableModelEvent e) {
794 Object src = e.getSource();
795 if (model != null && src != null) {
796 model.setRowCount(((TableModel)src).getRowCount());
798 super.tableChanged(e);
802 public void updateUI() {
804 adjustRowHeight(this);
807 void setWidth(JTable table) {
809 final int rowCount = table.getRowCount();
810 model.setRowCount(rowCount);
811 JLabel label = new JLabel(String.valueOf(rowCount * 1000L));
812 Dimension d = getSize();
813 d.width = Math.max(label.getPreferredSize().width, DEFAULT_WIDTH);
814 setPreferredScrollableViewportSize(d);
817 private void resetViewPosition(JTable table) {
818 // forces to reset its view position to table's view position
819 Container p1 = table.getParent();
820 Container p2 = getParent();
821 if (p1 instanceof JViewport && p2 instanceof JViewport) {
822 JViewport v1 = (JViewport)p1;
823 JViewport v2 = (JViewport)p2;
824 v2.setViewPosition(v1.getViewPosition());
829 public boolean isCellEditable(int row, int column) {
834 public TableCellRenderer getCellRenderer(int row, int column) {
843 public boolean search(Matcher matcher) {
844 final int rowCount = getRowCount();
848 final int columnCount = getColumnCount();
849 final boolean backward = matcher.isBackward();
850 final int amount = backward ? -1 : 1;
851 final int rowStart = backward ? rowCount - 1 : 0;
852 final int rowEnd = backward ? 0 : rowCount - 1;
853 final int columnStart = backward ? columnCount - 1 : 0;
854 final int columnEnd = backward ? 0 : columnCount - 1;
856 int column = columnStart;
857 if (getSelectedColumnCount() > 0) {
858 column = getSelectedColumn();
859 row = getSelectedRow() + amount;
869 if (row >= rowCount) {
871 if (column >= columnCount) {
878 final TableModel m = getModel();
879 for (; backward ? column >= columnEnd : column <= columnEnd; column += amount) {
880 for (; backward ? row >= rowEnd : row <= rowEnd; row += amount) {
881 if (matcher.find(String.valueOf(m.getValueAt(row, column)))) {
882 changeSelection(row, column, false, false);
892 public void reset() {
893 ((DefaultTableModel)getModel()).setRowCount(0);
894 lastSortedIndex = -1;
895 lastSortedIsReverse = false;
898 static final class TableHeaderTextSearch implements TextSearch {
899 private ResultSetTable rstable;
900 private JTableHeader tableHeader;
901 TableHeaderTextSearch(ResultSetTable rstable, JTableHeader tableHeader) {
902 this.rstable = rstable;
903 this.tableHeader = tableHeader;
906 public boolean search(Matcher matcher) {
907 TableColumnModel m = tableHeader.getColumnModel();
908 int columnCount = m.getColumnCount();
909 if (columnCount < 1) {
912 final boolean backward = matcher.isBackward();
913 final int amount = backward ? -1 : 1;
914 final int columnStart = backward ? columnCount - 1 : 0;
915 final int columnEnd = backward ? 0 : columnCount - 1;
916 int column = columnStart;
917 if (rstable.getSelectedColumnCount() > 0) {
918 column = rstable.getSelectedColumn() + amount;
920 for (; backward ? column >= columnEnd : column <= columnEnd; column += amount) {
921 if (matcher.find(String.valueOf(m.getColumn(column).getHeaderValue()))) {
922 rstable.jumpToColumn(column);
929 public void reset() {
936 private void setValueAtSelectedCells(Object value) {
937 int[] selectedColumns = getSelectedColumns();
938 for (int rowIndex : getSelectedRows()) {
939 for (int colIndex : selectedColumns) {
940 setValueAt(value, rowIndex, colIndex);
945 private void adjustColumnWidth() {
946 final int rowCount = getRowCount();
947 final boolean byHeader;
948 final boolean byValue;
949 switch (AnyActionKey.of(autoAdjustMode)) {
950 case autoAdjustModeNone:
954 case autoAdjustModeHeader:
958 case autoAdjustModeValue:
962 case autoAdjustModeHeaderAndValue:
967 log.warn("autoAdjustMode=%s", autoAdjustMode);
970 if (!byHeader && rowCount == 0) {
973 final float max = getParent().getWidth() * 0.8f;
974 TableColumnModel columnModel = getColumnModel();
975 JTableHeader header = getTableHeader();
976 for (int columnIndex = 0, n = getColumnCount(); columnIndex < n; columnIndex++) {
979 TableColumn column = columnModel.getColumn(columnIndex);
980 TableCellRenderer renderer = column.getHeaderRenderer();
981 if (renderer == null) {
982 renderer = header.getDefaultRenderer();
984 if (renderer != null) {
985 Component c = renderer.getTableCellRendererComponent(this,
986 column.getHeaderValue(),
991 size = c.getPreferredSize().width * 1.5f;
995 for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
996 TableCellRenderer renderer = getCellRenderer(rowIndex,
998 if (renderer == null) {
1001 Object value = getValueAt(rowIndex, columnIndex);
1002 Component c = renderer.getTableCellRendererComponent(this,
1008 size = Math.max(size, c.getPreferredSize().width);
1014 int width = Math.round(size > max ? max : size) + 1;
1015 columnModel.getColumn(columnIndex).setPreferredWidth(width);
1019 void doSort(int columnIndex) {
1020 if (getColumnCount() == 0) {
1023 final boolean reverse;
1024 if (lastSortedIndex == columnIndex) {
1025 reverse = (lastSortedIsReverse == false);
1027 lastSortedIndex = columnIndex;
1030 lastSortedIsReverse = reverse;
1031 getResultSetTableModel().sort(columnIndex, reverse);
1033 repaintRowHeader("unlinkedRowStatus");
1036 void changeTableColumnWidth(double rate) {
1037 for (TableColumn column : Collections.list(getColumnModel().getColumns())) {
1038 column.setPreferredWidth((int)(column.getWidth() * rate));