001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.util; 003 004import javax.swing.ListSelectionModel; 005import javax.swing.table.TableModel; 006 007import org.openstreetmap.josm.data.ReorderableModel; 008 009/** 010 * Defines a table model that can be reordered. 011 * @param <T> item type 012 * @since 15226 013 */ 014public interface ReorderableTableModel<T> extends TableModel, ReorderableModel<T> { 015 016 /** 017 * Returns the selection model. 018 * @return the selection model (never null) 019 */ 020 ListSelectionModel getSelectionModel(); 021 022 /** 023 * Returns an array of all of the selected indices in the selection model, in increasing order. 024 * @return an array of all of the selected indices in the selection model, in increasing order 025 */ 026 default int[] getSelectedIndices() { 027 return TableHelper.getSelectedIndices(getSelectionModel()); 028 } 029 030 /** 031 * Checks that the currently selected range of rows can be moved by a number of positions. 032 * @param delta negative or positive delta 033 * @return {@code true} if rows can be moved 034 */ 035 default boolean canMove(int delta) { 036 return canMove(delta, this::getRowCount, getSelectedIndices()); 037 } 038 039 /** 040 * Checks that the currently selected range of rows can be moved up. 041 * @return {@code true} if rows can be moved up 042 */ 043 default boolean canMoveUp() { 044 return canMoveUp(getSelectedIndices()); 045 } 046 047 /** 048 * Checks that a range of rows can be moved up. 049 * @param rows indexes of rows to move up 050 * @return {@code true} if rows can be moved up 051 */ 052 default boolean canMoveUp(int... rows) { 053 return canMoveUp(this::getRowCount, rows); 054 } 055 056 /** 057 * Checks that the currently selected range of rows can be moved down. 058 * @return {@code true} if rows can be moved down 059 */ 060 default boolean canMoveDown() { 061 return canMoveDown(getSelectedIndices()); 062 } 063 064 /** 065 * Checks that a range of rows can be moved down. 066 * @param rows indexes of rows to move down 067 * @return {@code true} if rows can be moved down 068 */ 069 default boolean canMoveDown(int... rows) { 070 return canMoveDown(this::getRowCount, rows); 071 } 072 073 /** 074 * Move up selected rows, if possible. 075 * @return {@code true} if the move was performed 076 * @see #canMoveUp 077 */ 078 default boolean moveUp() { 079 return moveUp(getSelectedIndices()); 080 } 081 082 /** 083 * Move up selected rows, if possible. 084 * @param selectedRows rows to move up 085 * @return {@code true} if the move was performed 086 * @see #canMoveUp 087 */ 088 default boolean moveUp(int... selectedRows) { 089 return move(-1, selectedRows); 090 } 091 092 /** 093 * Move down selected rows, if possible. 094 * @return {@code true} if the move was performed 095 * @see #canMoveDown 096 */ 097 default boolean moveDown() { 098 return moveDown(getSelectedIndices()); 099 } 100 101 /** 102 * Move down selected rows by 1 position, if possible. 103 * @param selectedRows rows to move down 104 * @return {@code true} if the move was performed 105 * @see #canMoveDown 106 */ 107 default boolean moveDown(int... selectedRows) { 108 return move(1, selectedRows); 109 } 110 111 /** 112 * Move selected rows by any number of positions, if possible. 113 * @param delta negative or positive delta 114 * @param selectedRows rows to move 115 * @return {@code true} if the move was performed 116 * @see #canMove 117 */ 118 default boolean move(int delta, int... selectedRows) { 119 if (!canMove(delta, this::getRowCount, selectedRows)) 120 return false; 121 if (!doMove(delta, selectedRows)) 122 return false; 123 final ListSelectionModel selectionModel = getSelectionModel(); 124 selectionModel.setValueIsAdjusting(true); 125 selectionModel.clearSelection(); 126 for (int row: selectedRows) { 127 selectionModel.addSelectionInterval(row + delta, row + delta); 128 } 129 selectionModel.setValueIsAdjusting(false); 130 return true; 131 } 132}