001 ///////////////////////////////////////////////// 002 //This file is part of Sears project. 003 //Subtitle Editor And Re-Synch 004 //A tool to easily modify and resynch movies subtitles. 005 ///////////////////////////////////////////////// 006 //This program is free software; 007 //you can redistribute it and/or modify it under the terms 008 //of the GNU General Public License 009 //as published by the Free Software Foundation; 010 //either version 2 of the License, or (at your option) any later version. 011 ///////////////////////////////////////////////// 012 //Sears project is available under sourceforge 013 //at adress: http://sourceforge.net/projects/sears/ 014 //Copyright (C) 2005 Booba Skaya 015 //Mail: booba.skaya@gmail.com 016 ///////////////////////////////////////////////// 017 018 //some suggestions about this class: floriaen@gmail.com 019 020 package sears.search.gui; 021 022 import java.awt.Component; 023 import java.awt.Rectangle; 024 025 import javax.swing.JScrollPane; 026 import javax.swing.JTable; 027 import javax.swing.SwingUtilities; 028 029 /** 030 * Gives method to manipulate table view 031 * [...] 032 * <p> 033 * Scroll to visible a table cell with a better style than 034 * the {@link JTable#scrollRectToVisible(Rectangle)} method 035 *</p> 036 */ 037 public class JTableManipulation { 038 039 private static final int SIZE_DECAY = 20; 040 041 private JTable table; 042 private JScrollPane scrollPane; 043 044 private int lastRow; 045 private int lastColumn; 046 047 /** 048 * Constructs a new <code>JTableManipulation</code> object 049 * @param scrollPane 050 * @throws NullPointerException 051 * @throws IllegalArgumentException 052 */ 053 public JTableManipulation(JScrollPane scrollPane) { 054 if( scrollPane == null ) { 055 throw new NullPointerException("JScrollPane object cannot be null"); 056 } 057 // try to get back view 058 Component view = scrollPane.getViewport().getView(); 059 if( view != null && view instanceof JTable ) { 060 table = (JTable) view; 061 } else { 062 throw new IllegalArgumentException("the JScrollPane object is not associated to a JTable object or this object is null"); 063 } 064 this.scrollPane = scrollPane; 065 resetColumn(); 066 } 067 068 /** 069 * Gets the previous row of <tt>row</tt> 070 * <br>Ensure loop coherence 071 * @param row the row 072 * @return the previous row 073 */ 074 private int getPreviousRow(int row) { 075 if( --row < 0 ) { 076 row = table.getRowCount(); 077 } 078 return row; 079 } 080 081 /** 082 * Gets the next row of <tt>row</tt> 083 * <br>Ensure loop coherence 084 * @param row the row 085 * @return the next row 086 */ 087 private int getNextRow(int row) { 088 if( ++row > table.getRowCount() ) { 089 row = 0; 090 } 091 return row; 092 } 093 094 /** 095 * Reset <tt>lastColumn</tt> 096 */ 097 public void resetColumn() { 098 lastColumn = -1; 099 } 100 101 /** 102 * Scroll to visible a table cell with a better style than 103 * the {@link JTable#scrollRectToVisible(Rectangle)} method. 104 * <br><tt>column</tt> must be coherent and must be the same 105 * that the previous given in parameters of this method. 106 * <br>call {@link #resetColumn()} before ... 107 * @param row the row to display in view 108 * @param column the column 109 * @param backward the direction 110 * @throws IllegalArgumentException if <tt>column</tt> is not the same than the last used <tt>column</tt> 111 */ 112 public void scrollCellToVisible(int row, int column, boolean backward) { 113 if( lastColumn >= 0 && column != lastColumn ) { 114 throw new IllegalArgumentException("Given column " + column + " must be equal to " + lastColumn); 115 } 116 if( row >= 0 && column >= 0 ) { 117 int rowCount = table.getRowCount(); 118 if( row < rowCount && column < table.getColumnCount() ) { 119 Rectangle cell = table.getCellRect(row, column, false); 120 Rectangle convertedCell = SwingUtilities.convertRectangle(scrollPane.getViewport().getView(), cell, scrollPane.getViewport()); 121 Rectangle bounds = scrollPane.getBounds(); 122 // if previous or next cell is not on view 123 if( !bounds.contains(convertedCell) ) { 124 int size = cell.height; 125 int viewSize = scrollPane.getViewport().getHeight(); 126 // condition to loop 127 boolean loop = ( backward && row > lastRow ) || ( !backward && row < lastRow ); 128 while( !loop && size < viewSize - SIZE_DECAY ) { 129 if( backward && ( row-- < getPreviousRow(row) ) ) { 130 loop = true; 131 } 132 if( !backward && ( row++ > getNextRow(row) ) ) { 133 loop = true; 134 } 135 cell = table.getCellRect(row, column, true); 136 size += cell.height; 137 } 138 // display cell in view 139 table.scrollRectToVisible(cell); 140 } 141 } 142 } 143 lastRow = row; 144 lastColumn = column; 145 } 146 }