| 1 | // Copyright © 2004-2006 University of Helsinki, Department of Computer Science | |
| 2 | // Copyright © 2012 various contributors | |
| 3 | // This software is released under GNU Lesser General Public License 2.1. | |
| 4 | // The license text is at http://www.gnu.org/licenses/lgpl-2.1.html | |
| 5 | ||
| 6 | package fi.helsinki.cs.titokone; | |
| 7 | ||
| 8 | import javax.swing.*; | |
| 9 | import javax.swing.table.*; | |
| 10 | import java.awt.*; | |
| 11 | import java.awt.event.MouseEvent; | |
| 12 | import java.util.logging.Logger; | |
| 13 | ||
| 14 | /** | |
| 15 | * This class is basically just normal JTable with added functionality. | |
| 16 | */ | |
| 17 | public class JTableX extends JTable { | |
| 18 | ||
| 19 | ||
| 20 | //protected int selectedRow; | |
| 21 | 7 | protected int[] selectedRows = {0}; |
| 22 | 3 | protected boolean areRowsSelected = false; |
| 23 | 3 | protected int tryCounter = 0; |
| 24 | protected String[] columnToolTips; | |
| 25 | ||
| 26 | ||
| 27 | public JTableX(TableModel dm) { | |
| 28 | super(dm); | |
| 29 | 2 | columnToolTips = new String[getColumnCount()]; |
| 30 | } | |
| 31 | ||
| 32 | ||
| 33 | public void setToolTipTextForColumns(String[] toolTips) { | |
| 34 | 1 | columnToolTips = toolTips; |
| 35 | } | |
| 36 | ||
| 37 | ||
| 38 | public String getToolTipText(MouseEvent e) { | |
| 39 | String tip = null; | |
| 40 | 1 | java.awt.Point p = e.getPoint(); |
| 41 | 1 | int index = columnModel.getColumnIndexAtX(p.x); |
| 42 | 2 | int realIndex = columnModel.getColumn(index).getModelIndex(); |
| 43 | 1 | return columnToolTips[realIndex]; |
| 44 | } | |
| 45 | ||
| 46 | ||
| 47 | /** | |
| 48 | * Returns the length of text in pixels in certain cell. The font and its | |
| 49 | * attributes are taken into account. | |
| 50 | * | |
| 51 | * @param row Row. | |
| 52 | * @param column Column. | |
| 53 | * @return Lenght of text in pixels. | |
| 54 | */ | |
| 55 | public int getTextLength(int row, int column) { | |
| 56 | ||
| 57 | 1 | Font tblFont = this.getFont(); |
| 58 | 1 | Graphics tblGraphics = this.getGraphics(); |
| 59 | 1 | FontMetrics tblFontMetrics = this.getFontMetrics(tblFont); |
| 60 | 2 | int marginLength = this.getColumnModel().getColumnMargin(); |
| 61 | ||
| 62 | 1 | String cellValue = (String) (this.getValueAt(row, column)); |
| 63 | 1 | if (cellValue == null) { |
| 64 | cellValue = ""; | |
| 65 | } | |
| 66 | ||
| 67 | 5 | int textLength = (int) (tblFontMetrics.getStringBounds(cellValue, tblGraphics).getWidth()) + 1; |
| 68 | ||
| 69 | 5 | return textLength + 2 * marginLength; |
| 70 | ||
| 71 | } | |
| 72 | ||
| 73 | ||
| 74 | /** | |
| 75 | * Returns a value, which is the length of the longest text in a certain column. | |
| 76 | * | |
| 77 | * @param column Number of the column. 0 is the leftmost, next to the right is 1, | |
| 78 | * and so on. | |
| 79 | * @return The lenght of the longest text in the given column, in pixel. | |
| 80 | */ | |
| 81 | public int getMaxTextLengthInColumn(int column) { | |
| 82 | ||
| 83 | 2 | int maxLength = 0; |
| 84 | 2 | int rowForMaxLength = 0; |
| 85 | ||
| 86 | 6 | for (int i = 0; i < this.getRowCount(); i++) { |
| 87 | 2 | String str = (String) ((DefaultTableModel) getModel()).getValueAt(i, column); |
| 88 | 3 | if (str.length() > maxLength) { |
| 89 | 1 | maxLength = str.length(); |
| 90 | rowForMaxLength = i; | |
| 91 | } | |
| 92 | ||
| 93 | /*int lngth = 0; | |
| 94 | ||
| 95 | if (str.length > 2) | |
| 96 | lngth = getTextLength(i, column); | |
| 97 | ||
| 98 | ||
| 99 | if (lngth > maxLength) { | |
| 100 | maxLength = lngth; | |
| 101 | }*/ | |
| 102 | } | |
| 103 | 6 | return getRowCount() != 0 ? getTextLength(rowForMaxLength, column) : 0; |
| 104 | } | |
| 105 | ||
| 106 | ||
| 107 | /** | |
| 108 | * Sets the column at index col to selected or deselected | |
| 109 | * based on the value of select. | |
| 110 | */ | |
| 111 | public void selectRow(int row) { | |
| 112 | 3 | this.selectedRows = new int[1]; |
| 113 | 2 | selectedRows[0] = row; |
| 114 | 3 | this.areRowsSelected = true; |
| 115 | } | |
| 116 | ||
| 117 | public void selectRows(int[] rows) { | |
| 118 | 1 | this.selectedRows = rows; |
| 119 | 3 | this.areRowsSelected = true; |
| 120 | } | |
| 121 | ||
| 122 | ||
| 123 | public void unselectAllRows() { | |
| 124 | 3 | this.areRowsSelected = false; |
| 125 | } | |
| 126 | ||
| 127 | ||
| 128 | /** | |
| 129 | * This method returns whether a particular cell is selected or not. | |
| 130 | */ | |
| 131 | public boolean isCellSelected(int row, int column) throws IllegalArgumentException { | |
| 132 | ||
| 133 | 5 | for (int i = 0; i < selectedRows.length; i++) { |
| 134 | 1 | if (selectedRows[i] == row) { |
| 135 | 1 | if (areRowsSelected) { |
| 136 | 3 | return true; |
| 137 | } else { | |
| 138 | 3 | return false; |
| 139 | } | |
| 140 | } | |
| 141 | } | |
| 142 | 3 | return false; |
| 143 | } | |
| 144 | ||
| 145 | /** | |
| 146 | * This method is redefined to catch an odd exception we cannot | |
| 147 | * otherwise seem to affect. It calls the corresponding method | |
| 148 | * in JTable, catches an ArrayOutOfBoundsException and logs it. | |
| 149 | * It then tries again a moment later to avoid race conditions. | |
| 150 | * If after ten attempts the error still occurs, it gives up | |
| 151 | * and returns null, probably causing an exception upstream. | |
| 152 | */ | |
| 153 | public Component prepareRenderer(TableCellRenderer renderer, int row, | |
| 154 | int column) { | |
| 155 | Logger logger; | |
| 156 | Component result; | |
| 157 | try { | |
| 158 | 1 | result = super.prepareRenderer(renderer, row, column); |
| 159 | 3 | tryCounter = 0; |
| 160 | 1 | return result; |
| 161 | } catch (ArrayIndexOutOfBoundsException ghostError) { | |
| 162 | logger = Logger.getLogger(getClass().getPackage().getName()); | |
| 163 | logger.warning(new Message("Our JTable override is causing " + | |
| 164 | "odd errors. Retrying in 100 " + | |
| 165 | "milliseconds.").toString()); | |
| 166 | logger.fine(new Message("Full JTable error was: {0}", | |
| 167 | ghostError.toString()).toString()); | |
| 168 | // Sleep for 100 milliseconds to avoid race conditions. | |
| 169 | try { | |
| 170 | 3 | Thread.sleep(100); |
| 171 | } catch (InterruptedException noMoreSleeping) { | |
| 172 | } | |
| 173 | 4 | tryCounter++; |
| 174 | // Try again. | |
| 175 | 4 | if (tryCounter < 10) { |
| 176 | 2 | return prepareRenderer(renderer, row, column); |
| 177 | } else { | |
| 178 | 3 | tryCounter = 0; |
| 179 | 1 | return null; |
| 180 | } | |
| 181 | } | |
| 182 | } | |
| 183 | } | |
| 184 | ||
| 185 | ||
Mutations | ||
| 21 |
Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE Removed assignment to member variable selectedRows : NO_COVERAGE |
|
| 22 |
Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE Removed assignment to member variable areRowsSelected : NO_COVERAGE |
|
| 23 |
Substituted 0 with 1 : NO_COVERAGE Removed assignment to member variable tryCounter : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE |
|
| 29 |
Removed assignment to member variable columnToolTips : NO_COVERAGE removed call to fi/helsinki/cs/titokone/JTableX::getColumnCount : NO_COVERAGE |
|
| 34 |
Removed assignment to member variable columnToolTips : NO_COVERAGE |
|
| 40 |
removed call to java/awt/event/MouseEvent::getPoint : NO_COVERAGE |
|
| 41 |
removed call to javax/swing/table/TableColumnModel::getColumnIndexAtX : NO_COVERAGE |
|
| 42 |
removed call to javax/swing/table/TableColumn::getModelIndex : NO_COVERAGE removed call to javax/swing/table/TableColumnModel::getColumn : NO_COVERAGE |
|
| 43 |
mutated return of Object value for fi/helsinki/cs/titokone/JTableX::getToolTipText to ( if (x != null) null else throw new RuntimeException ) : NO_COVERAGE |
|
| 57 |
removed call to fi/helsinki/cs/titokone/JTableX::getFont : NO_COVERAGE |
|
| 58 |
removed call to fi/helsinki/cs/titokone/JTableX::getGraphics : NO_COVERAGE |
|
| 59 |
removed call to fi/helsinki/cs/titokone/JTableX::getFontMetrics : NO_COVERAGE |
|
| 60 |
removed call to fi/helsinki/cs/titokone/JTableX::getColumnModel : NO_COVERAGE removed call to javax/swing/table/TableColumnModel::getColumnMargin : NO_COVERAGE |
|
| 62 |
removed call to fi/helsinki/cs/titokone/JTableX::getValueAt : NO_COVERAGE |
|
| 63 |
negated conditional : NO_COVERAGE |
|
| 67 |
removed call to java/awt/geom/Rectangle2D::getWidth : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE Replaced integer addition with subtraction : NO_COVERAGE removed call to java/awt/FontMetrics::getStringBounds : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE |
|
| 69 |
replaced return of integer sized value with (x == 0 ? 1 : 0) : NO_COVERAGE Replaced integer addition with subtraction : NO_COVERAGE Substituted 2 with 3 : NO_COVERAGE Substituted 2 with 3 : NO_COVERAGE Replaced integer multiplication with division : NO_COVERAGE |
|
| 83 |
Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE |
|
| 84 |
Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE |
|
| 86 |
Changed increment from 1 to -1 : NO_COVERAGE negated conditional : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE changed conditional boundary : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE removed call to fi/helsinki/cs/titokone/JTableX::getRowCount : NO_COVERAGE |
|
| 87 |
removed call to fi/helsinki/cs/titokone/JTableX::getModel : NO_COVERAGE removed call to javax/swing/table/DefaultTableModel::getValueAt : NO_COVERAGE |
|
| 88 |
removed call to java/lang/String::length : NO_COVERAGE changed conditional boundary : NO_COVERAGE negated conditional : NO_COVERAGE |
|
| 89 |
removed call to java/lang/String::length : NO_COVERAGE |
|
| 103 |
replaced return of integer sized value with (x == 0 ? 1 : 0) : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE removed call to fi/helsinki/cs/titokone/JTableX::getTextLength : NO_COVERAGE removed call to fi/helsinki/cs/titokone/JTableX::getRowCount : NO_COVERAGE negated conditional : NO_COVERAGE |
|
| 112 |
Substituted 1 with 0 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE Removed assignment to member variable selectedRows : NO_COVERAGE |
|
| 113 |
Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE |
|
| 114 |
Removed assignment to member variable areRowsSelected : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE |
|
| 118 |
Removed assignment to member variable selectedRows : NO_COVERAGE |
|
| 119 |
Substituted 1 with 0 : NO_COVERAGE Removed assignment to member variable areRowsSelected : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE |
|
| 124 |
Removed assignment to member variable areRowsSelected : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE |
|
| 133 |
Substituted 0 with 1 : NO_COVERAGE changed conditional boundary : NO_COVERAGE negated conditional : NO_COVERAGE Changed increment from 1 to -1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE |
|
| 134 |
negated conditional : NO_COVERAGE |
|
| 135 |
negated conditional : NO_COVERAGE |
|
| 136 |
replaced return of integer sized value with (x == 0 ? 1 : 0) : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE |
|
| 138 |
Substituted 0 with 1 : NO_COVERAGE replaced return of integer sized value with (x == 0 ? 1 : 0) : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE |
|
| 142 |
replaced return of integer sized value with (x == 0 ? 1 : 0) : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE |
|
| 158 |
removed call to javax/swing/JTable::prepareRenderer : NO_COVERAGE |
|
| 159 |
Removed assignment to member variable tryCounter : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE |
|
| 160 |
mutated return of Object value for fi/helsinki/cs/titokone/JTableX::prepareRenderer to ( if (x != null) null else throw new RuntimeException ) : NO_COVERAGE |
|
| 170 |
removed call to java/lang/Thread::sleep : NO_COVERAGE Substituted 100 with 101 : NO_COVERAGE Replaced constant value of 100 with 101 : NO_COVERAGE |
|
| 173 |
Removed assignment to member variable tryCounter : NO_COVERAGE Replaced integer addition with subtraction : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE |
|
| 175 |
negated conditional : NO_COVERAGE Substituted 10 with 11 : NO_COVERAGE Replaced constant value of 10 with 11 : NO_COVERAGE changed conditional boundary : NO_COVERAGE |
|
| 176 |
removed call to fi/helsinki/cs/titokone/JTableX::prepareRenderer : NO_COVERAGE mutated return of Object value for fi/helsinki/cs/titokone/JTableX::prepareRenderer to ( if (x != null) null else throw new RuntimeException ) : NO_COVERAGE |
|
| 178 |
Substituted 0 with 1 : NO_COVERAGE Removed assignment to member variable tryCounter : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE |
|
| 179 |
mutated return of Object value for fi/helsinki/cs/titokone/JTableX::prepareRenderer to ( if (x != null) null else throw new RuntimeException ) : NO_COVERAGE |