src/de/matthiasmann/twl/TableRowSelectionManager.java
author Matthias Mann
Sat Feb 27 00:44:50 2010 +0100 (23 months ago)
changeset 430 1f2f1bb2f52a
child 524 60ac686461b3
permissions -rw-r--r--
ActionMap: added javadoc, support for static handler methods
Widget: javadoc for action map methods
     1 /*
     2  * Copyright (c) 2008-2009, Matthias Mann
     3  *
     4  * All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions are met:
     8  *
     9  *     * Redistributions of source code must retain the above copyright notice,
    10  *       this list of conditions and the following disclaimer.
    11  *     * Redistributions in binary form must reproduce the above copyright
    12  *       notice, this list of conditions and the following disclaimer in the
    13  *       documentation and/or other materials provided with the distribution.
    14  *     * Neither the name of Matthias Mann nor the names of its contributors may
    15  *       be used to endorse or promote products derived from this software
    16  *       without specific prior written permission.
    17  *
    18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    25  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    26  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    27  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    29  */
    30 package de.matthiasmann.twl;
    31 
    32 import de.matthiasmann.twl.model.DefaultTableSelectionModel;
    33 import de.matthiasmann.twl.model.TableSelectionModel;
    34 
    35 /**
    36  *
    37  * @author Matthias Mann
    38  */
    39 public class TableRowSelectionManager implements TableSelectionManager {
    40 
    41     protected final ActionMap actionMap;
    42     protected final TableSelectionModel selectionModel;
    43 
    44     protected TableBase tableBase;
    45 
    46     public TableRowSelectionManager(TableSelectionModel selectionModel) {
    47         if(selectionModel == null) {
    48             throw new NullPointerException("selectionModel");
    49         }
    50         this.selectionModel = selectionModel;
    51         this.actionMap = new ActionMap();
    52 
    53         actionMap.addMapping(this);
    54     }
    55 
    56     public TableRowSelectionManager() {
    57         this(new DefaultTableSelectionModel());
    58     }
    59 
    60     public void setAssociatedTable(TableBase base) {
    61         if(tableBase != base) {
    62             if(tableBase != null && base != null) {
    63                 throw new IllegalStateException("selection manager still in use");
    64             }
    65             this.tableBase = base;
    66             modelChanged();
    67         }
    68     }
    69 
    70     public SelectionGranularity getSelectionGranularity() {
    71         return SelectionGranularity.ROWS;
    72     }
    73 
    74     public boolean handleKeyStrokeAction(String action, Event event) {
    75         return actionMap.invoke(action, event);
    76     }
    77 
    78     public boolean handleMouseEvent(int row, int column, Event event) {
    79         if(event.getType() == Event.Type.MOUSE_BTNDOWN && event.getMouseButton() == Event.MOUSE_LBUTTON) {
    80             boolean isShift = (event.getModifiers() & Event.MODIFIER_SHIFT) != 0;
    81             boolean isCtrl = (event.getModifiers() & Event.MODIFIER_CTRL) != 0;
    82             handleMouseClick(row, column, isShift, isCtrl);
    83             return true;
    84         }
    85         return false;
    86     }
    87 
    88     public boolean isRowSelected(int row) {
    89         return selectionModel.isSelected(row);
    90     }
    91 
    92     public boolean isCellSelected(int row, int column) {
    93         return false;
    94     }
    95 
    96     public int getLeadRow() {
    97         return selectionModel.getLeadIndex();
    98     }
    99 
   100     public int getLeadColumn() {
   101         return -1;
   102     }
   103 
   104     public void modelChanged() {
   105         selectionModel.clearSelection();
   106         selectionModel.setAnchorIndex(-1);
   107         selectionModel.setLeadIndex(-1);
   108     }
   109 
   110     public void rowsInserted(int index, int count) {
   111         selectionModel.rowsInserted(index, count);
   112     }
   113 
   114     public void rowsDeleted(int index, int count) {
   115         selectionModel.rowsDeleted(index, count);
   116     }
   117 
   118     public void columnInserted(int index, int count) {
   119     }
   120 
   121     public void columnsDeleted(int index, int count) {
   122     }
   123 
   124     @ActionMap.Action
   125     public void selectNextRow() {
   126         handleRelativeAction(1, SET);
   127     }
   128 
   129     @ActionMap.Action
   130     public void selectPreviousRow() {
   131         handleRelativeAction(-1, SET);
   132     }
   133 
   134     @ActionMap.Action
   135     public void selectNextPage() {
   136         handleRelativeAction(getPageSize(), SET);
   137     }
   138 
   139     @ActionMap.Action
   140     public void selectPreviousPage() {
   141         handleRelativeAction(-getPageSize(), SET);
   142     }
   143 
   144     @ActionMap.Action
   145     public void selectFirstRow() {
   146         int numRows = getNumRows();
   147         if(numRows > 0) {
   148             handleAbsoluteAction(0, SET);
   149         }
   150     }
   151 
   152     @ActionMap.Action
   153     public void selectLastRow() {
   154         int numRows = getNumRows();
   155         if(numRows > 0) {
   156             handleRelativeAction(numRows-1, SET);
   157         }
   158     }
   159 
   160     @ActionMap.Action
   161     public void extendSelectionToNextRow() {
   162         handleRelativeAction(1, EXTEND);
   163     }
   164 
   165     @ActionMap.Action
   166     public void extendSelectionToPreviousRow() {
   167         handleRelativeAction(-1, EXTEND);
   168     }
   169 
   170     @ActionMap.Action
   171     public void extendSelectionToNextPage() {
   172         handleRelativeAction(getPageSize(), EXTEND);
   173     }
   174 
   175     @ActionMap.Action
   176     public void extendSelectionToPreviousPage() {
   177         handleRelativeAction(-getPageSize(), EXTEND);
   178     }
   179 
   180     @ActionMap.Action
   181     public void extendSelectionToFirstRow() {
   182         int numRows = getNumRows();
   183         if(numRows > 0) {
   184             handleAbsoluteAction(0, EXTEND);
   185         }
   186     }
   187 
   188     @ActionMap.Action
   189     public void extendSelectionToLastRow() {
   190         int numRows = getNumRows();
   191         if(numRows > 0) {
   192             handleRelativeAction(numRows-1, EXTEND);
   193         }
   194     }
   195 
   196     @ActionMap.Action
   197     public void moveLeadToNextRow() {
   198         handleRelativeAction(1, MOVE);
   199     }
   200 
   201     @ActionMap.Action
   202     public void moveLeadToPreviousRow() {
   203         handleRelativeAction(-1, MOVE);
   204     }
   205 
   206     @ActionMap.Action
   207     public void moveLeadToNextPage() {
   208         handleRelativeAction(getPageSize(), MOVE);
   209     }
   210 
   211     @ActionMap.Action
   212     public void moveLeadToPreviousPage() {
   213         handleRelativeAction(-getPageSize(), MOVE);
   214     }
   215 
   216     @ActionMap.Action
   217     public void moveLeadToFirstRow() {
   218         int numRows = getNumRows();
   219         if(numRows > 0) {
   220             handleAbsoluteAction(0, MOVE);
   221         }
   222     }
   223 
   224     @ActionMap.Action
   225     public void moveLeadToLastRow() {
   226         int numRows = getNumRows();
   227         if(numRows > 0) {
   228             handleAbsoluteAction(numRows-1, MOVE);
   229         }
   230     }
   231 
   232     @ActionMap.Action
   233     public void toggleSelectionOnLeadRow() {
   234         int leadIndex = selectionModel.getLeadIndex();
   235         if(leadIndex > 0) {
   236             selectionModel.invertSelection(leadIndex, leadIndex);
   237         }
   238     }
   239 
   240     @ActionMap.Action
   241     public void selectAll() {
   242         int numRows = getNumRows();
   243         if(numRows > 0) {
   244             selectionModel.setSelection(0, numRows-1);
   245         }
   246     }
   247 
   248     @ActionMap.Action
   249     public void selectNone() {
   250         selectionModel.clearSelection();
   251     }
   252 
   253     protected static final int TOGGLE = 0;
   254     protected static final int EXTEND = 1;
   255     protected static final int SET = 2;
   256     protected static final int MOVE = 3;
   257 
   258     protected void handleRelativeAction(int delta, int mode) {
   259         int numRows = getNumRows();
   260         if(numRows > 0) {
   261             int leadIndex = Math.max(0, selectionModel.getLeadIndex());
   262             int index = Math.max(0, Math.min(numRows-1, leadIndex + delta));
   263 
   264             handleAbsoluteAction(index, mode);
   265         }
   266     }
   267 
   268     protected void handleAbsoluteAction(int index, int mode) {
   269         if(tableBase != null) {
   270             tableBase.adjustScrollPosition(index);
   271         }
   272 
   273         switch (mode) {
   274             case MOVE:
   275                 selectionModel.setLeadIndex(index);
   276                 break;
   277             case EXTEND:
   278                 int anchorIndex = Math.max(0, selectionModel.getAnchorIndex());
   279                 selectionModel.setSelection(anchorIndex, index);
   280                 break;
   281             case TOGGLE:
   282                 selectionModel.invertSelection(index, index);
   283                 break;
   284             default:
   285                 selectionModel.setSelection(index, index);
   286                 break;
   287         }
   288     }
   289 
   290     protected void handleMouseClick(int row, int column, boolean isShift, boolean isCtrl) {
   291         if(row < 0) {
   292             if(!isShift) {
   293                 selectionModel.clearSelection();
   294             }
   295         } else {
   296             tableBase.adjustScrollPosition(row);
   297             int anchorIndex = selectionModel.getAnchorIndex();
   298             boolean anchorSelected;
   299             if(anchorIndex == -1) {
   300                 anchorIndex = 0;
   301                 anchorSelected = false;
   302             } else {
   303                 anchorSelected = selectionModel.isSelected(anchorIndex);
   304             }
   305 
   306             if(isCtrl) {
   307                 if(isShift) {
   308                     if(anchorSelected) {
   309                         selectionModel.addSelection(anchorIndex, row);
   310                     } else {
   311                         selectionModel.removeSelection(anchorIndex, row);
   312                     }
   313                 } else if(selectionModel.isSelected(row)) {
   314                     selectionModel.removeSelection(row, row);
   315                 } else {
   316                     selectionModel.addSelection(row, row);
   317                 }
   318             } else if(isShift) {
   319                 selectionModel.setSelection(anchorIndex, row);
   320             } else {
   321                 selectionModel.setSelection(row, row);
   322             }
   323         }
   324     }
   325 
   326     protected int getNumRows() {
   327         if(tableBase != null) {
   328             return tableBase.getNumRows();
   329         }
   330         return 0;
   331     }
   332 
   333     protected int getPageSize() {
   334         if(tableBase != null) {
   335             return Math.max(1, tableBase.getNumVisibleRows());
   336         }
   337         return 1;
   338     }
   339 }