001 /* 002 * Copyright (C) 2008-2010 by Holger Arndt 003 * 004 * This file is part of the Universal Java Matrix Package (UJMP). 005 * See the NOTICE file distributed with this work for additional 006 * information regarding copyright ownership and licensing. 007 * 008 * UJMP is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation; either version 2 011 * of the License, or (at your option) any later version. 012 * 013 * UJMP is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU Lesser General Public License for more details. 017 * 018 * You should have received a copy of the GNU Lesser General Public 019 * License along with UJMP; if not, write to the 020 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 021 * Boston, MA 02110-1301 USA 022 */ 023 024 package org.ujmp.gui; 025 026 import java.awt.Component; 027 import java.awt.image.BufferedImage; 028 029 import javax.swing.Icon; 030 import javax.swing.ImageIcon; 031 import javax.swing.JFrame; 032 import javax.swing.JPanel; 033 import javax.swing.JTable; 034 import javax.swing.ListSelectionModel; 035 import javax.swing.event.EventListenerList; 036 import javax.swing.event.TableModelEvent; 037 import javax.swing.event.TableModelListener; 038 import javax.swing.table.AbstractTableModel; 039 import javax.swing.table.DefaultTableCellRenderer; 040 import javax.swing.table.TableModel; 041 042 import org.ujmp.core.Coordinates; 043 import org.ujmp.core.Matrix; 044 import org.ujmp.core.exceptions.MatrixException; 045 import org.ujmp.core.util.UJMPFormat; 046 import org.ujmp.core.util.UJMPSettings; 047 import org.ujmp.gui.frame.MatrixFrame; 048 import org.ujmp.gui.panels.MatrixPanel; 049 import org.ujmp.gui.util.FastListSelectionModel; 050 051 public class MatrixGUIObject extends AbstractGUIObject implements TableModel { 052 private static final long serialVersionUID = -5777110889052748093L; 053 054 private Matrix matrix = null; 055 056 private int modCount = 0; 057 058 private transient String tooltipText = null; 059 060 private transient ListSelectionModel rowSelectionModel = null; 061 062 private transient ListSelectionModel columnSelectionModel = null; 063 064 private transient EventListenerList listenerList = null; 065 066 private transient JFrame frame = null; 067 068 private transient JPanel panel = null; 069 070 public MatrixGUIObject(Matrix m) { 071 this.matrix = m; 072 } 073 074 public Matrix getMatrix() { 075 return matrix; 076 } 077 078 public void clear() { 079 matrix.clear(); 080 fireValueChanged(); 081 } 082 083 public double getEstimatedMaxValue(long timeOut) throws MatrixException { 084 double max = -Double.MAX_VALUE; 085 long t0 = System.currentTimeMillis(); 086 long t1; 087 double v = 0.0; 088 for (long[] c : matrix.availableCoordinates()) { 089 max = (v = matrix.getAsDouble(c)) > max ? v : max; 090 t1 = System.currentTimeMillis(); 091 if (t1 - t0 > timeOut) { 092 return max; 093 } 094 } 095 return max; 096 } 097 098 public double getEstimatedMinValue(long timeOut) throws MatrixException { 099 double min = Double.MAX_VALUE; 100 long t0 = System.currentTimeMillis(); 101 long t1; 102 double v = 0.0; 103 for (long[] c : matrix.availableCoordinates()) { 104 min = (v = matrix.getAsDouble(c)) < min ? v : min; 105 t1 = System.currentTimeMillis(); 106 if (t1 - t0 > timeOut) { 107 return min; 108 } 109 } 110 return min; 111 } 112 113 public long getValueCount() { 114 return matrix.getValueCount(); 115 } 116 117 public final EventListenerList getListenerList() { 118 if (listenerList == null) { 119 listenerList = new EventListenerList(); 120 } 121 return listenerList; 122 } 123 124 public String getLabel() { 125 return matrix.getLabel(); 126 } 127 128 public void setLabel(String label) { 129 matrix.setLabel(label); 130 } 131 132 public final void addTableModelListener(TableModelListener l) { 133 getListenerList().add(TableModelListener.class, l); 134 } 135 136 public final void removeTableModelListener(TableModelListener l) { 137 getListenerList().add(TableModelListener.class, l); 138 } 139 140 public final String getToolTipText() { 141 try { 142 if (tooltipText == null) { 143 StringBuilder s = new StringBuilder(); 144 s.append("<html>"); 145 s.append("<table>"); 146 s.append("<tr>"); 147 s.append("<td colspan=2><h3>Matrix</h3></td>"); 148 s.append("</tr>"); 149 s.append("<tr>"); 150 s.append("<td><b>Label:</b></td>"); 151 s.append("<td>" + getLabel() + "</td>"); 152 s.append("</tr>"); 153 s.append("<tr>"); 154 s.append("<td><b>Size:</b></td>"); 155 s.append("<td>" + getRowCount() + "x" + getColumnCount() 156 + "</td>"); 157 s.append("</tr>"); 158 s.append("<tr>"); 159 s.append("<td><b>Values:</b></td>"); 160 s.append("<td>"); 161 s.append("<table border=1>"); 162 int rowCount = getRowCount(); 163 int columnCount = getColumnCount(); 164 165 // header 166 s.append("<tr>"); 167 s.append("<th></th>"); 168 for (int col = 0; col < columnCount 169 && col < UJMPSettings.getMaxToolTipCols(); col++) { 170 s.append("<th>" + matrix.getColumnLabel(col) + "</th>"); 171 } 172 if (getColumnCount() > UJMPSettings.getMaxToolTipCols()) { 173 s.append("<th>...</th>"); 174 } 175 s.append("</tr>"); 176 177 for (int row = 0; row < rowCount 178 && row < UJMPSettings.getMaxToolTipRows(); row++) { 179 s.append("<tr>"); 180 s.append("<th>" + matrix.getRowLabel(row) + "</th>"); 181 for (int col = 0; col < columnCount 182 && col < UJMPSettings.getMaxToolTipCols(); col++) { 183 s 184 .append("<td align=right>" 185 + UJMPFormat.getSingleLineInstance() 186 .format( 187 matrix.getAsObject(row, 188 col)) + "</td>"); 189 } 190 if (getColumnCount() > UJMPSettings.getMaxToolTipCols()) { 191 s.append("<td align=right>...</td>"); 192 } 193 s.append("</tr>"); 194 } 195 if (getRowCount() > UJMPSettings.getMaxToolTipRows()) { 196 s.append("<tr>"); 197 s.append("<td></td>"); 198 for (int col = 0; col < getColumnCount() 199 && col < UJMPSettings.getMaxToolTipCols(); col++) { 200 s.append("<td align=right>...</td>"); 201 } 202 if (getColumnCount() > UJMPSettings.getMaxToolTipCols()) { 203 s.append("<td align=right>...</td>"); 204 } 205 s.append("</tr>"); 206 } 207 s.append("</table>"); 208 s.append("</td>"); 209 s.append("</tr>"); 210 s.append("</table>"); 211 s.append("</html>"); 212 tooltipText = s.toString(); 213 } 214 return tooltipText; 215 } catch (Exception e) { 216 // TODO 217 e.printStackTrace(); 218 return "error getting tooltip text"; 219 } 220 } 221 222 public final void fireValueChanged() { 223 for (Object o : getListenerList().getListenerList()) { 224 if (o instanceof TableModelListener) 225 ((TableModelListener) o) 226 .tableChanged(new TableModelEvent(this)); 227 } 228 modCount++; 229 } 230 231 public final void fireValueChanged(int row, int column, Object value) { 232 for (Object o : getListenerList().getListenerList()) { 233 if (o instanceof TableModelListener) 234 ((TableModelListener) o).tableChanged(new TableModelEvent(this, 235 row, row, column, TableModelEvent.UPDATE)); 236 } 237 modCount++; 238 } 239 240 public final Class<?> getColumnClass(int columnIndex) { 241 return Object.class; 242 } 243 244 public int getColumnCount() { 245 return (int) matrix.getColumnCount(); 246 } 247 248 // works only for 2D 249 public String getColumnName(int columnIndex) { 250 if (matrix.getDimensionCount() == 2) { 251 String label = matrix.getColumnLabel(columnIndex); 252 return label == null || "".equals(label) ? "" + columnIndex : label; 253 } else { 254 return ""; 255 } 256 } 257 258 public int getRowCount() { 259 return (int) matrix.getRowCount(); 260 } 261 262 public Object getValueAt(long[] c) { 263 return getValueAt((int) c[Matrix.ROW], (int) c[Matrix.COLUMN]); 264 } 265 266 public Object getValueAt(int rowIndex, int columnIndex) { 267 try { 268 return matrix.getAsObject(rowIndex, columnIndex); 269 } catch (MatrixException e) { 270 // TODO Auto-generated catch block 271 e.printStackTrace(); 272 return null; 273 } 274 } 275 276 public boolean isCellEditable(int rowIndex, int columnIndex) { 277 return !matrix.isReadOnly(); 278 } 279 280 public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 281 try { 282 matrix.setAsObject(aValue, rowIndex, columnIndex); 283 } catch (MatrixException e) { 284 // TODO Auto-generated catch block 285 e.printStackTrace(); 286 } 287 fireValueChanged(rowIndex, columnIndex, aValue); 288 tooltipText = null; 289 } 290 291 public Iterable<long[]> coordinates() { 292 return matrix.allCoordinates(); 293 } 294 295 // works only for 2D 296 public final String getRowName(int row) { 297 if (matrix.getDimensionCount() == 2) { 298 String label = matrix.getRowLabel(row); 299 return label == null || "".equals(label) ? "" + row : label; 300 } else { 301 return ""; 302 } 303 } 304 305 public int getZCount() { 306 return (int) matrix.getZCount(); 307 } 308 309 public boolean isSquare() { 310 return matrix.isSquare(); 311 } 312 313 public Double getDoubleValueAt(long... coordinates) throws MatrixException { 314 return matrix.getAsDouble(coordinates); 315 } 316 317 public boolean isSparse() { 318 return matrix.isSparse(); 319 } 320 321 public boolean isScalar() { 322 return matrix.isScalar(); 323 } 324 325 public ListSelectionModel getColumnSelectionModel() { 326 if (columnSelectionModel == null) { 327 columnSelectionModel = new FastListSelectionModel(); 328 } 329 return columnSelectionModel; 330 } 331 332 public void setColumnSelectionModel(ListSelectionModel columnSelectionModel) { 333 this.columnSelectionModel = columnSelectionModel; 334 } 335 336 public ListSelectionModel getRowSelectionModel() { 337 if (rowSelectionModel == null) { 338 rowSelectionModel = new FastListSelectionModel(); 339 } 340 return rowSelectionModel; 341 } 342 343 public void setRowSelectionModel(ListSelectionModel rowSelectionModel) { 344 this.rowSelectionModel = rowSelectionModel; 345 } 346 347 public long[] getSize() { 348 return matrix.getSize(); 349 } 350 351 public final Icon getIcon() { 352 try { 353 TableModel dataModel = new AbstractTableModel() { 354 private static final long serialVersionUID = 5562866897873790623L; 355 356 public int getColumnCount() { 357 return 1; 358 } 359 360 public int getRowCount() { 361 return 1; 362 } 363 364 public Object getValueAt(int row, int col) { 365 return this; 366 } 367 }; 368 JTable table = new JTable(dataModel); 369 table.getColumnModel().getColumn(0).setWidth(32); 370 table.setRowHeight(32); 371 372 int WIDTH = table.getColumnModel().getColumn(0).getWidth() - 1; 373 int HEIGHT = table.getRowHeight(0) - 1; 374 375 Class<?> cl = Class.forName("org.ujmp.gui.matrix.MatrixRenderer"); 376 DefaultTableCellRenderer mr = (DefaultTableCellRenderer) cl 377 .newInstance(); 378 Component c = mr.getTableCellRendererComponent(table, this, false, 379 false, 0, 0); 380 BufferedImage bi = new BufferedImage(WIDTH, HEIGHT, 381 BufferedImage.TYPE_INT_RGB); 382 c.paint(bi.getGraphics()); 383 return new ImageIcon(bi); 384 385 } catch (Exception e) { 386 return new ImageIcon("resources/icons/rebuild.png"); 387 } 388 } 389 390 // Description not supported for Matrix 391 public String getDescription() { 392 return null; 393 } 394 395 // Description not supported for Matrix 396 public void setDescription(String description) { 397 } 398 399 public String toString() { 400 if (matrix.getLabel() != null) { 401 return "[" + Coordinates.toString(matrix.getSize()) + "] " 402 + matrix.getClass().getSimpleName() + " [" 403 + matrix.getLabel() + "]"; 404 } else { 405 return "[" + Coordinates.toString(matrix.getSize()) + "] " 406 + matrix.getClass().getSimpleName(); 407 } 408 } 409 410 public Matrix getCoreObject() { 411 return matrix; 412 } 413 414 public JFrame getFrame() { 415 if (frame == null) { 416 frame = new MatrixFrame(this); 417 } 418 return frame; 419 } 420 421 public JPanel getPanel() { 422 if (panel == null) { 423 panel = new MatrixPanel(this); 424 } 425 return panel; 426 } 427 428 }