001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Anton Avtamonov
019: * @version $Revision$
020: */package javax.swing.plaf.basic;
021:
022: import java.awt.Rectangle;
023: import java.awt.event.ActionEvent;
024:
025: import javax.swing.AbstractAction;
026: import javax.swing.DefaultListSelectionModel;
027: import javax.swing.JComponent;
028: import javax.swing.JTable;
029: import javax.swing.ListSelectionModel;
030: import javax.swing.TransferHandler;
031:
032: import org.apache.harmony.x.swing.Utilities;
033:
034: final class BasicTableKeyboardActions {
035: private static abstract class AbstractTableAction extends
036: AbstractAction {
037: public void actionPerformed(final ActionEvent e) {
038: JTable table = (JTable) e.getSource();
039: if (table.getRowCount() == 0 || table.getColumnCount() == 0) {
040: return;
041: }
042:
043: processTable(table);
044: }
045:
046: protected abstract void processTable(final JTable table);
047: }
048:
049: private static abstract class AbstractRowColumnAction extends
050: AbstractTableAction {
051: protected abstract void processRowColumn(final JTable table,
052: final int currentRow, final int currentColumn);
053: }
054:
055: private static abstract class LeadRowColumnAction extends
056: AbstractRowColumnAction {
057: protected void processTable(final JTable table) {
058: if (!stopEditing(table)) {
059: return;
060: }
061: int currentRow = table.getSelectionModel()
062: .getLeadSelectionIndex();
063: int currentColumn = table.getColumnModel()
064: .getSelectionModel().getLeadSelectionIndex();
065: processRowColumn(table, currentRow, currentColumn);
066: }
067:
068: private boolean stopEditing(final JTable table) {
069: if (table.isEditing()) {
070: table.getCellEditor().stopCellEditing();
071: if (table.isEditing()) {
072: return false;
073: }
074: }
075:
076: return true;
077: }
078: }
079:
080: private static abstract class EnablebableLeadRowColumnAction extends
081: LeadRowColumnAction {
082: final JTable table;
083:
084: public EnablebableLeadRowColumnAction(final JTable table) {
085: this .table = table;
086: }
087:
088: public boolean isEnabled() {
089: return isEnabled(table, table.getSelectionModel()
090: .getLeadSelectionIndex(), table.getColumnModel()
091: .getSelectionModel().getLeadSelectionIndex());
092: }
093:
094: public abstract boolean isEnabled(final JTable table,
095: final int currentRow, final int currentColumn);
096: }
097:
098: private static AbstractAction selectNextColumnAction = new LeadRowColumnAction() {
099: protected void processRowColumn(final JTable table,
100: final int currentRow, final int currentColumn) {
101: if (currentColumn + 1 < table.getColumnCount()) {
102: table.changeSelection(currentRow, currentColumn + 1,
103: false, false);
104: }
105: }
106: };
107: private static AbstractAction selectNextColumnChangeLeadAction = new LeadRowColumnAction() {
108: protected void processRowColumn(final JTable table,
109: final int currentRow, final int currentColumn) {
110: if (currentColumn + 1 < table.getColumnCount()
111: && (table.getColumnModel().getSelectionModel() instanceof DefaultListSelectionModel)) {
112: ((DefaultListSelectionModel) table.getColumnModel()
113: .getSelectionModel())
114: .moveLeadSelectionIndex(currentColumn + 1);
115: ensureCellIsVisible(table, currentRow,
116: currentColumn + 1);
117: }
118: }
119: };
120: private static AbstractAction selectPreviousColumnAction = new LeadRowColumnAction() {
121: protected void processRowColumn(final JTable table,
122: final int currentRow, final int currentColumn) {
123: if (currentColumn > 0) {
124: table.changeSelection(currentRow, currentColumn - 1,
125: false, false);
126: }
127: }
128: };
129: private static AbstractAction selectPreviousColumnChangeLeadAction = new LeadRowColumnAction() {
130: protected void processRowColumn(final JTable table,
131: final int currentRow, final int currentColumn) {
132: if (currentColumn > 0
133: && (table.getColumnModel().getSelectionModel() instanceof DefaultListSelectionModel)) {
134: ((DefaultListSelectionModel) table.getColumnModel()
135: .getSelectionModel())
136: .moveLeadSelectionIndex(currentColumn - 1);
137: ensureCellIsVisible(table, currentRow,
138: currentColumn - 1);
139: }
140: }
141: };
142: private static AbstractAction selectNextRowAction = new LeadRowColumnAction() {
143: protected void processRowColumn(final JTable table,
144: final int currentRow, final int currentColumn) {
145: if (currentRow + 1 < table.getRowCount()) {
146: table.changeSelection(currentRow + 1, currentColumn,
147: false, false);
148: }
149: }
150: };
151: private static AbstractAction selectNextRowChangeLeadAction = new LeadRowColumnAction() {
152: protected void processRowColumn(final JTable table,
153: final int currentRow, final int currentColumn) {
154: if (currentRow + 1 < table.getRowCount()
155: && (table.getSelectionModel() instanceof DefaultListSelectionModel)) {
156: ((DefaultListSelectionModel) table.getSelectionModel())
157: .moveLeadSelectionIndex(currentRow + 1);
158: ensureCellIsVisible(table, currentRow + 1,
159: currentColumn);
160: }
161: }
162: };
163: private static AbstractAction selectPreviousRowAction = new LeadRowColumnAction() {
164: protected void processRowColumn(final JTable table,
165: final int currentRow, final int currentColumn) {
166: if (currentRow > 0) {
167: table.changeSelection(currentRow - 1, currentColumn,
168: false, false);
169: }
170: }
171: };
172: private static AbstractAction selectPreviousRowChangeLeadAction = new LeadRowColumnAction() {
173: protected void processRowColumn(final JTable table,
174: final int currentRow, final int currentColumn) {
175: if (currentRow > 0
176: && (table.getSelectionModel() instanceof DefaultListSelectionModel)) {
177: ((DefaultListSelectionModel) table.getSelectionModel())
178: .moveLeadSelectionIndex(currentRow - 1);
179: ensureCellIsVisible(table, currentRow - 1,
180: currentColumn);
181: }
182: }
183: };
184:
185: private static AbstractAction selectNextColumnExtendSelectionAction = new LeadRowColumnAction() {
186: protected void processRowColumn(final JTable table,
187: final int currentRow, final int currentColumn) {
188: if (currentColumn + 1 < table.getColumnCount()) {
189: table.changeSelection(currentRow, currentColumn + 1,
190: false, true);
191: }
192: }
193: };
194: private static AbstractAction selectPreviousColumnExtendSelectionAction = new LeadRowColumnAction() {
195: protected void processRowColumn(final JTable table,
196: final int currentRow, final int currentColumn) {
197: if (currentColumn > 0) {
198: table.changeSelection(currentRow, currentColumn - 1,
199: false, true);
200: }
201: }
202: };
203: private static AbstractAction selectNextRowExtendSelectionAction = new LeadRowColumnAction() {
204: protected void processRowColumn(final JTable table,
205: final int currentRow, final int currentColumn) {
206: if (currentRow + 1 < table.getRowCount()) {
207: table.changeSelection(currentRow + 1, currentColumn,
208: false, true);
209: }
210: }
211: };
212: private static AbstractAction selectPreviousRowExtendSelectionAction = new LeadRowColumnAction() {
213: protected void processRowColumn(final JTable table,
214: final int currentRow, final int currentColumn) {
215: if (currentRow > 0) {
216: table.changeSelection(currentRow - 1, currentColumn,
217: false, true);
218: }
219: }
220: };
221:
222: private static AbstractAction selectFirstColumnAction = new LeadRowColumnAction() {
223: protected void processRowColumn(final JTable table,
224: final int currentRow, final int currentColumn) {
225: table.changeSelection(currentRow, 0, false, false);
226: }
227: };
228: private static AbstractAction selectLastColumnAction = new LeadRowColumnAction() {
229: protected void processRowColumn(final JTable table,
230: final int currentRow, final int currentColumn) {
231: table.changeSelection(currentRow,
232: table.getColumnCount() - 1, false, false);
233: }
234: };
235: private static AbstractAction selectFirstRowAction = new LeadRowColumnAction() {
236: protected void processRowColumn(final JTable table,
237: final int currentRow, final int currentColumn) {
238: table.changeSelection(0, currentColumn, false, false);
239: }
240: };
241: private static AbstractAction selectLastRowAction = new LeadRowColumnAction() {
242: protected void processRowColumn(final JTable table,
243: final int currentRow, final int currentColumn) {
244: table.changeSelection(table.getRowCount() - 1,
245: currentColumn, false, false);
246: }
247: };
248:
249: private static AbstractAction selectFirstColumnExtendSelectionAction = new LeadRowColumnAction() {
250: protected void processRowColumn(final JTable table,
251: final int currentRow, final int currentColumn) {
252: table.changeSelection(currentRow, 0, false, true);
253: }
254: };
255: private static AbstractAction selectLastColumnExtendSelectionAction = new LeadRowColumnAction() {
256: protected void processRowColumn(final JTable table,
257: final int currentRow, final int currentColumn) {
258: table.changeSelection(currentRow,
259: table.getColumnCount() - 1, false, true);
260: }
261: };
262: private static AbstractAction selectFirstRowExtendSelectionAction = new LeadRowColumnAction() {
263: protected void processRowColumn(final JTable table,
264: final int currentRow, final int currentColumn) {
265: table.changeSelection(0, currentColumn, false, true);
266: }
267: };
268: private static AbstractAction selectLastRowExtendSelectionAction = new LeadRowColumnAction() {
269: protected void processRowColumn(final JTable table,
270: final int currentRow, final int currentColumn) {
271: table.changeSelection(table.getRowCount() - 1,
272: currentColumn, false, true);
273: }
274: };
275: private static AbstractAction toggleAndAnchorAction = new LeadRowColumnAction() {
276: protected void processRowColumn(final JTable table,
277: final int currentRow, final int currentColumn) {
278: if (currentRow >= 0 && currentColumn >= 0) {
279: table.changeSelection(currentRow, currentColumn, true,
280: false);
281: table.getSelectionModel().setAnchorSelectionIndex(
282: currentRow);
283: table.getColumnModel().getSelectionModel()
284: .setAnchorSelectionIndex(currentColumn);
285: }
286: }
287: };
288: private static AbstractAction moveSelectionToAction = new LeadRowColumnAction() {
289: protected void processRowColumn(final JTable table,
290: final int currentRow, final int currentColumn) {
291: if (currentRow >= 0 && currentColumn >= 0) {
292: table.changeSelection(currentRow, currentColumn, false,
293: false);
294: }
295: }
296: };
297: private static AbstractAction extendToAction = new LeadRowColumnAction() {
298: protected void processRowColumn(final JTable table,
299: final int currentRow, final int currentColumn) {
300: if (currentRow >= 0 && currentColumn >= 0) {
301: table.changeSelection(currentRow, currentColumn, false,
302: true);
303: }
304: }
305: };
306:
307: private static abstract class SelectRowColumnCellAction extends
308: LeadRowColumnAction {
309: protected abstract int[] nextCellCoords(final int[] cell,
310: final int minRow, final int maxRow,
311: final int minColumn, final int maxColumn);
312:
313: protected void processRowColumn(final JTable table,
314: final int currentRow, final int currentColumn) {
315: ListSelectionModel rowSelectionModel = table
316: .getSelectionModel();
317: ListSelectionModel colSelectionModel = table
318: .getColumnModel().getSelectionModel();
319: if (rowSelectionModel.getMinSelectionIndex() == rowSelectionModel
320: .getMaxSelectionIndex()
321: && colSelectionModel.getMinSelectionIndex() == colSelectionModel
322: .getMaxSelectionIndex()) {
323:
324: int[] currentCell = new int[] { currentRow,
325: currentColumn };
326: currentCell = nextCellCoords(currentCell, 0, table
327: .getRowCount() - 1, 0,
328: table.getColumnCount() - 1);
329: table.changeSelection(currentCell[0], currentCell[1],
330: false, false);
331: } else {
332: int[] currentCell = new int[] { currentRow,
333: currentColumn };
334: int rowMinSelectionIndex;
335: int rowMaxSelectionIndex;
336: int colMinSelectionIndex;
337: int colMaxSelectionIndex;
338:
339: if (table.getRowSelectionAllowed()
340: && table.getColumnSelectionAllowed()) {
341: rowMinSelectionIndex = rowSelectionModel
342: .getMinSelectionIndex();
343: rowMaxSelectionIndex = rowSelectionModel
344: .getMaxSelectionIndex();
345: colMinSelectionIndex = colSelectionModel
346: .getMinSelectionIndex();
347: colMaxSelectionIndex = colSelectionModel
348: .getMaxSelectionIndex();
349: } else if (table.getRowSelectionAllowed()
350: && !table.getColumnSelectionAllowed()) {
351: rowMinSelectionIndex = rowSelectionModel
352: .getMinSelectionIndex();
353: rowMaxSelectionIndex = rowSelectionModel
354: .getMaxSelectionIndex();
355: colMinSelectionIndex = 0;
356: colMaxSelectionIndex = table.getColumnCount() - 1;
357: } else if (!table.getRowSelectionAllowed()
358: && table.getColumnSelectionAllowed()) {
359: rowMinSelectionIndex = 0;
360: rowMaxSelectionIndex = table.getRowCount() - 1;
361: colMinSelectionIndex = colSelectionModel
362: .getMinSelectionIndex();
363: colMaxSelectionIndex = colSelectionModel
364: .getMaxSelectionIndex();
365: } else {
366: rowMinSelectionIndex = 0;
367: rowMaxSelectionIndex = table.getRowCount() - 1;
368: colMinSelectionIndex = 0;
369: colMaxSelectionIndex = table.getColumnCount() - 1;
370: }
371:
372: do {
373: currentCell = nextCellCoords(currentCell,
374: rowMinSelectionIndex, rowMaxSelectionIndex,
375: colMinSelectionIndex, colMaxSelectionIndex);
376:
377: if (!table.getRowSelectionAllowed()
378: && !table.getColumnSelectionAllowed()) {
379: break;
380: }
381: } while (!table.isCellSelected(currentCell[0],
382: currentCell[1]));
383:
384: colSelectionModel.addSelectionInterval(currentCell[1],
385: currentCell[1]);
386: rowSelectionModel.addSelectionInterval(currentCell[0],
387: currentCell[0]);
388: }
389: }
390: }
391:
392: private static AbstractAction selectNextColumnCellAction = new SelectRowColumnCellAction() {
393: protected int[] nextCellCoords(final int[] cell,
394: final int minRow, final int maxRow,
395: final int minColumn, final int maxColumn) {
396: if (cell[1] + 1 <= maxColumn) {
397: cell[1]++;
398: } else {
399: cell[1] = minColumn;
400: if (cell[0] + 1 <= maxRow) {
401: cell[0]++;
402: } else {
403: cell[0] = minRow;
404: }
405: }
406:
407: return cell;
408: }
409: };
410: private static AbstractAction selectPreviousColumnCellAction = new SelectRowColumnCellAction() {
411: protected int[] nextCellCoords(final int[] cell,
412: final int minRow, final int maxRow,
413: final int minColumn, final int maxColumn) {
414: if (cell[1] > minColumn) {
415: cell[1]--;
416: } else {
417: cell[1] = maxColumn;
418: if (cell[0] > minRow) {
419: cell[0]--;
420: } else {
421: cell[0] = maxRow;
422: }
423: }
424:
425: return cell;
426: }
427: };
428: private static AbstractAction selectNextRowCellAction = new SelectRowColumnCellAction() {
429: protected int[] nextCellCoords(final int[] cell,
430: final int minRow, final int maxRow,
431: final int minColumn, final int maxColumn) {
432: if (cell[0] + 1 <= maxRow) {
433: cell[0]++;
434: } else {
435: cell[0] = minRow;
436: if (cell[1] + 1 <= maxColumn) {
437: cell[1]++;
438: } else {
439: cell[1] = minColumn;
440: }
441: }
442:
443: return cell;
444: }
445: };
446: private static AbstractAction selectPreviousRowCellAction = new SelectRowColumnCellAction() {
447: protected int[] nextCellCoords(final int[] cell,
448: final int minRow, final int maxRow,
449: final int minColumn, final int maxColumn) {
450: if (cell[0] > minRow) {
451: cell[0]--;
452: } else {
453: cell[0] = maxRow;
454: if (cell[1] > minColumn) {
455: cell[1]--;
456: } else {
457: cell[1] = maxColumn;
458: }
459: }
460:
461: return cell;
462: }
463: };
464:
465: private static AbstractAction selectAllAction = new AbstractTableAction() {
466: protected void processTable(final JTable table) {
467: if (table.isEditing()) {
468: table.getCellEditor().cancelCellEditing();
469: }
470: table.selectAll();
471: }
472: };
473: private static AbstractAction clearSelectionAction = new AbstractTableAction() {
474: protected void processTable(final JTable table) {
475: if (table.isEditing()) {
476: table.getCellEditor().cancelCellEditing();
477: }
478: table.clearSelection();
479: }
480: };
481:
482: private static AbstractAction startEditingAction = new LeadRowColumnAction() {
483: protected void processRowColumn(final JTable table,
484: final int currentRow, final int currentColumn) {
485: if (table.isEditing()) {
486: table.getCellEditor().stopCellEditing();
487: } else if (table.editCellAt(currentRow, currentColumn)) {
488: table.getEditorComponent().requestFocus();
489: }
490: }
491: };
492: private static AbstractAction cancelAction = new AbstractTableAction() {
493: protected void processTable(final JTable table) {
494: if (table.isEditing()) {
495: table.getCellEditor().cancelCellEditing();
496: }
497: }
498: };
499:
500: private static AbstractAction scrollUpChangeSelectionAction = new LeadRowColumnAction() {
501: protected void processRowColumn(final JTable table,
502: final int currentRow, final int currentColumn) {
503: int scrollUpIndex = getScrollUpIndex(table);
504: if (scrollUpIndex > 0) {
505: table.changeSelection(scrollUpIndex, currentColumn,
506: false, false);
507: } else {
508: table.changeSelection(0, currentColumn, false, false);
509: }
510: }
511: };
512: private static AbstractAction scrollDownChangeSelectionAction = new LeadRowColumnAction() {
513: protected void processRowColumn(final JTable table,
514: final int currentRow, final int currentColumn) {
515: int scrollDownIndex = getScrollDownIndex(table);
516: if (scrollDownIndex < table.getRowCount()) {
517: table.changeSelection(scrollDownIndex, currentColumn,
518: false, false);
519: } else {
520: table.changeSelection(table.getRowCount() - 1,
521: currentColumn, false, false);
522: }
523: }
524: };
525: private static AbstractAction scrollRightChangeSelectionAction = new LeadRowColumnAction() {
526: protected void processRowColumn(final JTable table,
527: final int currentRow, final int currentColumn) {
528: int scrollRightIndex = getScrollRightIndex(table);
529: if (scrollRightIndex < table.getColumnCount()) {
530: table.changeSelection(currentRow, scrollRightIndex,
531: false, false);
532: } else {
533: table.changeSelection(currentRow, table
534: .getColumnCount() - 1, false, false);
535: }
536: }
537: };
538: private static AbstractAction scrollLeftChangeSelectionAction = new LeadRowColumnAction() {
539: protected void processRowColumn(final JTable table,
540: final int currentRow, final int currentColumn) {
541: int scrollLeftIndex = getScrollLeftIndex(table);
542: if (scrollLeftIndex > 0) {
543: table.changeSelection(currentRow, scrollLeftIndex,
544: false, false);
545: } else {
546: table.changeSelection(currentRow, 0, false, false);
547: }
548: }
549: };
550:
551: private static AbstractAction scrollUpExtendSelectionAction = new LeadRowColumnAction() {
552: protected void processRowColumn(final JTable table,
553: final int currentRow, final int currentColumn) {
554: int scrollUpIndex = getScrollUpIndex(table);
555: System.err.println("scrollup: " + scrollUpIndex);
556: if (scrollUpIndex > 0) {
557: table.changeSelection(scrollUpIndex, currentColumn,
558: false, true);
559: } else {
560: table.changeSelection(0, currentColumn, false, true);
561: }
562: }
563: };
564: private static AbstractAction scrollDownExtendSelectionAction = new LeadRowColumnAction() {
565: protected void processRowColumn(final JTable table,
566: final int currentRow, final int currentColumn) {
567: int scrollDownIndex = getScrollDownIndex(table);
568: if (scrollDownIndex < table.getRowCount()) {
569: table.changeSelection(scrollDownIndex, currentColumn,
570: false, true);
571: } else {
572: table.changeSelection(table.getRowCount() - 1,
573: currentColumn, false, true);
574: }
575: }
576: };
577: private static AbstractAction scrollRightExtendSelectionAction = new LeadRowColumnAction() {
578: protected void processRowColumn(final JTable table,
579: final int currentRow, final int currentColumn) {
580: int scrollRightIndex = getScrollRightIndex(table);
581: if (scrollRightIndex < table.getColumnCount()) {
582: table.changeSelection(currentRow, scrollRightIndex,
583: false, true);
584: } else {
585: table.changeSelection(currentRow, table
586: .getColumnCount() - 1, false, true);
587: }
588: }
589: };
590: private static AbstractAction scrollLeftExtendSelectionAction = new LeadRowColumnAction() {
591: protected void processRowColumn(final JTable table,
592: final int currentRow, final int currentColumn) {
593: int scrollLeftIndex = getScrollLeftIndex(table);
594: if (scrollLeftIndex > 0) {
595: table.changeSelection(currentRow, scrollLeftIndex,
596: false, true);
597: } else {
598: table.changeSelection(currentRow, 0, false, true);
599: }
600: }
601: };
602:
603: public static void installKeyboardActions(final JTable table) {
604: Utilities.installKeyboardActions(table,
605: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
606: "Table.ancestorInputMap",
607: "Table.ancestorInputMap.RightToLeft");
608:
609: table.getActionMap().put("copy",
610: TransferHandler.getCopyAction());
611: table.getActionMap().put("paste",
612: TransferHandler.getPasteAction());
613: table.getActionMap().put("cut", TransferHandler.getCutAction());
614:
615: table.getActionMap().put("selectNextColumn",
616: selectNextColumnAction);
617: table.getActionMap().put("selectPreviousColumn",
618: selectPreviousColumnAction);
619: table.getActionMap().put("selectNextRow", selectNextRowAction);
620: table.getActionMap().put("selectPreviousRow",
621: selectPreviousRowAction);
622:
623: table.getActionMap().put("selectPreviousRowChangeLead",
624: selectPreviousRowChangeLeadAction);
625: table.getActionMap().put("selectNextRowChangeLead",
626: selectNextRowChangeLeadAction);
627: table.getActionMap().put("selectPreviousColumnChangeLead",
628: selectPreviousColumnChangeLeadAction);
629: table.getActionMap().put("selectNextColumnChangeLead",
630: selectNextColumnChangeLeadAction);
631:
632: table.getActionMap().put("selectNextColumnExtendSelection",
633: selectNextColumnExtendSelectionAction);
634: table.getActionMap().put("selectPreviousColumnExtendSelection",
635: selectPreviousColumnExtendSelectionAction);
636: table.getActionMap().put("selectNextRowExtendSelection",
637: selectNextRowExtendSelectionAction);
638: table.getActionMap().put("selectPreviousRowExtendSelection",
639: selectPreviousRowExtendSelectionAction);
640:
641: table.getActionMap().put("scrollUpChangeSelection",
642: scrollUpChangeSelectionAction);
643: table.getActionMap().put("scrollDownChangeSelection",
644: scrollDownChangeSelectionAction);
645: table.getActionMap().put("scrollUpExtendSelection",
646: scrollUpExtendSelectionAction);
647: table.getActionMap().put("scrollDownExtendSelection",
648: scrollDownExtendSelectionAction);
649: table.getActionMap().put("scrollLeftChangeSelection",
650: scrollLeftChangeSelectionAction);
651: table.getActionMap().put("scrollRightChangeSelection",
652: scrollRightChangeSelectionAction);
653: table.getActionMap().put("scrollLeftExtendSelection",
654: scrollLeftExtendSelectionAction);
655: table.getActionMap().put("scrollRightExtendSelection",
656: scrollRightExtendSelectionAction);
657:
658: table.getActionMap().put("selectFirstColumn",
659: selectFirstColumnAction);
660: table.getActionMap().put("selectLastColumn",
661: selectLastColumnAction);
662: table.getActionMap()
663: .put("selectFirstRow", selectFirstRowAction);
664: table.getActionMap().put("selectLastRow", selectLastRowAction);
665:
666: table.getActionMap().put("selectFirstColumnExtendSelection",
667: selectFirstColumnExtendSelectionAction);
668: table.getActionMap().put("selectLastColumnExtendSelection",
669: selectLastColumnExtendSelectionAction);
670: table.getActionMap().put("selectFirstRowExtendSelection",
671: selectFirstRowExtendSelectionAction);
672: table.getActionMap().put("selectLastRowExtendSelection",
673: selectLastRowExtendSelectionAction);
674:
675: table.getActionMap().put("selectNextColumnCell",
676: selectNextColumnCellAction);
677: table.getActionMap().put("selectPreviousColumnCell",
678: selectPreviousColumnCellAction);
679: table.getActionMap().put("selectNextRowCell",
680: selectNextRowCellAction);
681: table.getActionMap().put("selectPreviousRowCell",
682: selectPreviousRowCellAction);
683:
684: table.getActionMap().put("selectAll", selectAllAction);
685: table.getActionMap()
686: .put("clearSelection", clearSelectionAction);
687:
688: table.getActionMap().put("addToSelection",
689: new EnablebableLeadRowColumnAction(table) {
690: protected void processRowColumn(final JTable table,
691: final int currentRow,
692: final int currentColumn) {
693: if (currentRow >= 0 && currentColumn >= 0) {
694: table.addRowSelectionInterval(currentRow,
695: currentRow);
696: table.addColumnSelectionInterval(
697: currentColumn, currentColumn);
698: }
699: }
700:
701: public boolean isEnabled(final JTable table,
702: final int currentRow,
703: final int currentColumn) {
704: return !table.isCellSelected(currentRow,
705: currentColumn);
706: }
707: });
708:
709: table.getActionMap().put("toggleAndAnchor",
710: toggleAndAnchorAction);
711: table.getActionMap().put("moveSelectionTo",
712: moveSelectionToAction);
713: table.getActionMap().put("extendTo", extendToAction);
714:
715: table.getActionMap().put("startEditing", startEditingAction);
716: table.getActionMap().put("cancel", cancelAction);
717: }
718:
719: public static void uninstallKeyboardActions(final JTable table) {
720: Utilities.uninstallKeyboardActions(table,
721: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
722: }
723:
724: private static int getFirstVisibleTableRowIndex(final JTable table) {
725: Rectangle visibleRect = table.getVisibleRect();
726: if (visibleRect.isEmpty()) {
727: return -1;
728: }
729:
730: int currentColumn = table.getColumnModel().getSelectionModel()
731: .getAnchorSelectionIndex();
732:
733: for (int i = 0; i < table.getRowCount(); i++) {
734: Rectangle bounds = table
735: .getCellRect(i, currentColumn, true);
736: if (bounds.intersects(visibleRect)) {
737: return i;
738: }
739: }
740:
741: return -1;
742: }
743:
744: private static int getLastVisibleTableRowIndex(final JTable table) {
745: Rectangle visibleRect = table.getVisibleRect();
746: if (visibleRect.isEmpty()) {
747: return -1;
748: }
749:
750: int currentColumn = table.getColumnModel().getSelectionModel()
751: .getAnchorSelectionIndex();
752:
753: for (int i = table.getRowCount() - 1; i >= 0; i--) {
754: Rectangle bounds = table
755: .getCellRect(i, currentColumn, true);
756: if (bounds.intersects(visibleRect)) {
757: return i;
758: }
759: }
760:
761: return -1;
762: }
763:
764: private static int getRightmostVisibleTableRowIndex(
765: final JTable table) {
766: Rectangle visibleRect = table.getVisibleRect();
767: if (visibleRect.isEmpty()) {
768: return -1;
769: }
770:
771: int currentRow = table.getSelectionModel()
772: .getAnchorSelectionIndex();
773:
774: for (int i = table.getColumnCount() - 1; i >= 0; i--) {
775: Rectangle bounds = table.getCellRect(currentRow, i, true);
776: if (bounds.intersects(visibleRect)) {
777: return i;
778: }
779: }
780:
781: return -1;
782: }
783:
784: private static int getLeftmostVisibleTableRowIndex(
785: final JTable table) {
786: Rectangle visibleRect = table.getVisibleRect();
787: if (visibleRect.isEmpty()) {
788: return -1;
789: }
790:
791: int currentRow = table.getSelectionModel()
792: .getAnchorSelectionIndex();
793:
794: for (int i = 0; i < table.getColumnCount(); i++) {
795: Rectangle bounds = table.getCellRect(currentRow, i, true);
796: if (bounds.intersects(visibleRect)) {
797: return i;
798: }
799: }
800:
801: return -1;
802: }
803:
804: private static int getScrollDownIndex(final JTable table) {
805: if (table.getRowCount() == 0) {
806: return -1;
807: }
808:
809: int currentSelection = table.getSelectionModel()
810: .getLeadSelectionIndex();
811: int lastVisible = getLastVisibleTableRowIndex(table);
812: if (lastVisible != currentSelection
813: || lastVisible == table.getRowCount() - 1) {
814: return lastVisible;
815: } else {
816: Rectangle visibleRect = table.getVisibleRect();
817: int currentColumn = table.getColumnModel()
818: .getSelectionModel().getLeadSelectionIndex();
819: int i = lastVisible + 1;
820: int cellsHeight = table.getCellRect(i, currentColumn, true).height;
821: while (i < table.getRowCount() - 1
822: && cellsHeight < visibleRect.height) {
823: i++;
824: cellsHeight += table
825: .getCellRect(i, currentColumn, true).height;
826: }
827:
828: return i;
829: }
830: }
831:
832: private static int getScrollUpIndex(final JTable table) {
833: if (table.getRowCount() == 0) {
834: return -1;
835: }
836:
837: int currentSelection = table.getSelectionModel()
838: .getLeadSelectionIndex();
839: int firstVisible = getFirstVisibleTableRowIndex(table);
840: if (firstVisible != currentSelection
841: || firstVisible == table.getRowCount() - 1) {
842: return firstVisible;
843: } else {
844: Rectangle visibleRect = table.getVisibleRect();
845: int currentColumn = table.getColumnModel()
846: .getSelectionModel().getLeadSelectionIndex();
847: int i = firstVisible - 1;
848: int cellsHeight = table.getCellRect(i, currentColumn, true).height;
849: while (i > 0 && cellsHeight < visibleRect.height) {
850: i--;
851: cellsHeight += table
852: .getCellRect(i, currentColumn, true).height;
853: }
854:
855: return i;
856: }
857: }
858:
859: private static int getScrollRightIndex(final JTable table) {
860: if (table.getColumnCount() == 0) {
861: return -1;
862: }
863:
864: int currentSelection = table.getColumnModel()
865: .getSelectionModel().getLeadSelectionIndex();
866: int lastVisible = getRightmostVisibleTableRowIndex(table);
867: if (lastVisible != currentSelection
868: || lastVisible == table.getColumnCount() - 1) {
869: return lastVisible;
870: } else {
871: Rectangle visibleRect = table.getVisibleRect();
872: int currentRow = table.getSelectionModel()
873: .getLeadSelectionIndex();
874: int i = lastVisible + 1;
875: int cellsWidth = table.getCellRect(currentRow, i, true).width;
876: while (i < table.getColumnCount() - 1
877: && cellsWidth < visibleRect.width) {
878: i++;
879: cellsWidth += table.getCellRect(currentRow, i, true).width;
880: }
881:
882: return i;
883: }
884: }
885:
886: private static int getScrollLeftIndex(final JTable table) {
887: if (table.getRowCount() == 0) {
888: return -1;
889: }
890:
891: int currentSelection = table.getColumnModel()
892: .getSelectionModel().getLeadSelectionIndex();
893: int firstVisible = getLeftmostVisibleTableRowIndex(table);
894: if (firstVisible != currentSelection
895: || firstVisible == table.getColumnCount() - 1) {
896: return firstVisible;
897: } else {
898: Rectangle visibleRect = table.getVisibleRect();
899: int currentRow = table.getSelectionModel()
900: .getLeadSelectionIndex();
901: int i = firstVisible - 1;
902: int cellsWidth = table.getCellRect(currentRow, i, true).width;
903: while (i > 0 && cellsWidth < visibleRect.width) {
904: i--;
905: cellsWidth += table.getCellRect(currentRow, i, true).width;
906: }
907:
908: return i;
909: }
910: }
911:
912: private static void ensureCellIsVisible(final JTable table,
913: final int row, final int column) {
914: table.scrollRectToVisible(table.getCellRect(row, column, true));
915: }
916: }
|