001/* A graphical component displaying matrix contents. 002 003 Copyright (c) 1997-2014 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 027 028 */ 029package ptolemy.actor.gui; 030 031import javax.swing.JScrollPane; 032import javax.swing.JTable; 033import javax.swing.SwingUtilities; 034import javax.swing.table.AbstractTableModel; 035 036import ptolemy.data.MatrixToken; 037import ptolemy.data.StringToken; 038import ptolemy.data.Token; 039 040/////////////////////////////////////////////////////////////////// 041//// MatrixPane 042 043/** 044 A graphical component that displays the values in a matrix. 045 The data to display is supplied in the form of a MatrixToken. 046 The table is currently not editable, although this may be changed 047 in the future. The table is an instance of Java's JTable class, 048 which is exposed as a public member. The rich interface 049 of the JTable class can be used to customize the display 050 in various ways. 051 052 @author Bart Kienhuis and Edward A. Lee 053 @version $Id$ 054 @since Ptolemy II 2.1 055 @Pt.ProposedRating Red (eal) 056 @Pt.AcceptedRating Red (eal) 057 */ 058@SuppressWarnings("serial") 059public class MatrixPane extends JScrollPane { 060 /** Construct an empty matrix pane. 061 */ 062 public MatrixPane() { 063 super(); 064 065 // Create a table. 066 table = new JTable(); 067 068 // No table header. 069 table.setTableHeader(null); 070 071 // Adjust column widths automatically. 072 // If the matrix is large, then elements will be 073 // elided and replaced with ... 074 table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); 075 076 // Add the table to the scroll pane. 077 setViewportView(table); 078 079 // Inherit the background color from the container. 080 table.setBackground(null); 081 } 082 083 /////////////////////////////////////////////////////////////////// 084 //// public methods //// 085 086 /** Clear the display. */ 087 public void clear() { 088 // When invoking methods in the table object, 089 // be sure to invoke them from the Swing Event 090 // thread. 091 // See http://bugzilla.ecoinformatics.org/show_bug.cgi?id=4826 092 SwingUtilities.invokeLater(new Runnable() { 093 @Override 094 public void run() { 095 table.setModel(_emptyTableModel); 096 } 097 }); 098 } 099 100 /** Set the matrix to display in the table. 101 * @param matrix The matrix to display in the table. 102 */ 103 public void display(MatrixToken matrix) { 104 final MatrixToken myMatrix = matrix; 105 SwingUtilities.invokeLater(new Runnable() { 106 @Override 107 public void run() { 108 table.setModel(new MatrixAsTable(myMatrix)); 109 } 110 }); 111 } 112 113 /////////////////////////////////////////////////////////////////// 114 //// public variables //// 115 116 /** The table representing the matrix. Methods in the class 117 * referred to by this field should only be invoked from the 118 * Swing event thread. See SwingUtilities.invokeLater(). 119 */ 120 public JTable table; 121 122 /////////////////////////////////////////////////////////////////// 123 //// private variables //// 124 125 /** Empty string. */ 126 private static Token _emptyStringToken = new StringToken(""); 127 128 /** Empty table model. */ 129 private static EmptyTableModel _emptyTableModel = new EmptyTableModel(); 130 131 /////////////////////////////////////////////////////////////////// 132 //// inner class //// 133 134 /** This class provides an implementation of the 135 * TableModel interface for viewing matrix tokens. 136 * Each element of the matrix is represented as an instance 137 * of Token, so all matrix types are supported. 138 */ 139 private static class MatrixAsTable extends AbstractTableModel { 140 // FindBugs suggests making this class static so as to decrease 141 // the size of instances and avoid dangling references. 142 143 /** Construct a table for the specified matrix. 144 * @param matrix The matrix. 145 */ 146 MatrixAsTable(MatrixToken matrix) { 147 _matrix = matrix; 148 } 149 150 /////////////////////////////////////////////////////////////////// 151 //// public methods //// 152 153 /** Get the column count of the Matrix. 154 * @return the column count. 155 */ 156 @Override 157 public int getColumnCount() { 158 return _matrix.getColumnCount(); 159 } 160 161 /** Get the name of the specified column, which is the column 162 * index as a string. 163 * @return The column index as a string. 164 */ 165 @Override 166 public String getColumnName(int columnIndex) { 167 return Integer.toString(columnIndex); 168 } 169 170 /** Get the row count of the Matrix. 171 * @return the row count. 172 */ 173 @Override 174 public int getRowCount() { 175 return _matrix.getRowCount(); 176 } 177 178 /** Get the specified entry from the matrix as a Token. 179 * @param row The row number. 180 * @param column The column number. 181 * @return An instance of Token representing the matrix value 182 * at the specified row and column. 183 */ 184 @Override 185 public Object getValueAt(int row, int column) { 186 // There is a bug in JTable, where it happily tries to access 187 // rows and columns that are outside of range. 188 if (row >= _matrix.getRowCount() 189 || column >= _matrix.getColumnCount()) { 190 return _emptyStringToken; 191 } 192 193 return _matrix.getElementAsToken(row, column).toString(); 194 } 195 196 /////////////////////////////////////////////////////////////////// 197 //// private members //// 198 199 /** The Matrix for which a Table Model is created. */ 200 private MatrixToken _matrix = null; 201 } 202 203 /** This class provides an implementation of the 204 * TableModel interface representing an empty matrix. 205 * This is used to clear the display. 206 */ 207 private static class EmptyTableModel extends AbstractTableModel { 208 /////////////////////////////////////////////////////////////////// 209 //// public methods //// 210 211 /** Get the column count of the Matrix. 212 * @return Zero. 213 */ 214 @Override 215 public int getColumnCount() { 216 return 0; 217 } 218 219 /** Get the row count of the Matrix. 220 * @return Zero. 221 */ 222 @Override 223 public int getRowCount() { 224 return 0; 225 } 226 227 /** Get the specified entry from the matrix as a Token. 228 * @param row The row number. 229 * @param column The column number. 230 * @return An instance of Token representing the matrix value 231 * at the specified row and column. 232 */ 233 @Override 234 public Object getValueAt(int row, int column) { 235 return _emptyStringToken; 236 } 237 } 238}