001/***************************************************************************** 002 * Copyright by The HDF Group. * 003 * Copyright by the Board of Trustees of the University of Illinois. * 004 * All rights reserved. * 005 * * 006 * This file is part of the HDF Java Products distribution. * 007 * The full copyright notice, including terms governing use, modification, * 008 * and redistribution, is contained in the files COPYING and Copyright.html. * 009 * COPYING can be found at the root of the source code distribution tree. * 010 * Or, see http://hdfgroup.org/products/hdf-java/doc/Copyright.html. * 011 * If you do not have access to either file, you may request a copy from * 012 * help@hdfgroup.org. * 013 ****************************************************************************/ 014 015package hdf.view; 016 017import hdf.object.CompoundDS; 018import hdf.object.Dataset; 019import hdf.object.Datatype; 020import hdf.object.FileFormat; 021import hdf.object.Group; 022import hdf.object.HObject; 023import hdf.object.ScalarDS; 024import hdf.view.ViewProperties.BITMASK_OP; 025import java.awt.BorderLayout; 026import java.awt.Color; 027import java.awt.Component; 028import java.awt.Cursor; 029import java.awt.Dimension; 030import java.awt.GridLayout; 031import java.awt.Insets; 032import java.awt.Point; 033import java.awt.Toolkit; 034import java.awt.datatransfer.Clipboard; 035import java.awt.datatransfer.DataFlavor; 036import java.awt.datatransfer.StringSelection; 037import java.awt.event.ActionEvent; 038import java.awt.event.ActionListener; 039import java.awt.event.InputEvent; 040import java.awt.event.ItemEvent; 041import java.awt.event.ItemListener; 042import java.awt.event.KeyEvent; 043import java.awt.event.MouseEvent; 044import java.awt.event.MouseListener; 045import java.io.BufferedInputStream; 046import java.io.BufferedReader; 047import java.io.BufferedWriter; 048import java.io.DataOutputStream; 049import java.io.File; 050import java.io.FileInputStream; 051import java.io.FileNotFoundException; 052import java.io.FileOutputStream; 053import java.io.FileReader; 054import java.io.FileWriter; 055import java.io.IOException; 056import java.io.PrintWriter; 057import java.io.StringReader; 058import java.lang.reflect.Array; 059import java.lang.reflect.Constructor; 060import java.math.BigInteger; 061import java.nio.ByteBuffer; 062import java.nio.ByteOrder; 063import java.nio.DoubleBuffer; 064import java.nio.FloatBuffer; 065import java.nio.IntBuffer; 066import java.nio.LongBuffer; 067import java.nio.ShortBuffer; 068import java.text.DecimalFormat; 069import java.text.NumberFormat; 070import java.util.BitSet; 071import java.util.Enumeration; 072import java.util.HashMap; 073import java.util.Iterator; 074import java.util.List; 075import java.util.StringTokenizer; 076import java.util.Vector; 077import javax.swing.BorderFactory; 078import javax.swing.ButtonGroup; 079import javax.swing.CellEditor; 080import javax.swing.JButton; 081import javax.swing.JCheckBoxMenuItem; 082import javax.swing.JComboBox; 083import javax.swing.JComponent; 084import javax.swing.JDialog; 085import javax.swing.JFileChooser; 086import javax.swing.JFrame; 087import javax.swing.JInternalFrame; 088import javax.swing.JLabel; 089import javax.swing.JList; 090import javax.swing.JMenu; 091import javax.swing.JMenuBar; 092import javax.swing.JMenuItem; 093import javax.swing.JOptionPane; 094import javax.swing.JPanel; 095import javax.swing.JPopupMenu; 096import javax.swing.JRadioButton; 097import javax.swing.JScrollPane; 098import javax.swing.JSplitPane; 099import javax.swing.JTable; 100import javax.swing.JTextArea; 101import javax.swing.JTextField; 102import javax.swing.JViewport; 103import javax.swing.KeyStroke; 104import javax.swing.SwingConstants; 105import javax.swing.UIManager; 106import javax.swing.WindowConstants; 107import javax.swing.border.Border; 108import javax.swing.border.CompoundBorder; 109import javax.swing.border.EtchedBorder; 110import javax.swing.border.LineBorder; 111import javax.swing.border.MatteBorder; 112import javax.swing.border.TitledBorder; 113import javax.swing.event.ChangeEvent; 114import javax.swing.event.ListSelectionEvent; 115import javax.swing.table.AbstractTableModel; 116import javax.swing.table.JTableHeader; 117import javax.swing.table.TableCellRenderer; 118import javax.swing.table.TableColumn; 119import javax.swing.tree.DefaultMutableTreeNode; 120import javax.swing.tree.TreeNode; 121 122/** 123 * TableView displays an HDF dataset as a two-dimensional table. 124 */ 125public class DefaultTableView extends JInternalFrame implements TableView, ActionListener, MouseListener { 126 private static final long serialVersionUID = -7452459299532863847L; 127 128 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DefaultTableView.class); 129 130 /** 131 * The main HDFView. 132 */ 133 private final ViewManager viewer; 134 135 /** 136 * Numerical data type. B = byte array, S = short array, I = int array, J = long array, F = 137 * float array, and D = double array. 138 */ 139 private char NT = ' '; 140 141 /** 142 * The Scalar Dataset. 143 */ 144 private Dataset dataset; 145 146 /** 147 * The value of the dataset. 148 */ 149 private Object dataValue; 150 151 /** 152 * The table used to hold the table data. 153 */ 154 private JTable table; 155 156 /** Label to indicate the current cell location. */ 157 private JLabel cellLabel; 158 159 /** Text field to display the value of of the current cell. */ 160 private JTextArea cellValueField; 161 162 private boolean isValueChanged; 163 164 private final Toolkit toolkit; 165 166 private boolean isReadOnly; 167 168 private boolean isDisplayTypeChar; 169 170 private boolean isDataTransposed; 171 172 private boolean isRegRef; 173 private boolean isObjRef; 174 175 private final JCheckBoxMenuItem checkFixedDataLength; 176 private int fixedDataLength; 177 private final JCheckBoxMenuItem checkCustomNotation; 178 private final JCheckBoxMenuItem checkScientificNotation; 179 private final JCheckBoxMenuItem checkHex; 180 private final JCheckBoxMenuItem checkBin; 181 182 // changed to use normalized scientific notation (1 <= coefficient < 10). 183 // private final DecimalFormat scientificFormat = new DecimalFormat("###.#####E0#"); 184 private final DecimalFormat scientificFormat = new DecimalFormat("0.0###E0###"); 185 private DecimalFormat customFormat = new DecimalFormat("###.#####"); 186 private final NumberFormat normalFormat = null; // NumberFormat.getInstance(); 187 private NumberFormat numberFormat = normalFormat; 188 private boolean showAsHex = false, showAsBin = false; 189 private final boolean startEditing[] = { false }; 190 private JPopupMenu popupMenu; 191 192 private enum ViewType { 193 TABLE, IMAGE, TEXT 194 } 195 196 private ViewType viewType; 197 198 private JTextField frameField; 199 200 private long curFrame = 0; 201 private long maxFrame = 1; 202 203 private Object fillValue = null; 204 205 private BitSet bitmask; 206 207 private BITMASK_OP bitmaskOP = BITMASK_OP.EXTRACT; 208 209 private int binaryOrder; 210 211 private int indexBase = 0; 212 213 private static final int FLOAT_BUFFER_SIZE = 524288; 214 215 private static final int INT_BUFFER_SIZE = 524288; 216 217 private static final int SHORT_BUFFER_SIZE = 1048576; 218 219 private static final int LONG_BUFFER_SIZE = 262144; 220 221 private static final int DOUBLE_BUFFER_SIZE = 262144; 222 223 private static final int BYTE_BUFFER_SIZE = 2097152; 224 225 /* the value of the current cell value in editing. */ 226 private Object currentEditingCellValue = null; 227 228 /** 229 * Constructs an TableView. 230 * <p> 231 * 232 * @param theView 233 * the main HDFView. 234 */ 235 public DefaultTableView(ViewManager theView) { 236 this(theView, null); 237 } 238 239 /** 240 * Constructs an TableView. 241 * <p> 242 * 243 * @param theView 244 * the main HDFView. 245 * @param map 246 * the properties on how to show the data. The map is used to allow applications to 247 * pass properties on how to display the data, such as, transposing data, showing 248 * data as character, applying bitmask, and etc. Predefined keys are listed at 249 * ViewProperties.DATA_VIEW_KEY. 250 */ 251 public DefaultTableView(ViewManager theView, HashMap map) { 252 super(); 253 254 setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 255 log.trace("DefaultTableView start"); 256 257 viewer = theView; 258 toolkit = Toolkit.getDefaultToolkit(); 259 isValueChanged = false; 260 isReadOnly = false; 261 isRegRef = false; 262 isObjRef = false; 263 viewType = ViewType.TABLE; 264 fixedDataLength = -1; 265 HObject hobject = null; 266 popupMenu = null; 267 bitmask = null; 268 269 if (ViewProperties.isIndexBase1()) indexBase = 1; 270 log.trace("isIndexBase1() is {}", indexBase); 271 272 checkFixedDataLength = new JCheckBoxMenuItem("Fixed Data Length", false); 273 checkCustomNotation = new JCheckBoxMenuItem("Show Custom Notation", false); 274 checkScientificNotation = new JCheckBoxMenuItem("Show Scientific Notation", false); 275 checkHex = new JCheckBoxMenuItem("Show Hexadecimal", false); 276 checkBin = new JCheckBoxMenuItem("Show Binary", false); 277 278 if (map != null) { 279 hobject = (HObject) map.get(ViewProperties.DATA_VIEW_KEY.OBJECT); 280 281 bitmask = (BitSet) map.get(ViewProperties.DATA_VIEW_KEY.BITMASK); 282 bitmaskOP = (BITMASK_OP) map.get(ViewProperties.DATA_VIEW_KEY.BITMASKOP); 283 284 Boolean b = (Boolean) map.get(ViewProperties.DATA_VIEW_KEY.CHAR); 285 if (b != null) isDisplayTypeChar = b.booleanValue(); 286 287 b = (Boolean) map.get(ViewProperties.DATA_VIEW_KEY.TRANSPOSED); 288 if (b != null) isDataTransposed = b.booleanValue(); 289 290 b = (Boolean) map.get(ViewProperties.DATA_VIEW_KEY.INDEXBASE1); 291 if (b != null) { 292 if (b.booleanValue()) 293 indexBase = 1; 294 else 295 indexBase = 0; 296 } 297 } 298 log.trace("isIndexBase={} - isDataTransposed={} - isDisplayTypeChar={}", indexBase, isDataTransposed, isDisplayTypeChar); 299 300 if (hobject == null) hobject = viewer.getTreeView().getCurrentObject(); 301 302 if ((hobject == null) || !(hobject instanceof Dataset)) { 303 return; 304 } 305 306 dataset = (Dataset) hobject; 307 isReadOnly = dataset.getFileFormat().isReadOnly(); 308 log.trace("dataset({}) isReadOnly={}", dataset, isReadOnly); 309 310 long[] dims = dataset.getDims(); 311 long tsize = 1; 312 313 for (int i = 0; i < dims.length; i++) 314 tsize *= dims[i]; 315 316 log.trace("dataset size={} Height={} Width={}", tsize, dataset.getHeight(), dataset.getWidth()); 317 if (dataset.getHeight() <= 0 || dataset.getWidth() <= 0 || tsize <= 0) return; 318 319 // cannot edit hdf4 vdata 320 if (dataset.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF4)) 321 && (dataset instanceof CompoundDS)) { 322 isReadOnly = true; 323 } 324 325 // disable edit feature for szip compression when encode is not enabled 326 if (!isReadOnly) { 327 String compression = dataset.getCompression(); 328 if ((compression != null) && compression.startsWith("SZIP")) { 329 if (!compression.endsWith("ENCODE_ENABLED")) { 330 isReadOnly = true; 331 } 332 } 333 } 334 335 Datatype dtype = dataset.getDatatype(); 336 log.trace("dataset dtype.getDatatypeClass()={}", dtype.getDatatypeClass()); 337 isDisplayTypeChar = (isDisplayTypeChar && (dtype.getDatatypeSize() == 1 || (dtype.getDatatypeClass() == Datatype.CLASS_ARRAY && dtype 338 .getBasetype().getDatatypeClass() == Datatype.CLASS_CHAR))); 339 340 log.trace("dataset isDisplayTypeChar={} isConvertEnum={}", isDisplayTypeChar, ViewProperties.isConvertEnum()); 341 dataset.setEnumConverted(ViewProperties.isConvertEnum()); 342 343 // set title & border 344 TitledBorder border = BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.lightGray, 1), indexBase 345 + "-based", 346 TitledBorder.RIGHT, TitledBorder.TOP, this.getFont(), Color.black); 347 ((JPanel) getContentPane()).setBorder(border); 348 349 // create the table and its columnHeader 350 if (dataset instanceof CompoundDS) { 351 isDataTransposed = false; // disable transpose for compound dataset 352 this.setFrameIcon(ViewProperties.getTableIcon()); 353 table = createTable((CompoundDS) dataset); 354 } 355 else { /* if (dataset instanceof ScalarDS) */ 356 this.setFrameIcon(ViewProperties.getDatasetIcon()); 357 table = createTable((ScalarDS) dataset); 358 log.trace("createTable((ScalarDS) dataset) dtype.getDatatypeClass()={}", dtype.getDatatypeClass()); 359 360 if (dtype.getDatatypeClass() == Datatype.CLASS_REFERENCE) { 361 table.addMouseListener(this); 362 363 if (dtype.getDatatypeSize() > 8) { 364 isReadOnly = true; 365 isRegRef = true; 366 } 367 else 368 isObjRef = true; 369 } 370 else if ((dtype.getDatatypeClass() == Datatype.CLASS_BITFIELD) || (dtype.getDatatypeClass() == Datatype.CLASS_OPAQUE)) { 371 showAsHex = true; 372 checkHex.setSelected(true); 373 checkScientificNotation.setSelected(false); 374 checkCustomNotation.setSelected(false); 375 checkBin.setSelected(false); 376 showAsBin = false; 377 numberFormat = normalFormat; 378 } 379 log.trace("createTable((ScalarDS) dataset) isRegRef={} isObjRef={} showAsHex={}", isRegRef, isObjRef, showAsHex); 380 } 381 382 if (table == null) { 383 viewer.showStatus("Creating table failed - " + dataset.getName()); 384 dataset = null; 385 super.dispose(); 386 return; 387 } 388 table.setName("data"); 389 390 log.trace("DefaultTableView create ColumnHeader"); 391 ColumnHeader columnHeaders = new ColumnHeader(table); 392 columnHeaders.setName("columnHeaders"); 393 table.setTableHeader(columnHeaders); 394 table.setCellSelectionEnabled(true); 395 table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 396 table.setGridColor(Color.gray); 397 398 // add the table to a scroller 399 JScrollPane scrollingTable = new JScrollPane(table); 400 scrollingTable.getVerticalScrollBar().setUnitIncrement(100); 401 scrollingTable.getHorizontalScrollBar().setUnitIncrement(100); 402 403 // create row headers and add it to the scroller 404 log.trace("DefaultTableView create RowHeader"); 405 RowHeader rowHeaders = new RowHeader(table, dataset); 406 rowHeaders.setName("rowHeaders"); 407 408 JViewport viewp = new JViewport(); 409 viewp.add(rowHeaders); 410 viewp.setPreferredSize(rowHeaders.getPreferredSize()); 411 scrollingTable.setRowHeader(viewp); 412 413 cellLabel = new JLabel(""); 414 cellLabel.setBorder(new EtchedBorder(EtchedBorder.LOWERED)); 415 Dimension dim = cellLabel.getPreferredSize(); 416 dim.width = 75; 417 cellLabel.setPreferredSize(dim); 418 cellLabel.setHorizontalAlignment(SwingConstants.RIGHT); 419 420 cellValueField = new JTextArea(); 421 cellValueField.setLineWrap(true); 422 cellValueField.setWrapStyleWord(true); 423 cellValueField.setEditable(false); 424 cellValueField.setBackground(new Color(255, 255, 240)); 425 426 JScrollPane scrollingcellValue = new JScrollPane(cellValueField); 427 scrollingcellValue.getVerticalScrollBar().setUnitIncrement(50); 428 scrollingcellValue.getHorizontalScrollBar().setUnitIncrement(50); 429 430 JPanel valuePane = new JPanel(); 431 valuePane.setLayout(new BorderLayout()); 432 valuePane.add(cellLabel, BorderLayout.WEST); 433 valuePane.add(scrollingcellValue, BorderLayout.CENTER); 434 435 JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, valuePane, scrollingTable); 436 splitPane.setDividerLocation(25); 437 JPanel contentPane = (JPanel) getContentPane(); 438 contentPane.add(splitPane); 439 440 StringBuffer sb = new StringBuffer(hobject.getName()); 441 sb.append(" at "); 442 sb.append(hobject.getPath()); 443 sb.append(" ["); 444 sb.append(dataset.getFileFormat().getName()); 445 sb.append(" in "); 446 sb.append(dataset.getFileFormat().getParent()); 447 sb.append("]"); 448 setTitle(sb.toString()); 449 450 // setup subset information 451 log.trace("DefaultTableView setup subset information"); 452 int rank = dataset.getRank(); 453 int[] selectedIndex = dataset.getSelectedIndex(); 454 long[] count = dataset.getSelectedDims(); 455 long[] stride = dataset.getStride(); 456 // long[] dims = dataset.getDims(); 457 long[] start = dataset.getStartDims(); 458 int n = Math.min(3, rank); 459 if (rank > 2) { 460 curFrame = start[selectedIndex[2]] + indexBase; 461 maxFrame = dims[selectedIndex[2]]; 462 } 463 464 sb.append(" [ dims"); 465 sb.append(selectedIndex[0]); 466 for (int i = 1; i < n; i++) { 467 sb.append("x"); 468 sb.append(selectedIndex[i]); 469 } 470 sb.append(", start"); 471 sb.append(start[selectedIndex[0]]); 472 for (int i = 1; i < n; i++) { 473 sb.append("x"); 474 sb.append(start[selectedIndex[i]]); 475 } 476 sb.append(", count"); 477 sb.append(count[selectedIndex[0]]); 478 for (int i = 1; i < n; i++) { 479 sb.append("x"); 480 sb.append(count[selectedIndex[i]]); 481 } 482 sb.append(", stride"); 483 sb.append(stride[selectedIndex[0]]); 484 for (int i = 1; i < n; i++) { 485 sb.append("x"); 486 sb.append(stride[selectedIndex[i]]); 487 } 488 sb.append(" ] "); 489 log.trace("DefaultTableView subset={}", sb.toString()); 490 491 setJMenuBar(createMenuBar()); 492 viewer.showStatus(sb.toString()); 493 494 // set cell height for large fonts 495 int cellRowHeight = table.getFontMetrics(table.getFont()).getHeight(); 496 rowHeaders.setRowHeight(cellRowHeight); 497 table.setRowHeight(cellRowHeight); 498 499 // create popup menu for reg. ref. 500 if (isRegRef || isObjRef) popupMenu = createPopupMenu(); 501 log.trace("DefaultTableView finish"); 502 } 503 504 private JMenuBar createMenuBar ( ) { 505 JMenuBar bar = new JMenuBar(); 506 JButton button; 507 boolean isEditable = !isReadOnly; 508 boolean is3D = (dataset.getRank() > 2); 509 510 JMenu menu = new JMenu("Table", false); 511 menu.setMnemonic('T'); 512 bar.add(menu); 513 514 JMenuItem item = new JMenuItem("Export Data to Text File"); 515 item.addActionListener(this); 516 item.setActionCommand("Save table as text"); 517 menu.add(item); 518 519 JMenu exportAsBinaryMenu = new JMenu("Export Data to Binary File"); 520 if ((dataset instanceof ScalarDS)) { 521 menu.add(exportAsBinaryMenu); 522 } 523 item = new JMenuItem("Native Order"); 524 item.addActionListener(this); 525 item.setActionCommand("Save table as binary Native Order"); 526 exportAsBinaryMenu.add(item); 527 item = new JMenuItem("Little Endian"); 528 item.addActionListener(this); 529 item.setActionCommand("Save table as binary Little Endian"); 530 exportAsBinaryMenu.add(item); 531 item = new JMenuItem("Big Endian"); 532 item.addActionListener(this); 533 item.setActionCommand("Save table as binary Big Endian"); 534 exportAsBinaryMenu.add(item); 535 536 menu.addSeparator(); 537 538 item = new JMenuItem("Import Data from Text File"); 539 item.addActionListener(this); 540 item.setActionCommand("Import data from file"); 541 item.setEnabled(isEditable); 542 menu.add(item); 543 544 item = checkFixedDataLength; 545 item.addActionListener(this); 546 item.setActionCommand("Fixed data length"); 547 if (dataset instanceof ScalarDS) { 548 menu.add(item); 549 } 550 551 JMenu importFromBinaryMenu = new JMenu("Import Data from Binary File"); 552 if ((dataset instanceof ScalarDS)) { 553 menu.add(importFromBinaryMenu); 554 } 555 item = new JMenuItem("Native Order"); 556 item.addActionListener(this); 557 item.setActionCommand("Order as Native Order"); 558 importFromBinaryMenu.add(item); 559 item = new JMenuItem("Little Endian"); 560 item.addActionListener(this); 561 item.setActionCommand("Order as Little Endian"); 562 importFromBinaryMenu.add(item); 563 item = new JMenuItem("Big Endian"); 564 item.addActionListener(this); 565 item.setActionCommand("Order as Big Endian"); 566 importFromBinaryMenu.add(item); 567 568 menu.addSeparator(); 569 570 item = new JMenuItem("Copy"); 571 item.addActionListener(this); 572 item.setActionCommand("Copy data"); 573 item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), true)); 574 menu.add(item); 575 576 item = new JMenuItem("Paste"); 577 item.addActionListener(this); 578 item.setActionCommand("Paste data"); 579 item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), true)); 580 item.setEnabled(isEditable); 581 menu.add(item); 582 583 menu.addSeparator(); 584 585 item = new JMenuItem("Copy to New Dataset"); 586 item.addActionListener(this); 587 item.setActionCommand("Write selection to dataset"); 588 item.setEnabled(isEditable && (dataset instanceof ScalarDS)); 589 menu.add(item); 590 591 item = new JMenuItem("Save Changes to File"); 592 item.addActionListener(this); 593 item.setActionCommand("Save dataset"); 594 item.setEnabled(isEditable); 595 item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_U, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), true)); 596 menu.add(item); 597 598 menu.addSeparator(); 599 600 item = new JMenuItem("Select All"); 601 item.addActionListener(this); 602 item.setActionCommand("Select all data"); 603 item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), true)); 604 menu.add(item); 605 606 menu.addSeparator(); 607 608 item = new JMenuItem("Show Lineplot"); 609 item.addActionListener(this); 610 item.setActionCommand("Show chart"); 611 menu.add(item); 612 613 item = new JMenuItem("Show Statistics"); 614 item.addActionListener(this); 615 item.setActionCommand("Show statistics"); 616 menu.add(item); 617 618 menu.addSeparator(); 619 620 item = new JMenuItem("Math Conversion"); 621 item.addActionListener(this); 622 item.setActionCommand("Math conversion"); 623 item.setEnabled(isEditable); 624 menu.add(item); 625 626 menu.addSeparator(); 627 628 item = checkScientificNotation; 629 item.addActionListener(this); 630 item.setActionCommand("Show scientific notation"); 631 if (dataset instanceof ScalarDS) { 632 menu.add(item); 633 } 634 635 item = checkCustomNotation; 636 item.addActionListener(this); 637 item.setActionCommand("Show custom notation"); 638 if (dataset instanceof ScalarDS) { 639 menu.add(item); 640 } 641 642 item = new JMenuItem("Create custom notation"); 643 item.addActionListener(this); 644 item.setActionCommand("Create custom notation"); 645 menu.add(item); 646 647 boolean isInt = (NT == 'B' || NT == 'S' || NT == 'I' || NT == 'J'); 648 // this will allow disabling of hex and binary display menu options 649 // boolean isUINT64 = (dataset.getDatatype().isUnsigned() && (NT == 'J')); 650 item = checkHex; 651 item.addActionListener(this); 652 item.setActionCommand("Show hexadecimal"); 653 if ((dataset instanceof ScalarDS) && isInt /* && !isUINT64 */) { 654 menu.add(item); 655 } 656 657 item = checkBin; 658 item.addActionListener(this); 659 item.setActionCommand("Show binary"); 660 if ((dataset instanceof ScalarDS) && isInt /* && !isUINT64 */) { 661 menu.add(item); 662 } 663 664 menu.addSeparator(); 665 666 item = new JMenuItem("Close"); 667 item.addActionListener(this); 668 item.setActionCommand("Close"); 669 menu.add(item); 670 671 bar.add(new JLabel(" ")); 672 673 // add icons to the menubar 674 675 Insets margin = new Insets(0, 2, 0, 2); 676 677 // chart button 678 button = new JButton(ViewProperties.getChartIcon()); 679 bar.add(button); 680 button.setToolTipText("Line Plot"); 681 button.setMargin(margin); 682 button.addActionListener(this); 683 button.setActionCommand("Show chart"); 684 685 if (is3D) { 686 bar.add(new JLabel(" ")); 687 688 // first button 689 button = new JButton(ViewProperties.getFirstIcon()); 690 bar.add(button); 691 button.setToolTipText("First"); 692 button.setMargin(margin); 693 button.setName("firstbutton"); 694 button.addActionListener(this); 695 button.setActionCommand("First page"); 696 697 // previous button 698 button = new JButton(ViewProperties.getPreviousIcon()); 699 bar.add(button); 700 button.setToolTipText("Previous"); 701 button.setMargin(margin); 702 button.setName("prevbutton"); 703 button.addActionListener(this); 704 button.setActionCommand("Previous page"); 705 706 frameField = new JTextField(String.valueOf(curFrame)); 707 frameField.setMaximumSize(new Dimension(50, 30)); 708 bar.add(frameField); 709 frameField.setMargin(margin); 710 frameField.setName("framenumber"); 711 frameField.addActionListener(this); 712 frameField.setActionCommand("Go to frame"); 713 714 JLabel tmpField = new JLabel(String.valueOf(maxFrame), SwingConstants.CENTER); 715 tmpField.setMaximumSize(new Dimension(50, 30)); 716 bar.add(tmpField); 717 718 // next button 719 button = new JButton(ViewProperties.getNextIcon()); 720 bar.add(button); 721 button.setToolTipText("Next"); 722 button.setMargin(margin); 723 button.setName("nextbutton"); 724 button.addActionListener(this); 725 button.setActionCommand("Next page"); 726 727 // last button 728 button = new JButton(ViewProperties.getLastIcon()); 729 bar.add(button); 730 button.setToolTipText("Last"); 731 button.setMargin(margin); 732 button.setName("lastbutton"); 733 button.addActionListener(this); 734 button.setActionCommand("Last page"); 735 } 736 737 return bar; 738 } 739 740 @Override 741 public void actionPerformed (ActionEvent e) { 742 try { 743 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 744 745 e.getSource(); 746 String cmd = e.getActionCommand(); 747 log.trace("DefaultTableView actionPerformed: {}", cmd); 748 749 if (cmd.equals("Close")) { 750 dispose(); // terminate the application 751 } 752 else if (cmd.equals("Save table as text")) { 753 try { 754 saveAsText(); 755 } 756 catch (Exception ex) { 757 toolkit.beep(); 758 JOptionPane.showMessageDialog((JFrame) viewer, ex, getTitle(), JOptionPane.ERROR_MESSAGE); 759 } 760 } 761 else if (cmd.startsWith("Save table as binary")) { 762 if (cmd.equals("Save table as binary Native Order")) binaryOrder = 1; 763 if (cmd.equals("Save table as binary Little Endian")) binaryOrder = 2; 764 if (cmd.equals("Save table as binary Big Endian")) binaryOrder = 3; 765 try { 766 saveAsBinary(); 767 } 768 catch (Exception ex) { 769 toolkit.beep(); 770 JOptionPane.showMessageDialog((JFrame) viewer, ex, getTitle(), JOptionPane.ERROR_MESSAGE); 771 } 772 } 773 else if (cmd.equals("Copy data")) { 774 copyData(); 775 } 776 else if (cmd.equals("Paste data")) { 777 pasteData(); 778 } 779 else if (cmd.equals("Import data from file")) { 780 String currentDir = dataset.getFileFormat().getParent(); 781 JFileChooser fchooser = new JFileChooser(currentDir); 782 fchooser.setFileFilter(DefaultFileFilter.getFileFilterText()); 783 int returnVal = fchooser.showOpenDialog(this); 784 785 if (returnVal != JFileChooser.APPROVE_OPTION) { 786 return; 787 } 788 789 File choosedFile = fchooser.getSelectedFile(); 790 if (choosedFile == null) { 791 return; 792 } 793 794 String txtFile = choosedFile.getAbsolutePath(); 795 importTextData(txtFile); 796 } 797 else if (cmd.startsWith("Order as")) { 798 if (cmd.equals("Order as Native Order")) binaryOrder = 1; 799 if (cmd.equals("Order as Little Endian")) binaryOrder = 2; 800 if (cmd.equals("Order as Big Endian")) binaryOrder = 3; 801 802 importBinaryData(); 803 } 804 else if (cmd.equals("Write selection to dataset")) { 805 JTable jtable = getTable(); 806 if ((jtable.getSelectedColumnCount() <= 0) || (jtable.getSelectedRowCount() <= 0)) { 807 JOptionPane.showMessageDialog(this, "Select table cells to write.", "HDFView", JOptionPane.INFORMATION_MESSAGE); 808 return; 809 } 810 811 TreeView treeView = viewer.getTreeView(); 812 TreeNode node = viewer.getTreeView().findTreeNode(dataset); 813 Group pGroup = (Group) ((DefaultMutableTreeNode) node.getParent()).getUserObject(); 814 TreeNode root = dataset.getFileFormat().getRootNode(); 815 816 if (root == null) { 817 return; 818 } 819 820 Vector<Object> list = new Vector<Object>(dataset.getFileFormat().getNumberOfMembers() + 5); 821 DefaultMutableTreeNode theNode = null; 822 Enumeration<?> local_enum = ((DefaultMutableTreeNode) root).depthFirstEnumeration(); 823 while (local_enum.hasMoreElements()) { 824 theNode = (DefaultMutableTreeNode) local_enum.nextElement(); 825 list.add(theNode.getUserObject()); 826 } 827 828 NewDatasetDialog dialog = new NewDatasetDialog((JFrame) viewer, pGroup, list, this); 829 dialog.setVisible(true); 830 831 HObject obj = (HObject) dialog.getObject(); 832 if (obj != null) { 833 Group pgroup = dialog.getParentGroup(); 834 try { 835 treeView.addObject(obj, pgroup); 836 } 837 catch (Exception ex) { 838 log.debug("Write selection to dataset:", ex); 839 } 840 } 841 842 list.setSize(0); 843 } 844 else if (cmd.equals("Save dataset")) { 845 try { 846 updateValueInFile(); 847 } 848 catch (Exception ex) { 849 toolkit.beep(); 850 JOptionPane.showMessageDialog((JFrame) viewer, ex, getTitle(), JOptionPane.ERROR_MESSAGE); 851 } 852 } 853 else if (cmd.equals("Select all data")) { 854 try { 855 selectAll(); 856 } 857 catch (Exception ex) { 858 toolkit.beep(); 859 JOptionPane.showMessageDialog((JFrame) viewer, ex, getTitle(), JOptionPane.ERROR_MESSAGE); 860 } 861 } 862 else if (cmd.equals("Show chart")) { 863 showLineplot(); 864 } 865 else if (cmd.equals("First page")) { 866 firstPage(); 867 } 868 else if (cmd.equals("Previous page")) { 869 previousPage(); 870 } 871 else if (cmd.equals("Next page")) { 872 nextPage(); 873 } 874 else if (cmd.equals("Last page")) { 875 lastPage(); 876 } 877 else if (cmd.equals("Show statistics")) { 878 try { 879 Object theData = null; 880 theData = getSelectedData(); 881 882 if (dataset instanceof CompoundDS) { 883 int cols = table.getSelectedColumnCount(); 884 if (cols != 1) { 885 JOptionPane.showMessageDialog(this, "Please select one colunm a time for compound dataset.", 886 getTitle(), JOptionPane.ERROR_MESSAGE); 887 return; 888 } 889 } 890 else if (theData == null) { 891 theData = dataValue; 892 } 893 894 double[] minmax = new double[2]; 895 double[] stat = new double[2]; 896 Tools.findMinMax(theData, minmax, fillValue); 897 if (Tools.computeStatistics(theData, stat, fillValue) > 0) { 898 String statistics = "Min = " + minmax[0] + "\nMax = " + minmax[1] 899 + "\nMean = " + stat[0] + "\nStandard deviation = " + stat[1]; 900 JOptionPane.showMessageDialog(this, statistics, "Statistics", JOptionPane.INFORMATION_MESSAGE); 901 } 902 903 theData = null; 904 System.gc(); 905 } 906 catch (Exception ex) { 907 toolkit.beep(); 908 JOptionPane.showMessageDialog((JFrame) viewer, ex, getTitle(), JOptionPane.ERROR_MESSAGE); 909 } 910 } 911 else if (cmd.equals("Math conversion")) { 912 try { 913 mathConversion(); 914 } 915 catch (Exception ex) { 916 toolkit.beep(); 917 JOptionPane.showMessageDialog((JFrame) viewer, ex, getTitle(), JOptionPane.ERROR_MESSAGE); 918 } 919 } 920 else if (cmd.startsWith("Go to frame")) { 921 int page = 0; 922 try { 923 page = Integer.parseInt(frameField.getText().trim()) - indexBase; 924 } 925 catch (Exception ex) { 926 page = -1; 927 } 928 929 gotoPage(page); 930 } 931 else if (cmd.equals("Show scientific notation")) { 932 if (checkScientificNotation.isSelected()) { 933 checkCustomNotation.setSelected(false); 934 numberFormat = scientificFormat; 935 checkHex.setSelected(false); 936 checkBin.setSelected(false); 937 showAsHex = false; 938 showAsBin = false; 939 } 940 else 941 numberFormat = normalFormat; 942 this.updateUI(); 943 } 944 else if (cmd.equals("Create custom notation")) { 945 String msg = "Create number format by pattern \nINTEGER . FRACTION E EXPONENT\nusing # for optional digits and 0 for required digits" 946 + "\nwhere, INTEGER: the pattern for the integer part" 947 + "\n FRACTION: the pattern for the fractional part" 948 + "\n EXPONENT: the pattern for the exponent part" 949 + "\n\nFor example, " 950 + "\n\t the normalized scientific notation format is \"#.0###E0##\"" 951 + "\n\t to make the digits required \"0.00000E000\"\n\n"; 952 String str = (String) JOptionPane.showInputDialog(this, msg, "Create a custom number format", 953 JOptionPane.PLAIN_MESSAGE, ViewProperties.getLargeHdfIcon(), null, null); 954 if ((str == null) || (str.length() < 1)) { 955 return; 956 } 957 958 customFormat.applyPattern(str); 959 960 } 961 else if (cmd.equals("Show custom notation")) { 962 if (checkCustomNotation.isSelected()) { 963 numberFormat = customFormat; 964 checkScientificNotation.setSelected(false); 965 checkHex.setSelected(false); 966 checkBin.setSelected(false); 967 showAsHex = false; 968 showAsBin = false; 969 } 970 else 971 numberFormat = normalFormat; 972 this.updateUI(); 973 } 974 else if (cmd.equals("Show hexadecimal")) { 975 showAsHex = checkHex.isSelected(); 976 if (showAsHex) { 977 checkScientificNotation.setSelected(false); 978 checkCustomNotation.setSelected(false); 979 checkBin.setSelected(false); 980 showAsBin = false; 981 numberFormat = normalFormat; 982 } 983 this.updateUI(); 984 } 985 else if (cmd.equals("Show binary")) { 986 showAsBin = checkBin.isSelected(); 987 if (showAsBin) { 988 checkScientificNotation.setSelected(false); 989 checkCustomNotation.setSelected(false); 990 checkHex.setSelected(false); 991 showAsHex = false; 992 numberFormat = normalFormat; 993 } 994 this.updateUI(); 995 } 996 else if (cmd.equals("Fixed data length")) { 997 if (!checkFixedDataLength.isSelected()) { 998 fixedDataLength = -1; 999 this.updateUI(); 1000 return; 1001 } 1002 1003 String str = JOptionPane 1004 .showInputDialog( 1005 this, 1006 "Enter fixed data length when importing text data\n\n" 1007 + "For example, for a text string of \"12345678\"\n\t\tenter 2, the data will be 12, 34, 56, 78\n\t\tenter 4, the data will be 1234, 5678\n", 1008 ""); 1009 1010 if ((str == null) || (str.length() < 1)) { 1011 checkFixedDataLength.setSelected(false); 1012 return; 1013 } 1014 1015 try { 1016 fixedDataLength = Integer.parseInt(str); 1017 } 1018 catch (Exception ex) { 1019 fixedDataLength = -1; 1020 } 1021 1022 if (fixedDataLength < 1) { 1023 checkFixedDataLength.setSelected(false); 1024 return; 1025 } 1026 } 1027 else if (cmd.startsWith("Show data as")) { 1028 log.trace("DefaultTableView actionPerformed: {}", cmd); 1029 // show data pointed by reg. ref. 1030 if (cmd.endsWith("table")) 1031 viewType = ViewType.TABLE; 1032 else if (cmd.endsWith("image")) 1033 viewType = ViewType.IMAGE; 1034 else 1035 viewType = ViewType.TABLE; 1036 log.trace("DefaultTableView actionPerformed: Show data as: {}", viewType); 1037 1038 Object theData = getSelectedData(); 1039 if (theData == null) { 1040 toolkit.beep(); 1041 JOptionPane.showMessageDialog(this, "No data selected.", getTitle(), JOptionPane.ERROR_MESSAGE); 1042 return; 1043 1044 } 1045 1046 int[] selectedRows = table.getSelectedRows(); 1047 int[] selectedCols = table.getSelectedColumns(); 1048 if (selectedRows == null || selectedRows.length <= 0) { 1049 log.trace("DefaultTableView actionPerformed: Show data as: selectedRows is empty"); 1050 return; 1051 } 1052 int len = Array.getLength(selectedRows) * Array.getLength(selectedCols); 1053 log.trace("DefaultTableView actionPerformed: Show data as: len={}", len); 1054 for (int i = 0; i < len; i++) { 1055 if (isRegRef) { 1056 log.trace("DefaultTableView actionPerformed: Show data[{}] as: isRegRef={}", i, isRegRef); 1057 showRegRefData((String) Array.get(theData, i)); 1058 } 1059 else if (isObjRef) { 1060 log.trace("DefaultTableView actionPerformed: Show data[{}] as: isObjRef={}", i, isObjRef); 1061 showObjRefData(Array.getLong(theData, i)); 1062 } 1063 } 1064 } 1065 } 1066 finally { 1067 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 1068 } 1069 } 1070 1071 // Implementing DataView. 1072 @Override 1073 public HObject getDataObject ( ) { 1074 return dataset; 1075 } 1076 1077 @Override 1078 public void dispose ( ) { 1079 if (isValueChanged && !isReadOnly) { 1080 int op = JOptionPane.showConfirmDialog(this, "\"" + dataset.getName() + "\" has changed.\n" 1081 + "Do you want to save the changes?", getTitle(), JOptionPane.YES_NO_OPTION); 1082 1083 if (op == JOptionPane.YES_OPTION) { 1084 updateValueInFile(); 1085 } 1086 else 1087 dataset.clearData(); // reload data 1088 1089 } 1090 1091 if (dataset instanceof ScalarDS) { 1092 ScalarDS sds = (ScalarDS) dataset; 1093 // reload the data when it is displayed next time 1094 // because the display type (table or image) may be 1095 // different. 1096 1097 if (sds.isImage()) { 1098 sds.clearData(); 1099 } 1100 1101 dataValue = null; 1102 table = null; 1103 } 1104 1105 viewer.removeDataView(this); 1106 1107 super.dispose(); 1108 } 1109 1110 // Implementing DataObserver. 1111 private void previousPage ( ) { 1112 int rank = dataset.getRank(); 1113 1114 if (rank < 3) { 1115 return; 1116 } 1117 1118 long[] start = dataset.getStartDims(); 1119 dataset.getDims(); 1120 int[] selectedIndex = dataset.getSelectedIndex(); 1121 long idx = start[selectedIndex[2]]; 1122 if (idx == 0) { 1123 return; // current page is the first page 1124 } 1125 1126 gotoPage(start[selectedIndex[2]] - 1); 1127 } 1128 1129 // Implementing DataObserver. 1130 private void nextPage ( ) { 1131 int rank = dataset.getRank(); 1132 1133 if (rank < 3) { 1134 return; 1135 } 1136 1137 long[] start = dataset.getStartDims(); 1138 int[] selectedIndex = dataset.getSelectedIndex(); 1139 long[] dims = dataset.getDims(); 1140 long idx = start[selectedIndex[2]]; 1141 if (idx == dims[selectedIndex[2]] - 1) { 1142 return; // current page is the last page 1143 } 1144 1145 gotoPage(start[selectedIndex[2]] + 1); 1146 } 1147 1148 // Implementing DataObserver. 1149 private void firstPage ( ) { 1150 int rank = dataset.getRank(); 1151 1152 if (rank < 3) { 1153 return; 1154 } 1155 1156 long[] start = dataset.getStartDims(); 1157 int[] selectedIndex = dataset.getSelectedIndex(); 1158 dataset.getDims(); 1159 long idx = start[selectedIndex[2]]; 1160 if (idx == 0) { 1161 return; // current page is the first page 1162 } 1163 1164 gotoPage(0); 1165 } 1166 1167 // Implementing DataObserver. 1168 private void lastPage ( ) { 1169 int rank = dataset.getRank(); 1170 1171 if (rank < 3) { 1172 return; 1173 } 1174 1175 long[] start = dataset.getStartDims(); 1176 int[] selectedIndex = dataset.getSelectedIndex(); 1177 long[] dims = dataset.getDims(); 1178 long idx = start[selectedIndex[2]]; 1179 if (idx == dims[selectedIndex[2]] - 1) { 1180 return; // current page is the last page 1181 } 1182 1183 gotoPage(dims[selectedIndex[2]] - 1); 1184 } 1185 1186 // Implementing TableObserver. 1187 @Override 1188 public JTable getTable ( ) { 1189 return table; 1190 } 1191 1192 // Implementing TableObserver. 1193 private void showLineplot ( ) { 1194 int[] rows = table.getSelectedRows(); 1195 int[] cols = table.getSelectedColumns(); 1196 1197 if ((rows == null) || (cols == null) || (rows.length <= 0) || (cols.length <= 0)) { 1198 toolkit.beep(); 1199 JOptionPane.showMessageDialog(this, "Select rows/columns to draw line plot.", getTitle(), JOptionPane.ERROR_MESSAGE); 1200 return; 1201 } 1202 1203 int nrow = table.getRowCount(); 1204 int ncol = table.getColumnCount(); 1205 1206 log.trace("DefaultTableView showLineplot: {} - {}", nrow, ncol); 1207 LineplotOption lpo = new LineplotOption((JFrame) viewer, "Line Plot Options -- " + dataset.getName(), nrow, ncol); 1208 lpo.setVisible(true); 1209 1210 int plotType = lpo.getPlotBy(); 1211 if (plotType == LineplotOption.NO_PLOT) { 1212 return; 1213 } 1214 1215 boolean isRowPlot = (plotType == LineplotOption.ROW_PLOT); 1216 int xIndex = lpo.getXindex(); 1217 1218 // figure out to plot data by row or by column 1219 // Plot data by rows if all columns are selected and part of 1220 // rows are selected, otherwise plot data by column 1221 double[][] data = null; 1222 int nLines = 0; 1223 String title = "Lineplot - " + dataset.getPath() + dataset.getName(); 1224 String[] lineLabels = null; 1225 double[] yRange = { Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY }; 1226 double xData[] = null; 1227 1228 if (isRowPlot) { 1229 title += " - by row"; 1230 nLines = rows.length; 1231 if (nLines > 10) { 1232 toolkit.beep(); 1233 nLines = 10; 1234 JOptionPane.showMessageDialog(this, "More than 10 rows are selected.\n" + "The first 10 rows will be displayed.", 1235 getTitle(), JOptionPane.WARNING_MESSAGE); 1236 } 1237 lineLabels = new String[nLines]; 1238 data = new double[nLines][cols.length]; 1239 1240 double value = 0.0; 1241 for (int i = 0; i < nLines; i++) { 1242 lineLabels[i] = String.valueOf(rows[i] + indexBase); 1243 for (int j = 0; j < cols.length; j++) { 1244 data[i][j] = 0; 1245 try { 1246 value = Double.parseDouble(table.getValueAt(rows[i], cols[j]).toString()); 1247 data[i][j] = value; 1248 yRange[0] = Math.min(yRange[0], value); 1249 yRange[1] = Math.max(yRange[1], value); 1250 } 1251 catch (NumberFormatException ex) { 1252 log.debug("rows[{}]:", i, ex); 1253 } 1254 } // for (int j = 0; j < ncols; j++) 1255 } // for (int i = 0; i < rows.length; i++) 1256 1257 if (xIndex >= 0) { 1258 xData = new double[cols.length]; 1259 for (int j = 0; j < cols.length; j++) { 1260 xData[j] = 0; 1261 try { 1262 value = Double.parseDouble(table.getValueAt(xIndex, cols[j]).toString()); 1263 xData[j] = value; 1264 } 1265 catch (NumberFormatException ex) { 1266 log.debug("xIndex of {}:", xIndex, ex); 1267 } 1268 } 1269 } 1270 } // if (isRowPlot) 1271 else { 1272 title += " - by column"; 1273 nLines = cols.length; 1274 if (nLines > 10) { 1275 toolkit.beep(); 1276 nLines = 10; 1277 JOptionPane.showMessageDialog(this, "More than 10 columns are selected.\n" 1278 + "The first 10 columns will be displayed.", getTitle(), JOptionPane.WARNING_MESSAGE); 1279 } 1280 lineLabels = new String[nLines]; 1281 data = new double[nLines][rows.length]; 1282 double value = 0.0; 1283 for (int j = 0; j < nLines; j++) { 1284 lineLabels[j] = table.getColumnName(cols[j] /* + indexBase */); 1285 for (int i = 0; i < rows.length; i++) { 1286 data[j][i] = 0; 1287 try { 1288 value = Double.parseDouble(table.getValueAt(rows[i], cols[j]).toString()); 1289 data[j][i] = value; 1290 yRange[0] = Math.min(yRange[0], value); 1291 yRange[1] = Math.max(yRange[1], value); 1292 } 1293 catch (NumberFormatException ex) { 1294 log.debug("cols[{}]:", j, ex); 1295 } 1296 } // for (int j=0; j<ncols; j++) 1297 } // for (int i=0; i<rows.length; i++) 1298 1299 if (xIndex >= 0) { 1300 xData = new double[rows.length]; 1301 for (int j = 0; j < rows.length; j++) { 1302 xData[j] = 0; 1303 try { 1304 value = Double.parseDouble(table.getValueAt(rows[j], xIndex).toString()); 1305 xData[j] = value; 1306 } 1307 catch (NumberFormatException ex) { 1308 log.debug("xIndex of {}:", xIndex, ex); 1309 } 1310 } 1311 } 1312 } // else 1313 1314 int n = removeInvalidPlotData(data, xData, yRange); 1315 if (n < data[0].length) { 1316 double[][] dataNew = new double[data.length][n]; 1317 for (int i = 0; i < data.length; i++) 1318 System.arraycopy(data[i], 0, dataNew[i], 0, n); 1319 1320 data = dataNew; 1321 1322 if (xData != null) { 1323 double[] xDataNew = new double[n]; 1324 System.arraycopy(xData, 0, xDataNew, 0, n); 1325 xData = xDataNew; 1326 } 1327 } 1328 1329 // allow to draw a flat line: all values are the same 1330 if (yRange[0] == yRange[1]) { 1331 yRange[1] += 1; 1332 yRange[0] -= 1; 1333 } 1334 else if (yRange[0] > yRange[1]) { 1335 toolkit.beep(); 1336 JOptionPane.showMessageDialog(this, 1337 "Cannot show line plot for the selected data. \n" + "Please check the data range: (" 1338 + yRange[0] + ", " + yRange[1] + ").", getTitle(), JOptionPane.ERROR_MESSAGE); 1339 data = null; 1340 return; 1341 } 1342 if (xData == null) { // use array index and length for x data range 1343 xData = new double[2]; 1344 xData[0] = indexBase; // 1- or zero-based 1345 xData[1] = data[0].length + indexBase - 1; // maximum index 1346 } 1347 1348 Chart cv = new Chart((JFrame) viewer, title, Chart.LINEPLOT, data, xData, yRange); 1349 cv.setLineLabels(lineLabels); 1350 1351 String cname = dataValue.getClass().getName(); 1352 char dname = cname.charAt(cname.lastIndexOf("[") + 1); 1353 if ((dname == 'B') || (dname == 'S') || (dname == 'I') || (dname == 'J')) { 1354 cv.setTypeToInteger(); 1355 } 1356 1357 cv.setVisible(true); 1358 } 1359 1360 /** 1361 * Remove values of NaN, INF from the array. 1362 * 1363 * @param data 1364 * the data array 1365 * @param xData 1366 * the x-axis data points 1367 * @param yRange 1368 * the range of data values 1369 * @return number of data points in the plot data if successful; otherwise, returns false. 1370 */ 1371 private int removeInvalidPlotData (double[][] data, double[] xData, double[] yRange) { 1372 int idx = 0; 1373 boolean hasInvalid = false; 1374 1375 if (data == null || yRange == null) return -1; 1376 1377 yRange[0] = Double.POSITIVE_INFINITY; 1378 yRange[1] = Double.NEGATIVE_INFINITY; 1379 1380 for (int i = 0; i < data[0].length; i++) { 1381 hasInvalid = false; 1382 1383 for (int j = 0; j < data.length; j++) { 1384 hasInvalid = Tools.isNaNINF(data[j][i]); 1385 if (xData != null) hasInvalid = hasInvalid || Tools.isNaNINF(xData[i]); 1386 1387 if (hasInvalid) 1388 break; 1389 else { 1390 data[j][idx] = data[j][i]; 1391 if (xData != null) xData[idx] = xData[i]; 1392 yRange[0] = Math.min(yRange[0], data[j][idx]); 1393 yRange[1] = Math.max(yRange[1], data[j][idx]); 1394 } 1395 } 1396 1397 if (!hasInvalid) idx++; 1398 } 1399 1400 return idx; 1401 } 1402 1403 /** 1404 * Returns the selected data values. 1405 */ 1406 @Override 1407 public Object getSelectedData ( ) { 1408 if (dataset instanceof CompoundDS) { 1409 return getSelectedCompoundData(); 1410 } 1411 else { 1412 return getSelectedScalarData(); 1413 } 1414 } 1415 1416 /** 1417 * Returns the selected data values. 1418 */ 1419 private Object getSelectedScalarData ( ) { 1420 Object selectedData = null; 1421 1422 int[] selectedRows = table.getSelectedRows(); 1423 int[] selectedCols = table.getSelectedColumns(); 1424 if (selectedRows == null || selectedRows.length <= 0 || selectedCols == null || selectedCols.length <= 0) { 1425 return null; 1426 } 1427 1428 int size = selectedCols.length * selectedRows.length; 1429 log.trace("DefaultTableView getSelectedScalarData: {}", size); 1430 1431 // the whole table is selected 1432 if ((table.getColumnCount() == selectedCols.length) && (table.getRowCount() == selectedRows.length)) { 1433 return dataValue; 1434 } 1435 1436 selectedData = null; 1437 if (isRegRef) { 1438 // reg. ref data are stored in strings 1439 selectedData = new String[size]; 1440 } 1441 else { 1442 switch (NT) { 1443 case 'B': 1444 selectedData = new byte[size]; 1445 break; 1446 case 'S': 1447 selectedData = new short[size]; 1448 break; 1449 case 'I': 1450 selectedData = new int[size]; 1451 break; 1452 case 'J': 1453 selectedData = new long[size]; 1454 break; 1455 case 'F': 1456 selectedData = new float[size]; 1457 break; 1458 case 'D': 1459 selectedData = new double[size]; 1460 break; 1461 default: 1462 selectedData = null; 1463 break; 1464 } 1465 } 1466 1467 if (selectedData == null) { 1468 toolkit.beep(); 1469 JOptionPane.showMessageDialog(this, "Unsupported data type.", getTitle(), JOptionPane.ERROR_MESSAGE); 1470 return null; 1471 } 1472 log.trace("DefaultTableView getSelectedScalarData: selectedData is type {}", NT); 1473 1474 table.getSelectedRow(); 1475 table.getSelectedColumn(); 1476 int w = table.getColumnCount(); 1477 log.trace("DefaultTableView getSelectedScalarData: getColumnCount={}", w); 1478 int idx_src = 0; 1479 int idx_dst = 0; 1480 log.trace("DefaultTableView getSelectedScalarData: Rows.length={} Cols.length={}", selectedRows.length, selectedCols.length); 1481 for (int i = 0; i < selectedRows.length; i++) { 1482 for (int j = 0; j < selectedCols.length; j++) { 1483 idx_src = selectedRows[i] * w + selectedCols[j]; 1484 log.trace("DefaultTableView getSelectedScalarData[{},{}]: dataValue[{}]={} from r{} and c{}", i, j, idx_src, 1485 Array.get(dataValue, idx_src), selectedRows[i], selectedCols[j]); 1486 Array.set(selectedData, idx_dst, Array.get(dataValue, idx_src)); 1487 log.trace("DefaultTableView getSelectedScalarData[{},{}]: selectedData[{}]={}", i, j, idx_dst, 1488 Array.get(selectedData, idx_dst)); 1489 idx_dst++; 1490 } 1491 } 1492 1493 // this only works for continuous cells 1494 // for (int i = 0; i < rows; i++) { 1495 // idx_src = (r0 + i) * w + c0; 1496 // System.arraycopy(dataValue, idx_src, selectedData, idx_dst, cols); 1497 // idx_dst += cols; 1498 // } 1499 1500 return selectedData; 1501 } 1502 1503 /** 1504 * Returns the selected data values. 1505 */ 1506 private Object getSelectedCompoundData ( ) { 1507 Object selectedData = null; 1508 1509 int cols = table.getSelectedColumnCount(); 1510 int rows = table.getSelectedRowCount(); 1511 1512 if ((cols <= 0) || (rows <= 0)) { 1513 toolkit.beep(); 1514 JOptionPane.showMessageDialog(this, "No data is selected.", getTitle(), JOptionPane.ERROR_MESSAGE); 1515 return null; 1516 } 1517 1518 Object colData = null; 1519 try { 1520 colData = ((List<?>) dataset.getData()).get(table.getSelectedColumn()); 1521 } 1522 catch (Exception ex) { 1523 log.debug("colData:", ex); 1524 return null; 1525 } 1526 1527 int size = Array.getLength(colData); 1528 String cName = colData.getClass().getName(); 1529 int cIndex = cName.lastIndexOf("["); 1530 char nt = ' '; 1531 if (cIndex >= 0) { 1532 nt = cName.charAt(cIndex + 1); 1533 } 1534 log.trace("DefaultTableView getSelectedCompoundData: size={} cName={} nt={}", size, cName, nt); 1535 1536 if (nt == 'B') { 1537 selectedData = new byte[size]; 1538 } 1539 else if (nt == 'S') { 1540 selectedData = new short[size]; 1541 } 1542 else if (nt == 'I') { 1543 selectedData = new int[size]; 1544 } 1545 else if (nt == 'J') { 1546 selectedData = new long[size]; 1547 } 1548 else if (nt == 'F') { 1549 selectedData = new float[size]; 1550 } 1551 else if (nt == 'D') { 1552 selectedData = new double[size]; 1553 } 1554 else { 1555 toolkit.beep(); 1556 JOptionPane.showMessageDialog(this, "Unsupported data type.", getTitle(), JOptionPane.ERROR_MESSAGE); 1557 return null; 1558 } 1559 log.trace("DefaultTableView getSelectedCompoundData: selectedData={}", selectedData); 1560 1561 System.arraycopy(colData, 0, selectedData, 0, size); 1562 1563 return selectedData; 1564 } 1565 1566 /** 1567 * Creates a JTable to hold a scalar dataset. 1568 */ 1569 private JTable createTable (ScalarDS d) { 1570 JTable theTable = null; 1571 int rows = 0; 1572 int cols = 0; 1573 1574 log.trace("createTable: ScalarDS start"); 1575 int rank = d.getRank(); 1576 if (rank <= 0) { 1577 try { 1578 d.init(); 1579 log.trace("createTable: d.inited"); 1580 } 1581 catch (Exception ex) { 1582 JOptionPane.showMessageDialog(this, ex, "createTable:" + getTitle(), JOptionPane.ERROR_MESSAGE); 1583 dataValue = null; 1584 return null; 1585 } 1586 1587 rank = d.getRank(); 1588 } 1589 long[] dims = d.getSelectedDims(); 1590 1591 rows = (int) dims[0]; 1592 cols = 1; 1593 if (rank > 1) { 1594 rows = d.getHeight(); 1595 cols = d.getWidth(); 1596 } 1597 1598 log.trace("createTable: rows={} : cols={}", rows, cols); 1599 dataValue = null; 1600 try { 1601 dataValue = d.getData(); 1602 if (dataValue == null) { 1603 JOptionPane.showMessageDialog(this, "No data read", "ScalarDS createTable:" + getTitle(), 1604 JOptionPane.WARNING_MESSAGE); 1605 return null; 1606 } 1607 1608 log.trace("createTable: dataValue={}", dataValue); 1609 if (Tools.applyBitmask(dataValue, bitmask, bitmaskOP)) { 1610 isReadOnly = true; 1611 String opName = "Bits "; 1612 1613 if (bitmaskOP == ViewProperties.BITMASK_OP.AND) opName = "Bitwise AND "; 1614 1615 JPanel contentpane = (JPanel) getContentPane(); 1616 Border border = contentpane.getBorder(); 1617 1618 String btitle = ((TitledBorder) border).getTitle(); 1619 btitle += ", " + opName + bitmask; 1620 ((TitledBorder) border).setTitle(btitle); 1621 } 1622 1623 d.convertFromUnsignedC(); 1624 dataValue = d.getData(); 1625 1626 if (Array.getLength(dataValue) <= rows) cols = 1; 1627 } 1628 catch (Throwable ex) { 1629 JOptionPane.showMessageDialog(this, ex, "ScalarDS createTable:" + getTitle(), JOptionPane.ERROR_MESSAGE); 1630 dataValue = null; 1631 } 1632 1633 if (dataValue == null) { 1634 return null; 1635 } 1636 1637 fillValue = d.getFillValue(); 1638 log.trace("createTable: fillValue={}", fillValue); 1639 1640 String cName = dataValue.getClass().getName(); 1641 int cIndex = cName.lastIndexOf("["); 1642 if (cIndex >= 0) { 1643 NT = cName.charAt(cIndex + 1); 1644 } 1645 log.trace("createTable: cName={} NT={}", cName, NT); 1646 1647 // convert numerical data into char 1648 // only possible cases are byte[] and short[] (converted from unsigned 1649 // byte) 1650 if (isDisplayTypeChar && ((NT == 'B') || (NT == 'S'))) { 1651 int n = Array.getLength(dataValue); 1652 char[] charData = new char[n]; 1653 for (int i = 0; i < n; i++) { 1654 if (NT == 'B') { 1655 charData[i] = (char) Array.getByte(dataValue, i); 1656 } 1657 else if (NT == 'S') { 1658 charData[i] = (char) Array.getShort(dataValue, i); 1659 } 1660 } 1661 1662 dataValue = charData; 1663 } 1664 else if ((NT == 'B') && dataset.getDatatype().getDatatypeClass() == Datatype.CLASS_ARRAY) { 1665 Datatype baseType = dataset.getDatatype().getBasetype(); 1666 if (baseType.getDatatypeClass() == Datatype.CLASS_STRING) { 1667 dataValue = Dataset.byteToString((byte[]) dataValue, baseType.getDatatypeSize()); 1668 } 1669 } 1670 1671 final String columnNames[] = new String[cols]; 1672 final int rowCount = rows; 1673 final int colCount = cols; 1674 final long[] startArray = dataset.getStartDims(); 1675 final long[] strideArray = dataset.getStride(); 1676 int[] selectedIndex = dataset.getSelectedIndex(); 1677 final int rowStart = (int) startArray[selectedIndex[0]]; 1678 final int rowStride = (int) strideArray[selectedIndex[0]]; 1679 int start = 0; 1680 int stride = 1; 1681 1682 if (rank > 1) { 1683 start = (int) startArray[selectedIndex[1]]; 1684 stride = (int) strideArray[selectedIndex[1]]; 1685 1686 for (int i = 0; i < cols; i++) { 1687 columnNames[i] = String.valueOf(start + indexBase + i * stride); 1688 } 1689 } 1690 else { 1691 columnNames[0] = " "; 1692 } 1693 1694 AbstractTableModel tm = new AbstractTableModel() { 1695 private static final long serialVersionUID = 254175303655079056L; 1696 private final StringBuffer stringBuffer = new StringBuffer(); 1697 private final Datatype dtype = dataset.getDatatype(); 1698 private final Datatype btype = dtype.getBasetype(); 1699 private final int typeSize = dtype.getDatatypeSize(); 1700 private final boolean isArray = (dtype.getDatatypeClass() == Datatype.CLASS_ARRAY); 1701 private final boolean isStr = (NT == 'L'); 1702 private final boolean isInt = (NT == 'B' || NT == 'S' || NT == 'I' || NT == 'J'); 1703 private final boolean isUINT64 = (dtype.isUnsigned() && (NT == 'J')); 1704 private Object theValue; 1705 1706 boolean isNaturalOrder = (dataset.getRank() == 1 || (dataset.getSelectedIndex()[0] < dataset 1707 .getSelectedIndex()[1])); 1708 1709 @Override 1710 public int getColumnCount ( ) { 1711 return columnNames.length; 1712 } 1713 1714 @Override 1715 public int getRowCount ( ) { 1716 return rowCount; 1717 } 1718 1719 @Override 1720 public String getColumnName (int col) { 1721 return columnNames[col]; 1722 } 1723 1724 @Override 1725 public Object getValueAt (int row, int column) { 1726 if (startEditing[0]) return ""; 1727 log.trace("ScalarDS:createTable:AbstractTableModel:getValueAt({},{}) start", row, column); 1728 log.trace("ScalarDS:createTable:AbstractTableModel:getValueAt isInt={} isArray={} showAsHex={} showAsBin={}", 1729 isInt, isArray, showAsHex, showAsBin); 1730 1731 if (isArray) { 1732 // ARRAY dataset 1733 int arraySize = dtype.getDatatypeSize() / btype.getDatatypeSize(); 1734 log.trace( 1735 "ScalarDS:createTable:AbstractTableModel:getValueAt ARRAY dataset size={} isDisplayTypeChar={} isUINT64={}", 1736 arraySize, isDisplayTypeChar, isUINT64); 1737 1738 stringBuffer.setLength(0); // clear the old string 1739 int i0 = (row * colCount + column) * arraySize; 1740 int i1 = i0 + arraySize; 1741 1742 if (isDisplayTypeChar) { 1743 for (int i = i0; i < i1; i++) { 1744 stringBuffer.append(Array.getChar(dataValue, i)); 1745 if (stringBuffer.length() > 0 && i < (i1 - 1)) stringBuffer.append(", "); 1746 } 1747 } 1748 else { 1749 if (isUINT64) { 1750 // array of unsigned longs 1751 for (int i = i0; i < i1; i++) { 1752 Long l = (Long) Array.get(dataValue, i); 1753 BigInteger big; 1754 if (l < 0) { 1755 l = (l << 1) >>> 1; 1756 BigInteger big1 = new BigInteger("9223372036854775808"); // 2^65 1757 BigInteger big2 = new BigInteger(l.toString()); 1758 big = big1.add(big2); 1759 } 1760 else { 1761 big = new BigInteger(l.toString()); 1762 } 1763 if (showAsHex) 1764 theValue = Tools.toHexString(big.longValue(), 8); 1765 else if (showAsBin) 1766 theValue = Tools.toBinaryString(big.longValue(), 8); 1767 else 1768 theValue = big.toString(10); 1769 1770 stringBuffer.append(theValue); 1771 if (stringBuffer.length() > 0 && i < (i1 - 1)) stringBuffer.append(", "); 1772 } 1773 } 1774 else { 1775 for (int i = i0; i < i1; i++) { 1776 theValue = Array.get(dataValue, i); 1777 if (showAsHex) 1778 theValue = Tools.toHexString(Long.valueOf(theValue.toString()), typeSize / arraySize); 1779 else if (showAsBin) 1780 theValue = Tools.toBinaryString(Long.valueOf(theValue.toString()), typeSize / arraySize); 1781 else 1782 theValue = theValue.toString(); 1783 1784 stringBuffer.append(theValue); 1785 1786 if (stringBuffer.length() > 0 && i < (i1 - 1)) 1787 stringBuffer.append(", "); 1788 } 1789 } 1790 } 1791 theValue = stringBuffer; 1792 } 1793 else { 1794 // not an array 1795 int index = column * rowCount + row; 1796 1797 if (dataset.getRank() > 1) { 1798 log.trace( 1799 "ScalarDS:createTable:AbstractTableModel:getValueAt rank={} isDataTransposed={} isNaturalOrder={}", 1800 dataset.getRank(), isDataTransposed, isNaturalOrder); 1801 if ((isDataTransposed && isNaturalOrder) || (!isDataTransposed && !isNaturalOrder)) 1802 index = column * rowCount + row; 1803 else 1804 index = row * colCount + column; 1805 } 1806 log.trace("ScalarDS:createTable:AbstractTableModel:getValueAt index={} isStr={} isUINT64={}", index, isStr, 1807 isUINT64); 1808 1809 if (isStr) { 1810 theValue = Array.get(dataValue, index); 1811 return theValue; 1812 } 1813 1814 if (isUINT64) { 1815 theValue = Array.get(dataValue, index); 1816 Long l = (Long) theValue; 1817 BigInteger big; 1818 if (l < 0) { 1819 l = (l << 1) >>> 1; 1820 BigInteger big1 = new BigInteger("9223372036854775808"); // 2^65 1821 BigInteger big2 = new BigInteger(l.toString()); 1822 big = big1.add(big2); 1823 } 1824 else { 1825 big = new BigInteger(l.toString()); 1826 } 1827 if (showAsHex) 1828 theValue = Tools.toHexString(big.longValue(), 8);// big.toString(16); 1829 else if (showAsBin) 1830 theValue = Tools.toBinaryString(big.longValue(), 8); 1831 else 1832 theValue = big.toString(10); 1833 } 1834 else if (showAsHex && isInt) { 1835 // show in Hexadecimal 1836 theValue = Array.get(dataValue, index); 1837 theValue = Tools.toHexString(Long.valueOf(theValue.toString()), typeSize); 1838 } 1839 else if (showAsBin && isInt) { 1840 theValue = Array.get(dataValue, index); 1841 theValue = Tools.toBinaryString(Long.valueOf(theValue.toString()), typeSize); 1842 } 1843 else if (numberFormat != null) { 1844 // show in scientific format 1845 theValue = Array.get(dataValue, index); 1846 theValue = numberFormat.format(theValue); 1847 } 1848 else { 1849 theValue = Array.get(dataValue, index); 1850 } 1851 } 1852 1853 log.trace("ScalarDS:createTable:AbstractTableModel:getValueAt finish"); 1854 return theValue; 1855 } // getValueAt(int row, int column) 1856 }; 1857 1858 theTable = new JTable(tm) { 1859 private static final long serialVersionUID = -145476220959400488L; 1860 private final Datatype dtype = dataset.getDatatype(); 1861 private final boolean isArray = (dtype.getDatatypeClass() == Datatype.CLASS_ARRAY); 1862 1863 @Override 1864 public boolean isCellEditable (int row, int col) { 1865 if (isReadOnly || isDisplayTypeChar || isArray || showAsBin || showAsHex) { 1866 return false; 1867 } 1868 else { 1869 return true; 1870 } 1871 } 1872 1873 @Override 1874 public boolean editCellAt (int row, int column, java.util.EventObject e) { 1875 if (!isCellEditable(row, column)) { 1876 return super.editCellAt(row, column, e); 1877 } 1878 1879 if (e instanceof KeyEvent) { 1880 KeyEvent ke = (KeyEvent) e; 1881 if (ke.getID() == KeyEvent.KEY_PRESSED) { 1882 startEditing[0] = true; 1883 } 1884 } 1885 else if (e instanceof MouseEvent) { 1886 MouseEvent me = (MouseEvent) e; 1887 int mc = me.getClickCount(); 1888 if (mc > 1) { 1889 currentEditingCellValue = getValueAt(row, column); 1890 } 1891 } 1892 1893 return super.editCellAt(row, column, e); 1894 } 1895 1896 @Override 1897 public void editingStopped (ChangeEvent e) { 1898 int row = getEditingRow(); 1899 int col = getEditingColumn(); 1900 super.editingStopped(e); 1901 startEditing[0] = false; 1902 1903 Object source = e.getSource(); 1904 1905 if (source instanceof CellEditor) { 1906 CellEditor editor = (CellEditor) source; 1907 String cellValue = (String) editor.getCellEditorValue(); 1908 1909 try { 1910 updateValueInMemory(cellValue, row, col); 1911 } 1912 catch (Exception ex) { 1913 toolkit.beep(); 1914 JOptionPane.showMessageDialog(this, ex, getTitle(), JOptionPane.ERROR_MESSAGE); 1915 } 1916 } // if (source instanceof CellEditor) 1917 } 1918 1919 @Override 1920 public boolean isCellSelected (int row, int column) { 1921 if ((getSelectedRow() == row) && (getSelectedColumn() == column)) { 1922 cellLabel.setText(String.valueOf(rowStart + indexBase + row * rowStride) + ", " + table.getColumnName(column) 1923 + " = "); 1924 1925 log.trace("JTable.ScalarDS isCellSelected isRegRef={} isObjRef={}", isRegRef, isObjRef); 1926 Object val = getValueAt(row, column); 1927 String strVal = null; 1928 1929 if (isRegRef) { 1930 boolean displayValues = ViewProperties.showRegRefValues(); 1931 log.trace("JTable.ScalarDS isCellSelected displayValues={}", displayValues); 1932 if (displayValues && val != null && ((String) val).compareTo("NULL") != 0) { 1933 String reg = (String) val; 1934 boolean isPointSelection = (reg.indexOf('-') <= 0); 1935 1936 // find the object location 1937 String oidStr = reg.substring(reg.indexOf('/'), reg.indexOf(' ')); 1938 log.trace("JTable.ScalarDS isCellSelected: isPointSelection={} oidStr={}", isPointSelection, oidStr); 1939 1940 // decode the region selection 1941 String regStr = reg.substring(reg.indexOf('{') + 1, reg.indexOf('}')); 1942 if (regStr == null || regStr.length() <= 0) { // no 1943 // selection 1944 strVal = null; 1945 } 1946 else { 1947 reg.substring(reg.indexOf('}') + 1); 1948 1949 StringTokenizer st = new StringTokenizer(regStr); 1950 int nSelections = st.countTokens(); 1951 if (nSelections <= 0) { // no selection 1952 strVal = null; 1953 } 1954 else { 1955 log.trace("JTable.ScalarDS isCellSelected: nSelections={}", nSelections); 1956 1957 HObject obj = FileFormat.findObject(dataset.getFileFormat(), oidStr); 1958 if (obj == null || !(obj instanceof ScalarDS)) { // no 1959 // selection 1960 strVal = null; 1961 } 1962 else { 1963 ScalarDS dset = (ScalarDS) obj; 1964 try { 1965 dset.init(); 1966 } 1967 catch (Exception ex) { 1968 log.debug("reference dset did not init()", ex); 1969 } 1970 StringBuffer selectionSB = new StringBuffer(); 1971 StringBuffer strvalSB = new StringBuffer(); 1972 1973 int idx = 0; 1974 while (st.hasMoreTokens()) { 1975 log.trace("JTable.ScalarDS isCellSelected: st.hasMoreTokens() begin"); 1976 1977 int rank = dset.getRank(); 1978 long start[] = dset.getStartDims(); 1979 long count[] = dset.getSelectedDims(); 1980 // long count[] = new long[rank]; 1981 1982 // set the selected dimension sizes 1983 // based on the region selection 1984 // info. 1985 String sizeStr = null; 1986 String token = st.nextToken(); 1987 1988 selectionSB.setLength(0); 1989 selectionSB.append(token); 1990 log.trace("JTable.ScalarDS isCellSelected: selectionSB={}", selectionSB); 1991 1992 token = token.replace('(', ' '); 1993 token = token.replace(')', ' '); 1994 if (isPointSelection) { 1995 // point selection 1996 String[] tmp = token.split(","); 1997 for (int x = 0; x < tmp.length; x++) { 1998 count[x] = 1; 1999 sizeStr = tmp[x].trim(); 2000 start[x] = Long.valueOf(sizeStr); 2001 log.trace("JTable.ScalarDS isCellSelected: point sel={}", tmp[x]); 2002 } 2003 } 2004 else { 2005 // rectangle selection 2006 String startStr = token.substring(0, token.indexOf('-')); 2007 String endStr = token.substring(token.indexOf('-') + 1); 2008 log.trace("JTable.ScalarDS isCellSelected: rect sel with startStr={} endStr={}", 2009 startStr, endStr); 2010 String[] tmp = startStr.split(","); 2011 log.trace("JTable.ScalarDS isCellSelected: tmp with length={} rank={}", tmp.length, 2012 rank); 2013 for (int x = 0; x < tmp.length; x++) { 2014 sizeStr = tmp[x].trim(); 2015 start[x] = Long.valueOf(sizeStr); 2016 log.trace("JTable.ScalarDS isCellSelected: rect start={}", tmp[x]); 2017 } 2018 tmp = endStr.split(","); 2019 for (int x = 0; x < tmp.length; x++) { 2020 sizeStr = tmp[x].trim(); 2021 count[x] = Long.valueOf(sizeStr) - start[x] + 1; 2022 log.trace("JTable.ScalarDS isCellSelected: rect end={} count={}", tmp[x], 2023 count[x]); 2024 } 2025 } 2026 log.trace("JTable.ScalarDS isCellSelected: selection inited"); 2027 2028 Object dbuf = null; 2029 try { 2030 dbuf = dset.getData(); 2031 } 2032 catch (Exception ex) { 2033 JOptionPane.showMessageDialog(this, ex, "Region Reference:" + getTitle(), 2034 JOptionPane.ERROR_MESSAGE); 2035 } 2036 2037 // Convert dbuf to a displayable 2038 // string 2039 String cName = dbuf.getClass().getName(); 2040 int cIndex = cName.lastIndexOf("["); 2041 if (cIndex >= 0) { 2042 NT = cName.charAt(cIndex + 1); 2043 } 2044 log.trace("JTable.ScalarDS isCellSelected: cName={} NT={}", cName, NT); 2045 2046 if (idx > 0) strvalSB.append(','); 2047 2048 // convert numerical data into char 2049 // only possible cases are byte[] 2050 // and short[] (converted from 2051 // unsigned 2052 // byte) 2053 Datatype dtype = dset.getDatatype(); 2054 Datatype baseType = dtype.getBasetype(); 2055 log.trace("JTable.ScalarDS isCellSelected: dtype={} baseType={}", 2056 dtype.getDatatypeDescription(), baseType); 2057 if (baseType == null) baseType = dtype; 2058 if ((dtype.getDatatypeClass() == Datatype.CLASS_ARRAY && baseType.getDatatypeClass() == Datatype.CLASS_CHAR) 2059 && ((NT == 'B') || (NT == 'S'))) { 2060 int n = Array.getLength(dbuf); 2061 log.trace("JTable.ScalarDS isCellSelected charData length = {}", n); 2062 char[] charData = new char[n]; 2063 for (int i = 0; i < n; i++) { 2064 if (NT == 'B') { 2065 charData[i] = (char) Array.getByte(dbuf, i); 2066 } 2067 else if (NT == 'S') { 2068 charData[i] = (char) Array.getShort(dbuf, i); 2069 } 2070 } 2071 2072 strvalSB.append(charData); 2073 log.trace("JTable.ScalarDS isCellSelected charData");// = 2074 // {}", 2075 // strvalSB); 2076 } 2077 else { 2078 // numerical values 2079 if (dtype.getDatatypeClass() == Datatype.CLASS_ARRAY) dtype = baseType; 2080 boolean is_unsigned = dtype.isUnsigned(); 2081 int n = Array.getLength(dbuf); 2082 if (is_unsigned) { 2083 switch (NT) { 2084 case 'B': 2085 byte[] barray = (byte[]) dbuf; 2086 short sValue = barray[0]; 2087 if (sValue < 0) { 2088 sValue += 256; 2089 } 2090 strvalSB.append(sValue); 2091 for (int i = 1; i < n; i++) { 2092 strvalSB.append(','); 2093 sValue = barray[i]; 2094 if (sValue < 0) { 2095 sValue += 256; 2096 } 2097 strvalSB.append(sValue); 2098 } 2099 break; 2100 case 'S': 2101 short[] sarray = (short[]) dbuf; 2102 int iValue = sarray[0]; 2103 if (iValue < 0) { 2104 iValue += 65536; 2105 } 2106 strvalSB.append(iValue); 2107 for (int i = 1; i < n; i++) { 2108 strvalSB.append(','); 2109 iValue = sarray[i]; 2110 if (iValue < 0) { 2111 iValue += 65536; 2112 } 2113 strvalSB.append(iValue); 2114 } 2115 break; 2116 case 'I': 2117 int[] iarray = (int[]) dbuf; 2118 long lValue = iarray[0]; 2119 if (lValue < 0) { 2120 lValue += 4294967296L; 2121 } 2122 strvalSB.append(lValue); 2123 for (int i = 1; i < n; i++) { 2124 strvalSB.append(','); 2125 lValue = iarray[i]; 2126 if (lValue < 0) { 2127 lValue += 4294967296L; 2128 } 2129 strvalSB.append(lValue); 2130 } 2131 break; 2132 case 'J': 2133 long[] larray = (long[]) dbuf; 2134 Long l = (Long) larray[0]; 2135 String theValue = Long.toString(l); 2136 if (l < 0) { 2137 l = (l << 1) >>> 1; 2138 BigInteger big1 = new BigInteger("9223372036854775808"); // 2^65 2139 BigInteger big2 = new BigInteger(l.toString()); 2140 BigInteger big = big1.add(big2); 2141 theValue = big.toString(); 2142 } 2143 strvalSB.append(theValue); 2144 for (int i = 1; i < n; i++) { 2145 strvalSB.append(','); 2146 l = (Long) larray[i]; 2147 theValue = Long.toString(l); 2148 if (l < 0) { 2149 l = (l << 1) >>> 1; 2150 BigInteger big1 = new BigInteger("9223372036854775808"); // 2^65 2151 BigInteger big2 = new BigInteger(l.toString()); 2152 BigInteger big = big1.add(big2); 2153 theValue = big.toString(); 2154 } 2155 strvalSB.append(theValue); 2156 } 2157 break; 2158 default: 2159 strvalSB.append(Array.get(dbuf, 0)); 2160 for (int i = 1; i < n; i++) { 2161 strvalSB.append(','); 2162 strvalSB.append(Array.get(dbuf, i)); 2163 } 2164 break; 2165 } 2166 } 2167 else { 2168 for (int x = 0; x < n; x++) { 2169 Object theValue = Array.get(dbuf, x); 2170 if (x > 0) strvalSB.append(','); 2171 strvalSB.append(theValue); 2172 } 2173 } 2174 log.trace("JTable.ScalarDS isCellSelected byteString");// = 2175 // {}", 2176 // strvalSB); 2177 } 2178 idx++; 2179 dset.clearData(); 2180 log.trace("JTable.ScalarDS isCellSelected: st.hasMoreTokens() end");// strvalSB 2181 // = 2182 // {}", 2183 // strvalSB); 2184 } // while (st.hasMoreTokens()) 2185 strVal = strvalSB.toString(); 2186 log.trace("JTable.ScalarDS isCellSelected: st.hasMoreTokens() end");// value 2187 // = 2188 // {}", 2189 // strVal); 2190 } 2191 } 2192 } 2193 } 2194 else { 2195 strVal = null; 2196 } 2197 } 2198 else if (isObjRef) { 2199 Long ref = (Long) val; 2200 long oid[] = { ref.longValue() }; 2201 2202 // decode object ID 2203 try { 2204 HObject obj = FileFormat.findObject(dataset.getFileFormat(), oid); 2205 strVal = obj.getFullName(); 2206 } 2207 catch (Exception ex) { 2208 strVal = null; 2209 } 2210 } 2211 2212 if (strVal == null && val != null) strVal = val.toString(); 2213 2214 log.trace("JTable.ScalarDS isCellSelected finish");// value 2215 // = 2216 // {}",strVal); 2217 cellValueField.setText(strVal); 2218 } 2219 2220 return super.isCellSelected(row, column); 2221 } 2222 }; 2223 theTable.setName("ScalarDS"); 2224 2225 log.trace("createTable: ScalarDS finish"); 2226 return theTable; 2227 } 2228 2229 /** 2230 * Creates a JTable to hold a compound dataset. 2231 */ 2232 private JTable createTable (CompoundDS d) { 2233 JTable theTable = null; 2234 log.trace("createTable: CompoundDS start"); 2235 2236 int rank = d.getRank(); 2237 if (rank <= 0) { 2238 d.init(); 2239 } 2240 2241 long[] startArray = d.getStartDims(); 2242 long[] strideArray = d.getStride(); 2243 int[] selectedIndex = d.getSelectedIndex(); 2244 final int rowStart = (int) startArray[selectedIndex[0]]; 2245 final int rowStride = (int) strideArray[selectedIndex[0]]; 2246 2247 // use lazy convert for large number of strings 2248 if (d.getHeight() > 10000) { 2249 d.setConvertByteToString(false); 2250 } 2251 2252 dataValue = null; 2253 try { 2254 dataValue = d.getData(); 2255 } 2256 catch (Throwable ex) { 2257 toolkit.beep(); 2258 JOptionPane.showMessageDialog(this, ex, "TableView" + getTitle(), JOptionPane.ERROR_MESSAGE); 2259 dataValue = null; 2260 } 2261 2262 if ((dataValue == null) || !(dataValue instanceof List)) { 2263 return null; 2264 } 2265 2266 final int rows = d.getHeight(); 2267 int cols = d.getSelectedMemberCount(); 2268 String[] columnNames = new String[cols]; 2269 2270 int idx = 0; 2271 String[] columnNamesAll = d.getMemberNames(); 2272 for (int i = 0; i < columnNamesAll.length; i++) { 2273 if (d.isMemberSelected(i)) { 2274 columnNames[idx] = columnNamesAll[i]; 2275 columnNames[idx] = columnNames[idx].replaceAll(CompoundDS.separator, "->"); 2276 idx++; 2277 } 2278 } 2279 2280 String[] subColumnNames = columnNames; 2281 int columns = d.getWidth(); 2282 if (columns > 1) { 2283 // multi-dimension compound dataset 2284 subColumnNames = new String[columns * columnNames.length]; 2285 int halfIdx = columnNames.length / 2; 2286 for (int i = 0; i < columns; i++) { 2287 for (int j = 0; j < columnNames.length; j++) { 2288 // display column index only once, in the middle of the 2289 // compound fields 2290 if (j == halfIdx) { 2291 // subColumnNames[i * columnNames.length + j] = (i + 1) 2292 // + "\n " + columnNames[j]; 2293 subColumnNames[i * columnNames.length + j] = (i + indexBase) + "\n " + columnNames[j]; 2294 } 2295 else { 2296 subColumnNames[i * columnNames.length + j] = " \n " + columnNames[j]; 2297 } 2298 } 2299 } 2300 } 2301 2302 final String[] allColumnNames = subColumnNames; 2303 AbstractTableModel tm = new AbstractTableModel() { 2304 private static final long serialVersionUID = -2176296469630678304L; 2305 CompoundDS compound = (CompoundDS) dataset; 2306 int orders[] = compound.getSelectedMemberOrders(); 2307 Datatype types[] = compound.getSelectedMemberTypes(); 2308 StringBuffer stringBuffer = new StringBuffer(); 2309 int nFields = ((List<?>) dataValue).size(); 2310 int nRows = getRowCount(); 2311 int nSubColumns = (nFields > 0) ? getColumnCount() / nFields : 0; 2312 2313 @Override 2314 public int getColumnCount ( ) { 2315 return allColumnNames.length; 2316 } 2317 2318 @Override 2319 public int getRowCount ( ) { 2320 return rows; 2321 } 2322 2323 @Override 2324 public String getColumnName (int col) { 2325 return allColumnNames[col]; 2326 } 2327 2328 @Override 2329 public Object getValueAt (int row, int col) { 2330 if (startEditing[0]) return ""; 2331 2332 int fieldIdx = col; 2333 int rowIdx = row; 2334 char CNT = ' '; 2335 boolean CshowAsHex = false; 2336 boolean CshowAsBin = false; 2337 log.trace("CompoundDS:createTable:AbstractTableModel:getValueAt({},{}) start", row, col); 2338 2339 if (nSubColumns > 1) { // multi-dimension compound dataset 2340 int colIdx = col / nFields; 2341 fieldIdx = col - colIdx * nFields; 2342 // BUG 573: rowIdx = row * orders[fieldIdx] + colIdx * nRows 2343 // * orders[fieldIdx]; 2344 rowIdx = row * orders[fieldIdx] * nSubColumns + colIdx * orders[fieldIdx]; 2345 log.trace( 2346 "CompoundDS:createTable:AbstractTableModel:getValueAt() row={} orders[{}]={} nSubColumns={} colIdx={}", 2347 row, fieldIdx, orders[fieldIdx], nSubColumns, colIdx); 2348 } 2349 else { 2350 rowIdx = row * orders[fieldIdx]; 2351 log.trace("CompoundDS:createTable:AbstractTableModel:getValueAt() row={} orders[{}]={}", row, fieldIdx, 2352 orders[fieldIdx]); 2353 } 2354 log.trace("CompoundDS:createTable:AbstractTableModel:getValueAt() rowIdx={}", rowIdx); 2355 2356 Object colValue = ((List<?>) dataValue).get(fieldIdx); 2357 if (colValue == null) { 2358 return "Null"; 2359 } 2360 2361 stringBuffer.setLength(0); // clear the old string 2362 Datatype dtype = types[fieldIdx]; 2363 boolean isString = (dtype.getDatatypeClass() == Datatype.CLASS_STRING); 2364 boolean isArray = (dtype.getDatatypeClass() == Datatype.CLASS_ARRAY); 2365 if (isArray) { 2366 dtype = types[fieldIdx].getBasetype(); 2367 isString = (dtype.getDatatypeClass() == Datatype.CLASS_STRING); 2368 log.trace("**CompoundDS:createTable:AbstractTableModel:getValueAt(): isArray={} isString={}", isArray, isString); 2369 } 2370 log.trace("CompoundDS:createTable:AbstractTableModel:getValueAt(): isString={} getBasetype()={}", isString, types[fieldIdx].getDatatypeClass()); 2371 if (isString && ((colValue instanceof byte[]) || isArray)) { 2372 // strings 2373 int strlen = dtype.getDatatypeSize(); 2374 int arraylen = strlen; 2375 if(isArray) { 2376 arraylen = types[fieldIdx].getDatatypeSize(); 2377 } 2378 log.trace("**CompoundDS:createTable:AbstractTableModel:getValueAt(): isArray={} of {} isString={} of {}", isArray, arraylen, isString, strlen); 2379 int arraycnt = arraylen / strlen; 2380 for (int loopidx = 0; loopidx < arraycnt; loopidx++) { 2381 if(isArray && loopidx > 0) { 2382 stringBuffer.append(", "); 2383 } 2384 String str = new String(((byte[]) colValue), rowIdx * strlen + loopidx * strlen, strlen); 2385 int idx = str.indexOf('\0'); 2386 if (idx > 0) { 2387 str = str.substring(0, idx); 2388 } 2389 stringBuffer.append(str.trim()); 2390 } 2391 } 2392 else { 2393 // numerical values 2394 2395 String cName = colValue.getClass().getName(); 2396 int cIndex = cName.lastIndexOf("["); 2397 if (cIndex >= 0) { 2398 CNT = cName.charAt(cIndex + 1); 2399 } 2400 log.trace("CompoundDS:createTable:AbstractTableModel:getValueAt(): cName={} CNT={}", cName, CNT); 2401 2402 boolean isUINT64 = false; 2403 boolean isInt = (CNT == 'B' || CNT == 'S' || CNT == 'I' || CNT == 'J'); 2404 int typeSize = dtype.getDatatypeSize(); 2405 2406 if ((dtype.getDatatypeClass() == Datatype.CLASS_BITFIELD) 2407 || (dtype.getDatatypeClass() == Datatype.CLASS_OPAQUE)) { 2408 CshowAsHex = true; 2409 log.trace("CompoundDS:createTable:AbstractTableModel:getValueAt() class={} (BITFIELD or OPAQUE)", 2410 dtype.getDatatypeClass()); 2411 } 2412 if (dtype.isUnsigned()) { 2413 if (cIndex >= 0) { 2414 isUINT64 = (cName.charAt(cIndex + 1) == 'J'); 2415 } 2416 } 2417 log.trace( 2418 "CompoundDS:createTable:AbstractTableModel:getValueAt() isUINT64={} isInt={} CshowAsHex={} typeSize={}", 2419 isUINT64, isInt, CshowAsHex, typeSize); 2420 2421 for (int i = 0; i < orders[fieldIdx]; i++) { 2422 if (isUINT64) { 2423 Object theValue = Array.get(colValue, rowIdx + i); 2424 log.trace("CompoundDS:createTable:AbstractTableModel:getValueAt() isUINT64 theValue[{}]={}", i, 2425 theValue.toString()); 2426 Long l = (Long) theValue; 2427 BigInteger big; 2428 if (l < 0) { 2429 l = (l << 1) >>> 1; 2430 BigInteger big1 = new BigInteger("9223372036854775808"); // 2^65 2431 BigInteger big2 = new BigInteger(l.toString()); 2432 big = big1.add(big2); 2433 } 2434 else { 2435 big = new BigInteger(l.toString()); 2436 } 2437 if (showAsHex) 2438 theValue = Tools.toHexString(big.longValue(), typeSize);// big.toString(16); 2439 else if (showAsBin) 2440 theValue = Tools.toBinaryString(big.longValue(), typeSize); 2441 else 2442 theValue = big.toString(10); 2443 2444 if (i > 0) stringBuffer.append(", "); 2445 stringBuffer.append(theValue); 2446 } 2447 else if (CshowAsHex && isInt) { 2448 char[] hexArray = "0123456789ABCDEF".toCharArray(); 2449 Object theValue = Array.get(colValue, rowIdx * typeSize + typeSize * i); 2450 log.trace("CompoundDS:createTable:AbstractTableModel:getValueAt() CshowAsHex theValue[{}]={}", i, 2451 theValue.toString()); 2452 // show in Hexadecimal 2453 char[] hexChars = new char[2]; 2454 if (i > 0) stringBuffer.append(", "); 2455 for (int x = 0; x < typeSize; x++) { 2456 if (x > 0) 2457 theValue = Array.get(colValue, rowIdx * typeSize + typeSize * i + x); 2458 int v = (int) ((Byte) theValue) & 0xFF; 2459 hexChars[0] = hexArray[v >>> 4]; 2460 hexChars[1] = hexArray[v & 0x0F]; 2461 if (x > 0) stringBuffer.append(":"); 2462 stringBuffer.append(hexChars); 2463 log.trace("CompoundDS:createTable:AbstractTableModel:getValueAt() hexChars[{}]={}", x, hexChars); 2464 } 2465 } 2466 else if (showAsBin && isInt) { 2467 Object theValue = Array.get(colValue, rowIdx + typeSize * i); 2468 log.trace("CompoundDS:createTable:AbstractTableModel:getValueAt() showAsBin theValue[{}]={}", i, 2469 theValue.toString()); 2470 theValue = Tools.toBinaryString(Long.valueOf(theValue.toString()), typeSize); 2471 if (i > 0) stringBuffer.append(", "); 2472 stringBuffer.append(theValue); 2473 } 2474 else if (numberFormat != null) { 2475 // show in scientific format 2476 Object theValue = Array.get(colValue, rowIdx + i); 2477 log.trace("CompoundDS:createTable:AbstractTableModel:getValueAt() numberFormat theValue[{}]={}", i, 2478 theValue.toString()); 2479 theValue = numberFormat.format(theValue); 2480 if (i > 0) stringBuffer.append(", "); 2481 stringBuffer.append(theValue); 2482 } 2483 else { 2484 Object theValue = Array.get(colValue, rowIdx + i); 2485 log.trace("CompoundDS:createTable:AbstractTableModel:getValueAt() theValue[{}]={}", i, 2486 theValue.toString()); 2487 if (i > 0) stringBuffer.append(", "); 2488 stringBuffer.append(theValue); 2489 } 2490 } 2491 } // end of else { 2492 2493 return stringBuffer; 2494 } 2495 }; 2496 2497 theTable = new JTable(tm) { 2498 private static final long serialVersionUID = 3221288637329958074L; 2499 int lastSelectedRow = -1; 2500 int lastSelectedColumn = -1; 2501 2502 @Override 2503 public boolean isCellEditable (int row, int column) { 2504 return !isReadOnly; 2505 } 2506 2507 @Override 2508 public boolean editCellAt (int row, int column, java.util.EventObject e) { 2509 if (!isCellEditable(row, column)) { 2510 return super.editCellAt(row, column, e); 2511 } 2512 2513 if (e instanceof KeyEvent) { 2514 KeyEvent ke = (KeyEvent) e; 2515 if (ke.getID() == KeyEvent.KEY_PRESSED) startEditing[0] = true; 2516 } 2517 else if (e instanceof MouseEvent) { 2518 MouseEvent me = (MouseEvent) e; 2519 int mc = me.getClickCount(); 2520 if (mc > 1) { 2521 currentEditingCellValue = getValueAt(row, column); 2522 } 2523 } 2524 2525 return super.editCellAt(row, column, e); 2526 } 2527 2528 @Override 2529 public void editingStopped (ChangeEvent e) { 2530 int row = getEditingRow(); 2531 int col = getEditingColumn(); 2532 super.editingStopped(e); 2533 startEditing[0] = false; 2534 2535 Object source = e.getSource(); 2536 2537 if (source instanceof CellEditor) { 2538 CellEditor editor = (CellEditor) source; 2539 String cellValue = (String) editor.getCellEditorValue(); 2540 2541 try { 2542 updateValueInMemory(cellValue, row, col); 2543 } 2544 catch (Exception ex) { 2545 toolkit.beep(); 2546 JOptionPane.showMessageDialog(this, ex, getTitle(), JOptionPane.ERROR_MESSAGE); 2547 } 2548 } // if (source instanceof CellEditor) 2549 } 2550 2551 @Override 2552 public boolean isCellSelected (int row, int column) { 2553 if ((lastSelectedRow == row) && (lastSelectedColumn == column)) { 2554 return super.isCellSelected(row, column); 2555 } 2556 log.trace("JTable.CompoundDS isCellSelected row={} column={}", row, column); 2557 2558 lastSelectedRow = row; 2559 lastSelectedColumn = column; 2560 if ((getSelectedRow() == row) && (getSelectedColumn() == column)) { 2561 cellLabel.setText(String.valueOf(rowStart + indexBase + row * rowStride) + ", " + table.getColumnName(column) 2562 + " = "); 2563 cellValueField.setText(getValueAt(row, column).toString()); 2564 } 2565 2566 return super.isCellSelected(row, column); 2567 } 2568 }; 2569 2570 if (columns > 1) { 2571 // multi-dimension compound dataset 2572 MultiLineHeaderRenderer renderer = new MultiLineHeaderRenderer(columns, columnNames.length); 2573 Enumeration<?> local_enum = theTable.getColumnModel().getColumns(); 2574 while (local_enum.hasMoreElements()) { 2575 ((TableColumn) local_enum.nextElement()).setHeaderRenderer(renderer); 2576 } 2577 } 2578 theTable.setName("CompoundDS"); 2579 2580 log.trace("createTable: CompoundDS finish"); 2581 return theTable; 2582 } /* createTable */ 2583 2584 private void gotoPage (long idx) { 2585 if (dataset.getRank() < 3 || idx == (curFrame - indexBase)) { 2586 return; 2587 } 2588 2589 if (isValueChanged) { 2590 updateValueInFile(); 2591 } 2592 2593 long[] start = dataset.getStartDims(); 2594 int[] selectedIndex = dataset.getSelectedIndex(); 2595 long[] dims = dataset.getDims(); 2596 2597 if ((idx < 0) || (idx >= dims[selectedIndex[2]])) { 2598 toolkit.beep(); 2599 JOptionPane.showMessageDialog(this, "Frame number must be between" + indexBase + " and " 2600 + (dims[selectedIndex[2]] - 1 + indexBase), getTitle(), JOptionPane.ERROR_MESSAGE); 2601 return; 2602 } 2603 2604 start[selectedIndex[2]] = idx; 2605 curFrame = idx + indexBase; 2606 dataset.clearData(); 2607 2608 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 2609 2610 try { 2611 dataValue = dataset.getData(); 2612 if (dataset instanceof ScalarDS) { 2613 ((ScalarDS) dataset).convertFromUnsignedC(); 2614 dataValue = dataset.getData(); 2615 } 2616 } 2617 catch (Exception ex) { 2618 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 2619 dataValue = null; 2620 JOptionPane.showMessageDialog(this, ex, getTitle(), JOptionPane.ERROR_MESSAGE); 2621 return; 2622 } 2623 2624 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 2625 2626 frameField.setText(String.valueOf(curFrame)); 2627 updateUI(); 2628 } 2629 2630 /** copy data from the spreadsheet to the system clipboard. */ 2631 private void copyData ( ) { 2632 StringBuffer sb = new StringBuffer(); 2633 2634 int r0 = table.getSelectedRow(); // starting row 2635 int c0 = table.getSelectedColumn(); // starting column 2636 2637 if ((r0 < 0) || (c0 < 0)) { 2638 return; 2639 } 2640 2641 int nr = table.getSelectedRowCount(); 2642 int nc = table.getSelectedColumnCount(); 2643 int r1 = r0 + nr; // finish row 2644 int c1 = c0 + nc; // finishing column 2645 2646 try { 2647 for (int i = r0; i < r1; i++) { 2648 sb.append(table.getValueAt(i, c0).toString()); 2649 for (int j = c0 + 1; j < c1; j++) { 2650 sb.append("\t"); 2651 sb.append(table.getValueAt(i, j).toString()); 2652 } 2653 sb.append("\n"); 2654 } 2655 } 2656 catch (java.lang.OutOfMemoryError err) { 2657 toolkit.beep(); 2658 JOptionPane.showMessageDialog((JFrame) viewer, 2659 "Copying data to system clipboard failed. \nUsing \"export/import data\" for copying/pasting large data.", 2660 getTitle(), JOptionPane.ERROR_MESSAGE); 2661 return; 2662 } 2663 2664 Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard(); 2665 StringSelection contents = new StringSelection(sb.toString()); 2666 cb.setContents(contents, null); 2667 } 2668 2669 /** paste data from the system clipboard to the spreadsheet. */ 2670 private void pasteData ( ) { 2671 int pasteDataFlag = JOptionPane.showConfirmDialog(this, "Do you want to paste selected data?", this.getTitle(), 2672 JOptionPane.YES_NO_OPTION); 2673 if (pasteDataFlag == JOptionPane.NO_OPTION) { 2674 return; 2675 } 2676 2677 int cols = table.getColumnCount(); 2678 int rows = table.getRowCount(); 2679 int r0 = table.getSelectedRow(); 2680 int c0 = table.getSelectedColumn(); 2681 2682 if (c0 < 0) { 2683 c0 = 0; 2684 } 2685 if (r0 < 0) { 2686 r0 = 0; 2687 } 2688 int r = r0; 2689 int c = c0; 2690 2691 Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard(); 2692 // Transferable content = cb.getContents(this); 2693 String line = ""; 2694 try { 2695 String s = (String) cb.getData(DataFlavor.stringFlavor); 2696 2697 StringTokenizer st = new StringTokenizer(s, "\n"); 2698 // read line by line 2699 while (st.hasMoreTokens() && (r < rows)) { 2700 line = st.nextToken(); 2701 2702 if (fixedDataLength < 1) { 2703 // separate by delimiter 2704 StringTokenizer lt = new StringTokenizer(line, "\t"); 2705 while (lt.hasMoreTokens() && (c < cols)) { 2706 try { 2707 updateValueInMemory(lt.nextToken(), r, c); 2708 } 2709 catch (Exception ex) { 2710 continue; 2711 } 2712 c++; 2713 } 2714 r = r + 1; 2715 c = c0; 2716 } 2717 else { 2718 // the data has fixed length 2719 int n = line.length(); 2720 String theVal; 2721 for (int i = 0; i < n; i = i + fixedDataLength) { 2722 try { 2723 theVal = line.substring(i, i + fixedDataLength); 2724 updateValueInMemory(theVal, r, c); 2725 } 2726 catch (Exception ex) { 2727 continue; 2728 } 2729 c++; 2730 } 2731 } 2732 } 2733 } 2734 catch (Throwable ex) { 2735 toolkit.beep(); 2736 JOptionPane.showMessageDialog(this, ex, getTitle(), JOptionPane.ERROR_MESSAGE); 2737 } 2738 2739 table.updateUI(); 2740 } 2741 2742 /** 2743 * import data values from text file. 2744 */ 2745 private void importTextData (String fname) { 2746 int pasteDataFlag = JOptionPane.showConfirmDialog(this, "Do you want to paste selected data?", this.getTitle(), 2747 JOptionPane.YES_NO_OPTION); 2748 if (pasteDataFlag == JOptionPane.NO_OPTION) { 2749 return; 2750 } 2751 int cols = table.getColumnCount(); 2752 int rows = table.getRowCount(); 2753 int r0 = table.getSelectedRow(); 2754 int c0 = table.getSelectedColumn(); 2755 2756 if (c0 < 0) { 2757 c0 = 0; 2758 } 2759 if (r0 < 0) { 2760 r0 = 0; 2761 } 2762 2763 // start at the first column for compound datasets 2764 if (dataset instanceof CompoundDS) c0 = 0; 2765 2766 BufferedReader in = null; 2767 try { 2768 in = new BufferedReader(new FileReader(fname)); 2769 } 2770 catch (FileNotFoundException ex) { 2771 log.debug("import data values from text file {}:", fname, ex); 2772 return; 2773 } 2774 2775 String line = null; 2776 StringTokenizer tokenizer1 = null; 2777 2778 try { 2779 line = in.readLine(); 2780 } 2781 catch (IOException ex) { 2782 try { 2783 in.close(); 2784 } 2785 catch (IOException ex2) { 2786 log.debug("close text file {}:", fname, ex2); 2787 } 2788 log.debug("read text file {}:", fname, ex); 2789 return; 2790 } 2791 2792 String delName = ViewProperties.getDataDelimiter(); 2793 String delimiter = ""; 2794 2795 // delimiter must include a tab to be consistent with copy/paste for 2796 // compound fields 2797 if (dataset instanceof CompoundDS) 2798 delimiter = "\t"; 2799 else { 2800 if (delName.equalsIgnoreCase(ViewProperties.DELIMITER_TAB)) { 2801 delimiter = "\t"; 2802 } 2803 else if (delName.equalsIgnoreCase(ViewProperties.DELIMITER_SPACE)) { 2804 delimiter = " " + delimiter; 2805 } 2806 else if (delName.equalsIgnoreCase(ViewProperties.DELIMITER_COMMA)) { 2807 delimiter = ","; 2808 } 2809 else if (delName.equalsIgnoreCase(ViewProperties.DELIMITER_COLON)) { 2810 delimiter = ":"; 2811 } 2812 else if (delName.equalsIgnoreCase(ViewProperties.DELIMITER_SEMI_COLON)) { 2813 delimiter = ";"; 2814 } 2815 } 2816 String token = null; 2817 int r = r0; 2818 int c = c0; 2819 while ((line != null) && (r < rows)) { 2820 if (fixedDataLength > 0) { 2821 // the data has fixed length 2822 int n = line.length(); 2823 String theVal; 2824 for (int i = 0; i < n; i = i + fixedDataLength) { 2825 try { 2826 theVal = line.substring(i, i + fixedDataLength); 2827 updateValueInMemory(theVal, r, c); 2828 } 2829 catch (Exception ex) { 2830 continue; 2831 } 2832 c++; 2833 } 2834 } 2835 else { 2836 try { 2837 tokenizer1 = new StringTokenizer(line, delimiter); 2838 while (tokenizer1.hasMoreTokens() && (c < cols)) { 2839 token = tokenizer1.nextToken(); 2840 if (dataset instanceof ScalarDS) { 2841 StringTokenizer tokenizer2 = new StringTokenizer(token); 2842 while (tokenizer2.hasMoreTokens() && (c < cols)) { 2843 updateValueInMemory(tokenizer2.nextToken(), r, c); 2844 c++; 2845 } 2846 } 2847 else { 2848 updateValueInMemory(token, r, c); 2849 c++; 2850 } 2851 } // while (tokenizer1.hasMoreTokens() && index < size) 2852 } 2853 catch (Exception ex) { 2854 JOptionPane.showMessageDialog(this, ex, getTitle(), JOptionPane.ERROR_MESSAGE); 2855 try { 2856 in.close(); 2857 } 2858 catch (IOException ex2) { 2859 log.debug("close text file {}:", fname, ex2); 2860 } 2861 return; 2862 } 2863 } 2864 2865 try { 2866 line = in.readLine(); 2867 } 2868 catch (IOException ex) { 2869 log.debug("read text file {}:", fname, ex); 2870 line = null; 2871 } 2872 c = 0; 2873 r++; 2874 } // while ((line != null) && (r < rows)) 2875 2876 try { 2877 in.close(); 2878 } 2879 catch (IOException ex) { 2880 log.debug("close text file {}:", fname, ex); 2881 } 2882 2883 table.updateUI(); 2884 } 2885 2886 /** 2887 * import data values from binary file. 2888 */ 2889 private void importBinaryData ( ) { 2890 String currentDir = dataset.getFileFormat().getParent(); 2891 JFileChooser fchooser = new JFileChooser(currentDir); 2892 fchooser.setFileFilter(DefaultFileFilter.getFileFilterBinary()); 2893 int returnVal = fchooser.showOpenDialog(this); 2894 2895 if (returnVal != JFileChooser.APPROVE_OPTION) { 2896 return; 2897 } 2898 File choosedFile = fchooser.getSelectedFile(); 2899 if (choosedFile == null) { 2900 return; 2901 } 2902 String fname = choosedFile.getAbsolutePath(); 2903 2904 int pasteDataFlag = JOptionPane.showConfirmDialog(this, "Do you want to paste selected data?", this.getTitle(), 2905 JOptionPane.YES_NO_OPTION); 2906 if (pasteDataFlag == JOptionPane.NO_OPTION) { 2907 return; 2908 } 2909 2910 getBinaryDatafromFile(fname); 2911 } 2912 2913 /** Reads data from a binary file into a buffer and updates table. */ 2914 private void getBinaryDatafromFile (String fileName) { 2915 String fname = fileName; 2916 FileInputStream inputFile = null; 2917 BufferedInputStream in = null; 2918 ByteBuffer byteBuffer = null; 2919 try { 2920 inputFile = new FileInputStream(fname); 2921 long fileSize = inputFile.getChannel().size(); 2922 in = new BufferedInputStream(inputFile); 2923 2924 Object data = dataset.getData(); 2925 int datasetSize = Array.getLength(data); 2926 String cname = data.getClass().getName(); 2927 char dname = cname.charAt(cname.lastIndexOf("[") + 1); 2928 2929 if (dname == 'B') { 2930 long datasetByteSize = datasetSize; 2931 byteBuffer = ByteBuffer.allocate(BYTE_BUFFER_SIZE); 2932 if (binaryOrder == 1) 2933 byteBuffer.order(ByteOrder.nativeOrder()); 2934 else if (binaryOrder == 2) 2935 byteBuffer.order(ByteOrder.LITTLE_ENDIAN); 2936 else if (binaryOrder == 3) byteBuffer.order(ByteOrder.BIG_ENDIAN); 2937 2938 int bufferSize = (int) Math.min(fileSize, datasetByteSize); 2939 2940 int remainingSize = bufferSize - (BYTE_BUFFER_SIZE); 2941 int allocValue = 0; 2942 int iterationNumber = 0; 2943 byte[] byteArray = new byte[BYTE_BUFFER_SIZE]; 2944 do { 2945 if (remainingSize <= 0) { 2946 allocValue = remainingSize + (BYTE_BUFFER_SIZE); 2947 } 2948 else { 2949 allocValue = (BYTE_BUFFER_SIZE); 2950 } 2951 2952 in.read(byteBuffer.array(), 0, allocValue); 2953 2954 byteBuffer.get(byteArray, 0, allocValue); 2955 System.arraycopy(byteArray, 0, dataValue, (iterationNumber * BYTE_BUFFER_SIZE), allocValue); 2956 byteBuffer.clear(); 2957 remainingSize = remainingSize - (BYTE_BUFFER_SIZE); 2958 iterationNumber++; 2959 } while (remainingSize > -(BYTE_BUFFER_SIZE)); 2960 2961 isValueChanged = true; 2962 } 2963 else if (dname == 'S') { 2964 long datasetShortSize = datasetSize * 2; 2965 byteBuffer = ByteBuffer.allocate(SHORT_BUFFER_SIZE * 2); 2966 if (binaryOrder == 1) 2967 byteBuffer.order(ByteOrder.nativeOrder()); 2968 else if (binaryOrder == 2) 2969 byteBuffer.order(ByteOrder.LITTLE_ENDIAN); 2970 else if (binaryOrder == 3) byteBuffer.order(ByteOrder.BIG_ENDIAN); 2971 2972 int bufferSize = (int) Math.min(fileSize, datasetShortSize); 2973 int remainingSize = bufferSize - (SHORT_BUFFER_SIZE * 2); 2974 int allocValue = 0; 2975 int iterationNumber = 0; 2976 ShortBuffer sb = byteBuffer.asShortBuffer(); 2977 short[] shortArray = new short[SHORT_BUFFER_SIZE]; 2978 2979 do { 2980 if (remainingSize <= 0) { 2981 allocValue = remainingSize + (SHORT_BUFFER_SIZE * 2); 2982 } 2983 else { 2984 allocValue = (SHORT_BUFFER_SIZE * 2); 2985 } 2986 in.read(byteBuffer.array(), 0, allocValue); 2987 sb.get(shortArray, 0, allocValue / 2); 2988 System.arraycopy(shortArray, 0, dataValue, (iterationNumber * SHORT_BUFFER_SIZE), allocValue / 2); 2989 byteBuffer.clear(); 2990 sb.clear(); 2991 remainingSize = remainingSize - (SHORT_BUFFER_SIZE * 2); 2992 iterationNumber++; 2993 } while (remainingSize > -(SHORT_BUFFER_SIZE * 2)); 2994 2995 isValueChanged = true; 2996 } 2997 else if (dname == 'I') { 2998 long datasetIntSize = datasetSize * 4; 2999 byteBuffer = ByteBuffer.allocate(INT_BUFFER_SIZE * 4); 3000 if (binaryOrder == 1) 3001 byteBuffer.order(ByteOrder.nativeOrder()); 3002 else if (binaryOrder == 2) 3003 byteBuffer.order(ByteOrder.LITTLE_ENDIAN); 3004 else if (binaryOrder == 3) byteBuffer.order(ByteOrder.BIG_ENDIAN); 3005 3006 int bufferSize = (int) Math.min(fileSize, datasetIntSize); 3007 int remainingSize = bufferSize - (INT_BUFFER_SIZE * 4); 3008 int allocValue = 0; 3009 int iterationNumber = 0; 3010 int[] intArray = new int[INT_BUFFER_SIZE]; 3011 byte[] tmpBuf = byteBuffer.array(); 3012 IntBuffer ib = byteBuffer.asIntBuffer(); 3013 3014 do { 3015 if (remainingSize <= 0) { 3016 allocValue = remainingSize + (INT_BUFFER_SIZE * 4); 3017 } 3018 else { 3019 allocValue = (INT_BUFFER_SIZE * 4); 3020 } 3021 in.read(tmpBuf, 0, allocValue); 3022 ib.get(intArray, 0, allocValue / 4); 3023 System.arraycopy(intArray, 0, dataValue, (iterationNumber * INT_BUFFER_SIZE), allocValue / 4); 3024 byteBuffer.clear(); 3025 ib.clear(); 3026 remainingSize = remainingSize - (INT_BUFFER_SIZE * 4); 3027 iterationNumber++; 3028 } while (remainingSize > -(INT_BUFFER_SIZE * 4)); 3029 3030 isValueChanged = true; 3031 } 3032 else if (dname == 'J') { 3033 long datasetLongSize = datasetSize * 8; 3034 byteBuffer = ByteBuffer.allocate(LONG_BUFFER_SIZE * 8); 3035 3036 if (binaryOrder == 1) 3037 byteBuffer.order(ByteOrder.nativeOrder()); 3038 else if (binaryOrder == 2) 3039 byteBuffer.order(ByteOrder.LITTLE_ENDIAN); 3040 else if (binaryOrder == 3) byteBuffer.order(ByteOrder.BIG_ENDIAN); 3041 3042 int bufferSize = (int) Math.min(fileSize, datasetLongSize); 3043 int remainingSize = bufferSize - (LONG_BUFFER_SIZE * 8); 3044 int allocValue = 0; 3045 int iterationNumber = 0; 3046 long[] longArray = new long[LONG_BUFFER_SIZE]; 3047 LongBuffer lb = byteBuffer.asLongBuffer(); 3048 3049 do { 3050 if (remainingSize <= 0) { 3051 allocValue = remainingSize + (LONG_BUFFER_SIZE * 8); 3052 } 3053 else { 3054 allocValue = (LONG_BUFFER_SIZE * 8); 3055 } 3056 3057 in.read(byteBuffer.array(), 0, allocValue); 3058 lb.get(longArray, 0, allocValue / 8); 3059 System.arraycopy(longArray, 0, dataValue, (iterationNumber * LONG_BUFFER_SIZE), allocValue / 8); 3060 byteBuffer.clear(); 3061 lb.clear(); 3062 remainingSize = remainingSize - (LONG_BUFFER_SIZE * 8); 3063 iterationNumber++; 3064 } while (remainingSize > -(LONG_BUFFER_SIZE * 8)); 3065 3066 isValueChanged = true; 3067 } 3068 else if (dname == 'F') { 3069 long datasetFloatSize = datasetSize * 4; 3070 byteBuffer = ByteBuffer.allocate(FLOAT_BUFFER_SIZE * 4); 3071 if (binaryOrder == 1) 3072 byteBuffer.order(ByteOrder.nativeOrder()); 3073 else if (binaryOrder == 2) 3074 byteBuffer.order(ByteOrder.LITTLE_ENDIAN); 3075 else if (binaryOrder == 3) byteBuffer.order(ByteOrder.BIG_ENDIAN); 3076 3077 int bufferSize = (int) Math.min(fileSize, datasetFloatSize); 3078 int remainingSize = bufferSize - (FLOAT_BUFFER_SIZE * 4); 3079 int allocValue = 0; 3080 int iterationNumber = 0; 3081 FloatBuffer fb = byteBuffer.asFloatBuffer(); 3082 float[] floatArray = new float[FLOAT_BUFFER_SIZE]; 3083 do { 3084 if (remainingSize <= 0) { 3085 allocValue = remainingSize + (FLOAT_BUFFER_SIZE * 4); 3086 } 3087 else { 3088 allocValue = (FLOAT_BUFFER_SIZE * 4); 3089 } 3090 3091 in.read(byteBuffer.array(), 0, allocValue); 3092 fb.get(floatArray, 0, allocValue / 4); 3093 System.arraycopy(floatArray, 0, dataValue, (iterationNumber * FLOAT_BUFFER_SIZE), allocValue / 4); 3094 byteBuffer.clear(); 3095 fb.clear(); 3096 remainingSize = remainingSize - (FLOAT_BUFFER_SIZE * 4); 3097 iterationNumber++; 3098 } while (remainingSize > -(FLOAT_BUFFER_SIZE * 4)); 3099 3100 isValueChanged = true; 3101 } 3102 else if (dname == 'D') { 3103 long datasetDoubleSize = datasetSize * 8; 3104 byteBuffer = ByteBuffer.allocate(DOUBLE_BUFFER_SIZE * 8); 3105 if (binaryOrder == 1) 3106 byteBuffer.order(ByteOrder.nativeOrder()); 3107 else if (binaryOrder == 2) 3108 byteBuffer.order(ByteOrder.LITTLE_ENDIAN); 3109 else if (binaryOrder == 3) byteBuffer.order(ByteOrder.BIG_ENDIAN); 3110 3111 int bufferSize = (int) Math.min(fileSize, datasetDoubleSize); 3112 int remainingSize = bufferSize - (DOUBLE_BUFFER_SIZE * 8); 3113 int allocValue = 0; 3114 int iterationNumber = 0; 3115 DoubleBuffer db = byteBuffer.asDoubleBuffer(); 3116 double[] doubleArray = new double[DOUBLE_BUFFER_SIZE]; 3117 3118 do { 3119 if (remainingSize <= 0) { 3120 allocValue = remainingSize + (DOUBLE_BUFFER_SIZE * 8); 3121 } 3122 else { 3123 allocValue = (DOUBLE_BUFFER_SIZE * 8); 3124 } 3125 3126 in.read(byteBuffer.array(), 0, allocValue); 3127 db.get(doubleArray, 0, allocValue / 8); 3128 System.arraycopy(doubleArray, 0, dataValue, (iterationNumber * DOUBLE_BUFFER_SIZE), allocValue / 8); 3129 byteBuffer.clear(); 3130 db.clear(); 3131 remainingSize = remainingSize - (DOUBLE_BUFFER_SIZE * 8); 3132 iterationNumber++; 3133 } while (remainingSize > -(DOUBLE_BUFFER_SIZE * 8)); 3134 3135 isValueChanged = true; 3136 3137 } 3138 3139 } 3140 catch (Exception es) { 3141 es.printStackTrace(); 3142 } 3143 finally { 3144 try { 3145 in.close(); 3146 inputFile.close(); 3147 } 3148 catch (IOException ex) { 3149 log.debug("close binary file {}:", fname, ex); 3150 } 3151 } 3152 table.updateUI(); 3153 } 3154 3155 /** Save data as text. */ 3156 private void saveAsText ( ) throws Exception { 3157 final JFileChooser fchooser = new JFileChooser(dataset.getFile()); 3158 fchooser.setFileFilter(DefaultFileFilter.getFileFilterText()); 3159 // fchooser.changeToParentDirectory(); 3160 fchooser.setDialogTitle("Save Current Data To Text File --- " + dataset.getName()); 3161 3162 File choosedFile = new File(dataset.getName() + ".txt"); 3163 3164 fchooser.setSelectedFile(choosedFile); 3165 int returnVal = fchooser.showSaveDialog(this); 3166 3167 if (returnVal != JFileChooser.APPROVE_OPTION) { 3168 return; 3169 } 3170 3171 choosedFile = fchooser.getSelectedFile(); 3172 if (choosedFile == null) { 3173 return; 3174 } 3175 String fname = choosedFile.getAbsolutePath(); 3176 log.trace("DefaultTableView saveAsText: file={}", fname); 3177 3178 // check if the file is in use 3179 List<?> fileList = viewer.getTreeView().getCurrentFiles(); 3180 if (fileList != null) { 3181 FileFormat theFile = null; 3182 Iterator<?> iterator = fileList.iterator(); 3183 while (iterator.hasNext()) { 3184 theFile = (FileFormat) iterator.next(); 3185 if (theFile.getFilePath().equals(fname)) { 3186 toolkit.beep(); 3187 JOptionPane.showMessageDialog(this, "Unable to save data to file \"" + fname + "\". \nThe file is being used.", 3188 getTitle(), JOptionPane.ERROR_MESSAGE); 3189 return; 3190 } 3191 } 3192 } 3193 3194 if (choosedFile.exists()) { 3195 int newFileFlag = JOptionPane.showConfirmDialog(this, "File exists. Do you want to replace it?", this.getTitle(), 3196 JOptionPane.YES_NO_OPTION); 3197 if (newFileFlag == JOptionPane.NO_OPTION) { 3198 return; 3199 } 3200 } 3201 3202 PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(choosedFile))); 3203 3204 String delName = ViewProperties.getDataDelimiter(); 3205 String delimiter = ""; 3206 3207 // delimiter must include a tab to be consistent with copy/paste for 3208 // compound fields 3209 if (dataset instanceof CompoundDS) delimiter = "\t"; 3210 3211 if (delName.equalsIgnoreCase(ViewProperties.DELIMITER_TAB)) { 3212 delimiter = "\t"; 3213 } 3214 else if (delName.equalsIgnoreCase(ViewProperties.DELIMITER_SPACE)) { 3215 delimiter = " " + delimiter; 3216 } 3217 else if (delName.equalsIgnoreCase(ViewProperties.DELIMITER_COMMA)) { 3218 delimiter = "," + delimiter; 3219 } 3220 else if (delName.equalsIgnoreCase(ViewProperties.DELIMITER_COLON)) { 3221 delimiter = ":" + delimiter; 3222 } 3223 else if (delName.equalsIgnoreCase(ViewProperties.DELIMITER_SEMI_COLON)) { 3224 delimiter = ";" + delimiter; 3225 } 3226 3227 int cols = table.getColumnCount(); 3228 int rows = table.getRowCount(); 3229 3230 for (int i = 0; i < rows; i++) { 3231 out.print(table.getValueAt(i, 0)); 3232 for (int j = 1; j < cols; j++) { 3233 out.print(delimiter); 3234 out.print(table.getValueAt(i, j)); 3235 } 3236 out.println(); 3237 } 3238 3239 out.flush(); 3240 out.close(); 3241 3242 viewer.showStatus("Data save to: " + fname); 3243 } 3244 3245 /** Save data as binary. */ 3246 private void saveAsBinary ( ) throws Exception { 3247 final JFileChooser fchooser = new JFileChooser(dataset.getFile()); 3248 fchooser.setFileFilter(DefaultFileFilter.getFileFilterBinary()); 3249 // fchooser.changeToParentDirectory(); 3250 fchooser.setDialogTitle("Save Current Data To Binary File --- " + dataset.getName()); 3251 3252 File choosedFile = new File(dataset.getName() + ".bin"); 3253 fchooser.setSelectedFile(choosedFile); 3254 int returnVal = fchooser.showSaveDialog(this); 3255 3256 if (returnVal != JFileChooser.APPROVE_OPTION) { 3257 return; 3258 } 3259 3260 choosedFile = fchooser.getSelectedFile(); 3261 if (choosedFile == null) { 3262 return; 3263 } 3264 String fname = choosedFile.getAbsolutePath(); 3265 log.trace("DefaultTableView saveAsBinary: file={}", fname); 3266 3267 // check if the file is in use 3268 List<?> fileList = viewer.getTreeView().getCurrentFiles(); 3269 if (fileList != null) { 3270 FileFormat theFile = null; 3271 Iterator<?> iterator = fileList.iterator(); 3272 while (iterator.hasNext()) { 3273 theFile = (FileFormat) iterator.next(); 3274 if (theFile.getFilePath().equals(fname)) { 3275 toolkit.beep(); 3276 JOptionPane.showMessageDialog(this, "Unable to save data to file \"" + fname + "\". \nThe file is being used.", 3277 getTitle(), JOptionPane.ERROR_MESSAGE); 3278 return; 3279 } 3280 } 3281 } 3282 3283 // check if the file exists 3284 if (choosedFile.exists()) { 3285 int newFileFlag = JOptionPane.showConfirmDialog(this, "File exists. Do you want to replace it?", this.getTitle(), 3286 JOptionPane.YES_NO_OPTION); 3287 if (newFileFlag == JOptionPane.NO_OPTION) { 3288 return; 3289 } 3290 } 3291 3292 FileOutputStream outputFile = new FileOutputStream(choosedFile); 3293 DataOutputStream out = new DataOutputStream(outputFile); 3294 3295 if (dataset instanceof ScalarDS) { 3296 ((ScalarDS) dataset).convertToUnsignedC(); 3297 Object data = dataset.getData(); 3298 String cname = data.getClass().getName(); 3299 char dname = cname.charAt(cname.lastIndexOf("[") + 1); 3300 ByteBuffer bb = null; 3301 3302 int size = Array.getLength(data); 3303 3304 if (dname == 'B') { 3305 byte[] bdata = new byte[size]; 3306 bdata = (byte[]) data; 3307 3308 bb = ByteBuffer.allocate(BYTE_BUFFER_SIZE); 3309 if (binaryOrder == 1) 3310 bb.order(ByteOrder.nativeOrder()); 3311 else if (binaryOrder == 2) 3312 bb.order(ByteOrder.LITTLE_ENDIAN); 3313 else if (binaryOrder == 3) bb.order(ByteOrder.BIG_ENDIAN); 3314 3315 int remainingSize = size - BYTE_BUFFER_SIZE; 3316 int allocValue = 0; 3317 int iterationNumber = 0; 3318 do { 3319 if (remainingSize <= 0) { 3320 allocValue = remainingSize + BYTE_BUFFER_SIZE; 3321 } 3322 else { 3323 allocValue = BYTE_BUFFER_SIZE; 3324 } 3325 bb.clear(); 3326 bb.put(bdata, (iterationNumber * BYTE_BUFFER_SIZE), allocValue); 3327 out.write(bb.array(), 0, allocValue); 3328 remainingSize = remainingSize - BYTE_BUFFER_SIZE; 3329 iterationNumber++; 3330 } while (remainingSize > -BYTE_BUFFER_SIZE); 3331 3332 out.flush(); 3333 out.close(); 3334 } 3335 else if (dname == 'S') { 3336 short[] sdata = new short[size]; 3337 sdata = (short[]) data; 3338 bb = ByteBuffer.allocate(SHORT_BUFFER_SIZE * 2); 3339 if (binaryOrder == 1) 3340 bb.order(ByteOrder.nativeOrder()); 3341 else if (binaryOrder == 2) 3342 bb.order(ByteOrder.LITTLE_ENDIAN); 3343 else if (binaryOrder == 3) bb.order(ByteOrder.BIG_ENDIAN); 3344 3345 ShortBuffer sb = bb.asShortBuffer(); 3346 int remainingSize = size - SHORT_BUFFER_SIZE; 3347 int allocValue = 0; 3348 int iterationNumber = 0; 3349 do { 3350 if (remainingSize <= 0) { 3351 allocValue = remainingSize + SHORT_BUFFER_SIZE; 3352 } 3353 else { 3354 allocValue = SHORT_BUFFER_SIZE; 3355 } 3356 bb.clear(); 3357 sb.clear(); 3358 sb.put(sdata, (iterationNumber * SHORT_BUFFER_SIZE), allocValue); 3359 out.write(bb.array(), 0, allocValue * 2); 3360 remainingSize = remainingSize - SHORT_BUFFER_SIZE; 3361 iterationNumber++; 3362 } while (remainingSize > -SHORT_BUFFER_SIZE); 3363 3364 out.flush(); 3365 out.close(); 3366 } 3367 else if (dname == 'I') { 3368 int[] idata = new int[size]; 3369 idata = (int[]) data; 3370 bb = ByteBuffer.allocate(INT_BUFFER_SIZE * 4); 3371 if (binaryOrder == 1) 3372 bb.order(ByteOrder.nativeOrder()); 3373 else if (binaryOrder == 2) 3374 bb.order(ByteOrder.LITTLE_ENDIAN); 3375 else if (binaryOrder == 3) bb.order(ByteOrder.BIG_ENDIAN); 3376 3377 IntBuffer ib = bb.asIntBuffer(); 3378 int remainingSize = size - INT_BUFFER_SIZE; 3379 int allocValue = 0; 3380 int iterationNumber = 0; 3381 do { 3382 if (remainingSize <= 0) { 3383 allocValue = remainingSize + INT_BUFFER_SIZE; 3384 } 3385 else { 3386 allocValue = INT_BUFFER_SIZE; 3387 } 3388 bb.clear(); 3389 ib.clear(); 3390 ib.put(idata, (iterationNumber * INT_BUFFER_SIZE), allocValue); 3391 out.write(bb.array(), 0, allocValue * 4); 3392 remainingSize = remainingSize - INT_BUFFER_SIZE; 3393 iterationNumber++; 3394 } while (remainingSize > -INT_BUFFER_SIZE); 3395 3396 out.flush(); 3397 out.close(); 3398 } 3399 else if (dname == 'J') { 3400 long[] ldata = new long[size]; 3401 ldata = (long[]) data; 3402 3403 bb = ByteBuffer.allocate(LONG_BUFFER_SIZE * 8); 3404 if (binaryOrder == 1) 3405 bb.order(ByteOrder.nativeOrder()); 3406 else if (binaryOrder == 2) 3407 bb.order(ByteOrder.LITTLE_ENDIAN); 3408 else if (binaryOrder == 3) bb.order(ByteOrder.BIG_ENDIAN); 3409 3410 LongBuffer lb = bb.asLongBuffer(); 3411 int remainingSize = size - LONG_BUFFER_SIZE; 3412 int allocValue = 0; 3413 int iterationNumber = 0; 3414 do { 3415 if (remainingSize <= 0) { 3416 allocValue = remainingSize + LONG_BUFFER_SIZE; 3417 } 3418 else { 3419 allocValue = LONG_BUFFER_SIZE; 3420 } 3421 bb.clear(); 3422 lb.clear(); 3423 lb.put(ldata, (iterationNumber * LONG_BUFFER_SIZE), allocValue); 3424 out.write(bb.array(), 0, allocValue * 8); 3425 remainingSize = remainingSize - LONG_BUFFER_SIZE; 3426 iterationNumber++; 3427 } while (remainingSize > -LONG_BUFFER_SIZE); 3428 3429 out.flush(); 3430 out.close(); 3431 } 3432 else if (dname == 'F') { 3433 float[] fdata = new float[size]; 3434 fdata = (float[]) data; 3435 3436 bb = ByteBuffer.allocate(FLOAT_BUFFER_SIZE * 4); 3437 if (binaryOrder == 1) 3438 bb.order(ByteOrder.nativeOrder()); 3439 else if (binaryOrder == 2) 3440 bb.order(ByteOrder.LITTLE_ENDIAN); 3441 else if (binaryOrder == 3) bb.order(ByteOrder.BIG_ENDIAN); 3442 3443 FloatBuffer fb = bb.asFloatBuffer(); 3444 int remainingSize = size - FLOAT_BUFFER_SIZE; 3445 int allocValue = 0; 3446 int iterationNumber = 0; 3447 do { 3448 if (remainingSize <= 0) { 3449 allocValue = remainingSize + FLOAT_BUFFER_SIZE; 3450 } 3451 else { 3452 allocValue = FLOAT_BUFFER_SIZE; 3453 } 3454 bb.clear(); 3455 fb.clear(); 3456 fb.put(fdata, (iterationNumber * FLOAT_BUFFER_SIZE), allocValue); 3457 out.write(bb.array(), 0, allocValue * 4); 3458 remainingSize = remainingSize - FLOAT_BUFFER_SIZE; 3459 iterationNumber++; 3460 } while (remainingSize > -FLOAT_BUFFER_SIZE); 3461 3462 out.flush(); 3463 out.close(); 3464 } 3465 else if (dname == 'D') { 3466 double[] ddata = new double[size]; 3467 ddata = (double[]) data; 3468 3469 bb = ByteBuffer.allocate(DOUBLE_BUFFER_SIZE * 8); 3470 if (binaryOrder == 1) 3471 bb.order(ByteOrder.nativeOrder()); 3472 else if (binaryOrder == 2) 3473 bb.order(ByteOrder.LITTLE_ENDIAN); 3474 else if (binaryOrder == 3) bb.order(ByteOrder.BIG_ENDIAN); 3475 3476 DoubleBuffer db = bb.asDoubleBuffer(); 3477 int remainingSize = size - DOUBLE_BUFFER_SIZE; 3478 int allocValue = 0; 3479 int iterationNumber = 0; 3480 do { 3481 if (remainingSize <= 0) { 3482 allocValue = remainingSize + DOUBLE_BUFFER_SIZE; 3483 } 3484 else { 3485 allocValue = DOUBLE_BUFFER_SIZE; 3486 } 3487 bb.clear(); 3488 db.clear(); 3489 db.put(ddata, (iterationNumber * DOUBLE_BUFFER_SIZE), allocValue); 3490 out.write(bb.array(), 0, allocValue * 8); 3491 remainingSize = remainingSize - DOUBLE_BUFFER_SIZE; 3492 iterationNumber++; 3493 } while (remainingSize > -DOUBLE_BUFFER_SIZE); 3494 3495 out.flush(); 3496 out.close(); 3497 } 3498 } 3499 3500 viewer.showStatus("Data save to: " + fname); 3501 } 3502 3503 /** 3504 * update dataset value in file. The change will go to file. 3505 */ 3506 @Override 3507 public void updateValueInFile ( ) { 3508 log.trace("DefaultTableView updateValueInFile enter"); 3509 if (isReadOnly || showAsBin || showAsHex) { 3510 return; 3511 } 3512 3513 if (!isValueChanged) { 3514 return; 3515 } 3516 3517 try { 3518 log.trace("DefaultTableView updateValueInFile write"); 3519 dataset.write(); 3520 } 3521 catch (Exception ex) { 3522 toolkit.beep(); 3523 JOptionPane.showMessageDialog(this, ex, getTitle(), JOptionPane.ERROR_MESSAGE); 3524 return; 3525 } 3526 3527 isValueChanged = false; 3528 log.trace("DefaultTableView updateValueInFile exit"); 3529 } 3530 3531 /** 3532 * Selects all rows, columns, and cells in the table. 3533 */ 3534 private void selectAll ( ) throws Exception { 3535 table.selectAll(); 3536 } 3537 3538 /** 3539 * Converting selected data based on predefined math functions. 3540 */ 3541 private void mathConversion ( ) throws Exception { 3542 if (isReadOnly) { 3543 return; 3544 } 3545 3546 int cols = table.getSelectedColumnCount(); 3547 // if (!(dataset instanceof ScalarDS)) return; 3548 if ((dataset instanceof CompoundDS) && (cols > 1)) { 3549 toolkit.beep(); 3550 JOptionPane.showMessageDialog(this, "Please select one colunm a time for math conversion for compound dataset.", 3551 getTitle(), JOptionPane.ERROR_MESSAGE); 3552 return; 3553 } 3554 3555 Object theData = getSelectedData(); 3556 if (theData == null) { 3557 toolkit.beep(); 3558 JOptionPane.showMessageDialog(this, "No data is selected.", getTitle(), JOptionPane.ERROR_MESSAGE); 3559 return; 3560 } 3561 3562 MathConversionDialog dialog = new MathConversionDialog((JFrame) viewer, theData); 3563 dialog.setVisible(true); 3564 3565 if (dialog.isConverted()) { 3566 if (dataset instanceof CompoundDS) { 3567 Object colData = null; 3568 try { 3569 colData = ((List<?>) dataset.getData()).get(table.getSelectedColumn()); 3570 } 3571 catch (Exception ex) { 3572 log.debug("colData:", ex); 3573 } 3574 3575 if (colData != null) { 3576 int size = Array.getLength(theData); 3577 System.arraycopy(theData, 0, colData, 0, size); 3578 } 3579 } 3580 else { 3581 int rows = table.getSelectedRowCount(); 3582 int r0 = table.getSelectedRow(); 3583 int c0 = table.getSelectedColumn(); 3584 int w = table.getColumnCount(); 3585 int idx_src = 0; 3586 int idx_dst = 0; 3587 for (int i = 0; i < rows; i++) { 3588 idx_dst = (r0 + i) * w + c0; 3589 System.arraycopy(theData, idx_src, dataValue, idx_dst, cols); 3590 idx_src += cols; 3591 } 3592 } 3593 3594 theData = null; 3595 System.gc(); 3596 table.updateUI(); 3597 isValueChanged = true; 3598 } 3599 3600 } 3601 3602 /** 3603 * update cell value in memory. It does not change the dataset value in file. 3604 * 3605 * @param cellValue 3606 * the string value of input. 3607 * @param row 3608 * the row of the editing cell. 3609 * @param col 3610 * the column of the editing cell. 3611 */ 3612 private void updateValueInMemory (String cellValue, int row, int col) throws Exception { 3613 log.trace("DefaultTableView updateValueInMemory"); 3614 if (currentEditingCellValue != null) { 3615 // data values are the same, no need to change the data 3616 if (currentEditingCellValue.toString().equals(cellValue)) return; 3617 } 3618 3619 if (dataset instanceof ScalarDS) { 3620 updateScalarData(cellValue, row, col); 3621 } 3622 else if (dataset instanceof CompoundDS) { 3623 updateCompoundData(cellValue, row, col); 3624 } 3625 } 3626 3627 /** 3628 * update cell value in memory. It does not change the dataset value in file. 3629 * 3630 * @param cellValue 3631 * the string value of input. 3632 * @param row 3633 * the row of the editing cell. 3634 * @param col 3635 * the column of the editing cell. 3636 */ 3637 private void updateScalarData (String cellValue, int row, int col) throws Exception { 3638 if (!(dataset instanceof ScalarDS) || (cellValue == null) || ((cellValue = cellValue.trim()) == null) || showAsBin 3639 || showAsHex) { 3640 return; 3641 } 3642 3643 int i = 0; 3644 if (isDataTransposed) { 3645 i = col * table.getRowCount() + row; 3646 } 3647 else { 3648 i = row * table.getColumnCount() + col; 3649 } 3650 log.trace("DefaultTableView updateScalarData {} NT={}", cellValue, NT); 3651 3652 ScalarDS sds = (ScalarDS) dataset; 3653 boolean isUnsigned = sds.isUnsigned(); 3654 String cname = dataset.getOriginalClass().getName(); 3655 char dname = cname.charAt(cname.lastIndexOf("[") + 1); 3656 log.trace("updateScalarData isUnsigned={} cname={} dname={}", isUnsigned, cname, dname); 3657 3658 // check data range for unsigned datatype converted sizes! 3659 if (isUnsigned) { 3660 long lvalue = -1; 3661 long maxValue = Long.MAX_VALUE; 3662 if (dname == 'B') { 3663 maxValue = 255; 3664 lvalue = Long.parseLong(cellValue); 3665 3666 if (lvalue < 0) { 3667 throw new NumberFormatException("Negative value for unsigned integer: " + lvalue); 3668 } 3669 3670 if (lvalue > maxValue) { 3671 throw new NumberFormatException("Data value is out of range: " + lvalue); 3672 } 3673 } 3674 else if (dname == 'S') { 3675 maxValue = 65535; 3676 lvalue = Long.parseLong(cellValue); 3677 3678 if (lvalue < 0) { 3679 throw new NumberFormatException("Negative value for unsigned integer: " + lvalue); 3680 } 3681 3682 if (lvalue > maxValue) { 3683 throw new NumberFormatException("Data value is out of range: " + lvalue); 3684 } 3685 } 3686 else if (dname == 'I') { 3687 maxValue = 4294967295L; 3688 lvalue = Long.parseLong(cellValue); 3689 3690 if (lvalue < 0) { 3691 throw new NumberFormatException("Negative value for unsigned integer: " + lvalue); 3692 } 3693 3694 if (lvalue > maxValue) { 3695 throw new NumberFormatException("Data value is out of range: " + lvalue); 3696 } 3697 } 3698 else if (dname == 'J') { 3699 BigInteger Jmax = new BigInteger("18446744073709551615"); 3700 BigInteger big = new BigInteger(cellValue); 3701 if (big.compareTo(Jmax) > 0) { 3702 throw new NumberFormatException("Negative value for unsigned integer: " + cellValue); 3703 } 3704 if (big.compareTo(BigInteger.ZERO) < 0) { 3705 throw new NumberFormatException("Data value is out of range: " + cellValue); 3706 } 3707 } 3708 } 3709 3710 switch (NT) { 3711 case 'B': 3712 byte bvalue = 0; 3713 bvalue = Byte.parseByte(cellValue); 3714 Array.setByte(dataValue, i, bvalue); 3715 break; 3716 case 'S': 3717 short svalue = 0; 3718 svalue = Short.parseShort(cellValue); 3719 Array.setShort(dataValue, i, svalue); 3720 break; 3721 case 'I': 3722 int ivalue = 0; 3723 ivalue = Integer.parseInt(cellValue); 3724 Array.setInt(dataValue, i, ivalue); 3725 break; 3726 case 'J': 3727 long lvalue = 0; 3728 if (dname == 'J') { 3729 BigInteger big = new BigInteger(cellValue); 3730 lvalue = big.longValue(); 3731 } 3732 else 3733 lvalue = Long.parseLong(cellValue); 3734 Array.setLong(dataValue, i, lvalue); 3735 break; 3736 case 'F': 3737 float fvalue = 0; 3738 fvalue = Float.parseFloat(cellValue); 3739 Array.setFloat(dataValue, i, fvalue); 3740 break; 3741 case 'D': 3742 double dvalue = 0; 3743 dvalue = Double.parseDouble(cellValue); 3744 Array.setDouble(dataValue, i, dvalue); 3745 break; 3746 default: 3747 Array.set(dataValue, i, cellValue); 3748 break; 3749 } 3750 3751 isValueChanged = true; 3752 } 3753 3754 private void updateCompoundData (String cellValue, int row, int col) throws Exception { 3755 if (!(dataset instanceof CompoundDS) || (cellValue == null) || ((cellValue = cellValue.trim()) == null)) { 3756 return; 3757 } 3758 log.trace("DefaultTableView updateCompoundData"); 3759 3760 CompoundDS compDS = (CompoundDS) dataset; 3761 List<?> cdata = (List<?>) compDS.getData(); 3762 int orders[] = compDS.getSelectedMemberOrders(); 3763 Datatype types[] = compDS.getSelectedMemberTypes(); 3764 int nFields = cdata.size(); 3765 int nSubColumns = table.getColumnCount() / nFields; 3766 table.getRowCount(); 3767 int column = col; 3768 int offset = 0; 3769 int morder = 1; 3770 3771 if (nSubColumns > 1) { // multi-dimension compound dataset 3772 int colIdx = col / nFields; 3773 column = col - colIdx * nFields; 3774 // //BUG 573: offset = row * orders[column] + colIdx * nRows * 3775 // orders[column]; 3776 offset = row * orders[column] * nSubColumns + colIdx * orders[column]; 3777 } 3778 else { 3779 offset = row * orders[column]; 3780 } 3781 morder = orders[column]; 3782 3783 Object mdata = cdata.get(column); 3784 3785 // strings 3786 if (Array.get(mdata, 0) instanceof String) { 3787 Array.set(mdata, offset, cellValue); 3788 isValueChanged = true; 3789 return; 3790 } 3791 else if (types[column].getDatatypeClass() == Datatype.CLASS_STRING) { 3792 // it is string but not converted, still byte array 3793 int strlen = types[column].getDatatypeSize(); 3794 offset *= strlen; 3795 byte[] bytes = cellValue.getBytes(); 3796 byte[] bData = (byte[]) mdata; 3797 int n = Math.min(strlen, bytes.length); 3798 System.arraycopy(bytes, 0, bData, offset, n); 3799 offset += n; 3800 n = strlen - bytes.length; 3801 // space padding 3802 for (int i = 0; i < n; i++) { 3803 bData[offset + i] = ' '; 3804 } 3805 isValueChanged = true; 3806 return; 3807 } 3808 3809 // Numeric data 3810 char mNT = ' '; 3811 String cName = mdata.getClass().getName(); 3812 int cIndex = cName.lastIndexOf("["); 3813 if (cIndex >= 0) { 3814 mNT = cName.charAt(cIndex + 1); 3815 } 3816 3817 StringTokenizer st = new StringTokenizer(cellValue, ","); 3818 if (st.countTokens() < morder) { 3819 toolkit.beep(); 3820 JOptionPane.showMessageDialog(this, "Number of data point < " + morder + ".", getTitle(), JOptionPane.ERROR_MESSAGE); 3821 return; 3822 } 3823 3824 String token = ""; 3825 isValueChanged = true; 3826 switch (mNT) { 3827 case 'B': 3828 byte bvalue = 0; 3829 for (int i = 0; i < morder; i++) { 3830 token = st.nextToken().trim(); 3831 bvalue = Byte.parseByte(token); 3832 Array.setByte(mdata, offset + i, bvalue); 3833 } 3834 break; 3835 case 'S': 3836 short svalue = 0; 3837 for (int i = 0; i < morder; i++) { 3838 token = st.nextToken().trim(); 3839 svalue = Short.parseShort(token); 3840 Array.setShort(mdata, offset + i, svalue); 3841 } 3842 break; 3843 case 'I': 3844 int ivalue = 0; 3845 for (int i = 0; i < morder; i++) { 3846 token = st.nextToken().trim(); 3847 ivalue = Integer.parseInt(token); 3848 Array.setInt(mdata, offset + i, ivalue); 3849 } 3850 break; 3851 case 'J': 3852 long lvalue = 0; 3853 for (int i = 0; i < morder; i++) { 3854 token = st.nextToken().trim(); 3855 BigInteger big = new BigInteger(token); 3856 lvalue = big.longValue(); 3857 // lvalue = Long.parseLong(token); 3858 Array.setLong(mdata, offset + i, lvalue); 3859 } 3860 break; 3861 case 'F': 3862 float fvalue = 0; 3863 for (int i = 0; i < morder; i++) { 3864 token = st.nextToken().trim(); 3865 fvalue = Float.parseFloat(token); 3866 Array.setFloat(mdata, offset + i, fvalue); 3867 } 3868 break; 3869 case 'D': 3870 double dvalue = 0; 3871 for (int i = 0; i < morder; i++) { 3872 token = st.nextToken().trim(); 3873 dvalue = Double.parseDouble(token); 3874 Array.setDouble(mdata, offset + i, dvalue); 3875 } 3876 break; 3877 default: 3878 isValueChanged = false; 3879 } 3880 } 3881 3882 private class LineplotOption extends JDialog implements ActionListener, ItemListener { 3883 private static final long serialVersionUID = -3457035832213978906L; 3884 public static final int NO_PLOT = -1; 3885 public static final int ROW_PLOT = 0; 3886 public static final int COLUMN_PLOT = 1; 3887 3888 private int idx_xaxis = -1, plotType = -1; 3889 private JRadioButton rowButton, colButton; 3890 @SuppressWarnings("rawtypes") 3891 private JComboBox rowBox, colBox; 3892 3893 @SuppressWarnings({ "rawtypes", "unchecked" }) 3894 public LineplotOption(JFrame owner, String title, int nrow, int ncol) { 3895 super(owner, title, true); 3896 3897 rowBox = new JComboBox(); 3898 rowBox.setEditable(false); 3899 colBox = new JComboBox(); 3900 colBox.setEditable(false); 3901 3902 JPanel contentPane = (JPanel) this.getContentPane(); 3903 contentPane.setPreferredSize(new Dimension(400, 150)); 3904 contentPane.setLayout(new BorderLayout(10, 10)); 3905 3906 long[] startArray = dataset.getStartDims(); 3907 long[] strideArray = dataset.getStride(); 3908 int[] selectedIndex = dataset.getSelectedIndex(); 3909 int start = (int) startArray[selectedIndex[0]]; 3910 int stride = (int) strideArray[selectedIndex[0]]; 3911 3912 rowBox.addItem("array index"); 3913 for (int i = 0; i < nrow; i++) { 3914 rowBox.addItem("row " + (start + indexBase + i * stride)); 3915 } 3916 3917 colBox.addItem("array index"); 3918 for (int i = 0; i < ncol; i++) { 3919 colBox.addItem("column " + table.getColumnName(i)); 3920 } 3921 3922 rowButton = new JRadioButton("Row"); 3923 colButton = new JRadioButton("Column", true); 3924 rowButton.addItemListener(this); 3925 colButton.addItemListener(this); 3926 ButtonGroup rgroup = new ButtonGroup(); 3927 rgroup.add(rowButton); 3928 rgroup.add(colButton); 3929 3930 JPanel p1 = new JPanel(); 3931 p1.setLayout(new GridLayout(2, 1, 5, 5)); 3932 p1.add(new JLabel(" Series in:", SwingConstants.RIGHT)); 3933 p1.add(new JLabel(" For abscissa use:", SwingConstants.RIGHT)); 3934 3935 JPanel p2 = new JPanel(); 3936 p2.setLayout(new GridLayout(2, 1, 5, 5)); 3937 // p2.setBorder(new LineBorder(Color.lightGray)); 3938 p2.add(colButton); 3939 p2.add(colBox); 3940 3941 JPanel p3 = new JPanel(); 3942 p3.setLayout(new GridLayout(2, 1, 5, 5)); 3943 // p3.setBorder(new LineBorder(Color.lightGray)); 3944 p3.add(rowButton); 3945 p3.add(rowBox); 3946 3947 JPanel p = new JPanel(); 3948 p.setBorder(new LineBorder(Color.lightGray)); 3949 p.setLayout(new GridLayout(1, 3, 20, 5)); 3950 p.add(p1); 3951 p.add(p2); 3952 p.add(p3); 3953 3954 JPanel bp = new JPanel(); 3955 3956 JButton okButton = new JButton("Ok"); 3957 okButton.addActionListener(this); 3958 okButton.setActionCommand("Ok"); 3959 bp.add(okButton); 3960 3961 JButton cancelButton = new JButton("Cancel"); 3962 cancelButton.addActionListener(this); 3963 cancelButton.setActionCommand("Cancel"); 3964 bp.add(cancelButton); 3965 3966 contentPane.add(new JLabel(" Select plot options:"), BorderLayout.NORTH); 3967 contentPane.add(p, BorderLayout.CENTER); 3968 contentPane.add(bp, BorderLayout.SOUTH); 3969 3970 colBox.setEnabled(colButton.isSelected()); 3971 rowBox.setEnabled(rowButton.isSelected()); 3972 3973 Point l = getParent().getLocation(); 3974 l.x += 450; 3975 l.y += 200; 3976 setLocation(l); 3977 pack(); 3978 } 3979 3980 int getXindex ( ) { 3981 return idx_xaxis; 3982 } 3983 3984 int getPlotBy ( ) { 3985 return plotType; 3986 } 3987 3988 @Override 3989 public void actionPerformed (ActionEvent e) { 3990 e.getSource(); 3991 String cmd = e.getActionCommand(); 3992 3993 if (cmd.equals("Cancel")) { 3994 plotType = NO_PLOT; 3995 this.dispose(); // terminate the application 3996 } 3997 else if (cmd.equals("Ok")) { 3998 if (colButton.isSelected()) { 3999 idx_xaxis = colBox.getSelectedIndex() - 1; 4000 plotType = COLUMN_PLOT; 4001 } 4002 else { 4003 idx_xaxis = rowBox.getSelectedIndex() - 1; 4004 plotType = ROW_PLOT; 4005 } 4006 4007 this.dispose(); // terminate the application 4008 } 4009 } 4010 4011 @Override 4012 public void itemStateChanged (ItemEvent e) { 4013 Object source = e.getSource(); 4014 4015 if (source.equals(colButton) || source.equals(rowButton)) { 4016 colBox.setEnabled(colButton.isSelected()); 4017 rowBox.setEnabled(rowButton.isSelected()); 4018 } 4019 } 4020 } 4021 4022 private class ColumnHeader extends JTableHeader { 4023 private static final long serialVersionUID = -3179653809792147055L; 4024 private int currentColumnIndex = -1; 4025 private int lastColumnIndex = -1; 4026 private JTable parentTable; 4027 4028 public ColumnHeader(JTable theTable) { 4029 super(theTable.getColumnModel()); 4030 4031 parentTable = theTable; 4032 setReorderingAllowed(false); 4033 } 4034 4035 @Override 4036 protected void processMouseMotionEvent (MouseEvent e) { 4037 super.processMouseMotionEvent(e); 4038 4039 if (e.getID() == MouseEvent.MOUSE_DRAGGED) { 4040 // do not do anything, just resize the column 4041 if (getResizingColumn() != null) return; 4042 4043 int colEnd = columnAtPoint(e.getPoint()); 4044 4045 if (colEnd < 0) { 4046 colEnd = 0; 4047 } 4048 if (currentColumnIndex < 0) { 4049 currentColumnIndex = 0; 4050 } 4051 4052 parentTable.clearSelection(); 4053 4054 if (colEnd > currentColumnIndex) { 4055 parentTable.setColumnSelectionInterval(currentColumnIndex, colEnd); 4056 } 4057 else { 4058 parentTable.setColumnSelectionInterval(colEnd, currentColumnIndex); 4059 } 4060 4061 parentTable.setRowSelectionInterval(0, parentTable.getRowCount() - 1); 4062 } 4063 } 4064 4065 @Override 4066 protected void processMouseEvent (MouseEvent e) { 4067 super.processMouseEvent(e); 4068 4069 int mouseID = e.getID(); 4070 4071 if (mouseID == MouseEvent.MOUSE_CLICKED) { 4072 if (currentColumnIndex < 0) { 4073 return; 4074 } 4075 4076 if (e.isControlDown()) { 4077 // select discontinuous columns 4078 parentTable.addColumnSelectionInterval(currentColumnIndex, currentColumnIndex); 4079 } 4080 else if (e.isShiftDown()) { 4081 // select continuous columns 4082 if (lastColumnIndex < 0) { 4083 parentTable.addColumnSelectionInterval(0, currentColumnIndex); 4084 } 4085 else if (lastColumnIndex < currentColumnIndex) { 4086 parentTable.addColumnSelectionInterval(lastColumnIndex, currentColumnIndex); 4087 } 4088 else { 4089 parentTable.addColumnSelectionInterval(currentColumnIndex, lastColumnIndex); 4090 } 4091 } 4092 else { 4093 // clear old selection and set new column selection 4094 parentTable.clearSelection(); 4095 parentTable.setColumnSelectionInterval(currentColumnIndex, currentColumnIndex); 4096 } 4097 4098 lastColumnIndex = currentColumnIndex; 4099 parentTable.setRowSelectionInterval(0, parentTable.getRowCount() - 1); 4100 } 4101 else if (mouseID == MouseEvent.MOUSE_PRESSED) { 4102 currentColumnIndex = columnAtPoint(e.getPoint()); 4103 } 4104 } 4105 } // private class ColumnHeader 4106 4107 /** RowHeader defines the row header component of the Spreadsheet. */ 4108 private class RowHeader extends JTable { 4109 private static final long serialVersionUID = -1548007702499873626L; 4110 private int currentRowIndex = -1; 4111 private int lastRowIndex = -1; 4112 private JTable parentTable; 4113 4114 public RowHeader(JTable pTable, Dataset dset) { 4115 // Create a JTable with the same number of rows as 4116 // the parent table and one column. 4117 // super( pTable.getRowCount(), 1 ); 4118 4119 final long[] startArray = dset.getStartDims(); 4120 final long[] strideArray = dset.getStride(); 4121 final int[] selectedIndex = dset.getSelectedIndex(); 4122 final int start = (int) startArray[selectedIndex[0]]; 4123 final int stride = (int) strideArray[selectedIndex[0]]; 4124 final int rowCount = pTable.getRowCount(); 4125 parentTable = pTable; 4126 4127 AbstractTableModel tm = new AbstractTableModel() { 4128 private static final long serialVersionUID = -8117073107569884677L; 4129 4130 @Override 4131 public int getColumnCount ( ) { 4132 return 1; 4133 } 4134 4135 @Override 4136 public int getRowCount ( ) { 4137 return rowCount; 4138 } 4139 4140 @Override 4141 public String getColumnName (int col) { 4142 return " "; 4143 } 4144 4145 @Override 4146 public Object getValueAt (int row, int column) { 4147 log.trace("RowHeader:AbstractTableModel:getValueAt"); 4148 return String.valueOf(start + indexBase + row * stride); 4149 } 4150 }; 4151 4152 this.setModel(tm); 4153 4154 // Get the only table column. 4155 TableColumn col = getColumnModel().getColumn(0); 4156 4157 // Use the cell renderer in the column. 4158 col.setCellRenderer(new RowHeaderRenderer()); 4159 } 4160 4161 /** Overridden to return false since the headers are not editable. */ 4162 @Override 4163 public boolean isCellEditable (int row, int col) { 4164 return false; 4165 } 4166 4167 /** This is called when the selection changes in the row headers. */ 4168 @Override 4169 public void valueChanged (ListSelectionEvent e) { 4170 if (parentTable == null) { 4171 return; 4172 } 4173 4174 int rows[] = getSelectedRows(); 4175 if ((rows == null) || (rows.length == 0)) { 4176 return; 4177 } 4178 4179 parentTable.clearSelection(); 4180 parentTable.setRowSelectionInterval(rows[0], rows[rows.length - 1]); 4181 parentTable.setColumnSelectionInterval(0, parentTable.getColumnCount() - 1); 4182 } 4183 4184 @Override 4185 protected void processMouseMotionEvent (MouseEvent e) { 4186 if (e.getID() == MouseEvent.MOUSE_DRAGGED) { 4187 int colEnd = rowAtPoint(e.getPoint()); 4188 4189 if (colEnd < 0) { 4190 colEnd = 0; 4191 } 4192 if (currentRowIndex < 0) { 4193 currentRowIndex = 0; 4194 } 4195 4196 parentTable.clearSelection(); 4197 4198 if (colEnd > currentRowIndex) { 4199 parentTable.setRowSelectionInterval(currentRowIndex, colEnd); 4200 } 4201 else { 4202 parentTable.setRowSelectionInterval(colEnd, currentRowIndex); 4203 } 4204 4205 parentTable.setColumnSelectionInterval(0, parentTable.getColumnCount() - 1); 4206 } 4207 } 4208 4209 @Override 4210 protected void processMouseEvent (MouseEvent e) { 4211 int mouseID = e.getID(); 4212 4213 if (mouseID == MouseEvent.MOUSE_CLICKED) { 4214 if (currentRowIndex < 0) { 4215 return; 4216 } 4217 4218 if (e.isControlDown()) { 4219 // select discontinuous rows 4220 parentTable.addRowSelectionInterval(currentRowIndex, currentRowIndex); 4221 } 4222 else if (e.isShiftDown()) { 4223 // select contiguous columns 4224 if (lastRowIndex < 0) { 4225 parentTable.addRowSelectionInterval(0, currentRowIndex); 4226 } 4227 else if (lastRowIndex < currentRowIndex) { 4228 parentTable.addRowSelectionInterval(lastRowIndex, currentRowIndex); 4229 } 4230 else { 4231 parentTable.addRowSelectionInterval(currentRowIndex, lastRowIndex); 4232 } 4233 } 4234 else { 4235 // clear old selection and set new column selection 4236 parentTable.clearSelection(); 4237 parentTable.setRowSelectionInterval(currentRowIndex, currentRowIndex); 4238 } 4239 4240 lastRowIndex = currentRowIndex; 4241 4242 parentTable.setColumnSelectionInterval(0, parentTable.getColumnCount() - 1); 4243 } 4244 else if (mouseID == MouseEvent.MOUSE_PRESSED) { 4245 currentRowIndex = rowAtPoint(e.getPoint()); 4246 } 4247 } 4248 } // private class RowHeader extends JTable 4249 4250 /** 4251 * RowHeaderRenderer is a custom cell renderer that displays cells as buttons. 4252 */ 4253 private class RowHeaderRenderer extends JLabel implements TableCellRenderer { 4254 private static final long serialVersionUID = -8963879626159783226L; 4255 4256 public RowHeaderRenderer( ) { 4257 super(); 4258 setHorizontalAlignment(SwingConstants.CENTER); 4259 4260 setOpaque(true); 4261 setBorder(UIManager.getBorder("TableHeader.cellBorder")); 4262 setBackground(Color.lightGray); 4263 } 4264 4265 /** Configures the button for the current cell, and returns it. */ 4266 @Override 4267 public Component getTableCellRendererComponent (JTable table, Object value, boolean isSelected, boolean hasFocus, int row, 4268 int column) { 4269 setFont(table.getFont()); 4270 4271 if (value != null) { 4272 setText(value.toString()); 4273 } 4274 4275 return this; 4276 } 4277 } // private class RowHeaderRenderer extends JLabel implements 4278 // TableCellRenderer 4279 4280 @SuppressWarnings("rawtypes") 4281 private class MultiLineHeaderRenderer extends JList implements TableCellRenderer { 4282 private static final long serialVersionUID = -3697496960833719169L; 4283 private final CompoundBorder subBorder = new CompoundBorder(new MatteBorder(1, 0, 1, 0, java.awt.Color.darkGray), 4284 new MatteBorder(1, 0, 1, 0, java.awt.Color.white)); 4285 private final CompoundBorder majorBorder = new CompoundBorder(new MatteBorder(1, 1, 1, 0, java.awt.Color.darkGray), 4286 new MatteBorder(1, 2, 1, 0, java.awt.Color.white)); 4287 Vector<String> lines = new Vector<String>(); 4288 int nSubcolumns = 1; 4289 4290 public MultiLineHeaderRenderer(int majorColumns, int subColumns) { 4291 nSubcolumns = subColumns; 4292 setOpaque(true); 4293 setForeground(UIManager.getColor("TableHeader.foreground")); 4294 setBackground(UIManager.getColor("TableHeader.background")); 4295 } 4296 4297 @Override 4298 public Component getTableCellRendererComponent (JTable table, Object value, boolean isSelected, boolean hasFocus, int row, 4299 int column) { 4300 setFont(table.getFont()); 4301 String str = (value == null) ? "" : value.toString(); 4302 BufferedReader br = new BufferedReader(new StringReader(str)); 4303 String line; 4304 4305 lines.clear(); 4306 try { 4307 while ((line = br.readLine()) != null) { 4308 lines.addElement(line); 4309 } 4310 } 4311 catch (IOException ex) { 4312 log.debug("string read:", ex); 4313 } 4314 4315 if ((column / nSubcolumns) * nSubcolumns == column) { 4316 setBorder(majorBorder); 4317 } 4318 else { 4319 setBorder(subBorder); 4320 } 4321 setListData(lines); 4322 4323 return this; 4324 } 4325 } 4326 4327 // //////////////////////////////////////////////////////////////////////// 4328 // // 4329 // The code below was added to deal with region references // 4330 // Peter Cao, 4/30/2009 // 4331 // // 4332 // //////////////////////////////////////////////////////////////////////// 4333 4334 @Override 4335 public void mouseClicked (MouseEvent e) { 4336 // only deal with reg. ref 4337 if (!(isRegRef || isObjRef)) return; 4338 4339 int eMod = e.getModifiers(); 4340 4341 // provide two options here: double click to show data in table, or 4342 // right mouse to choose to show data in table or in image 4343 4344 // right mouse click 4345 if (e.isPopupTrigger() 4346 || (eMod == InputEvent.BUTTON3_MASK) 4347 || (System.getProperty("os.name").startsWith("Mac") 4348 && (eMod == (InputEvent.BUTTON1_MASK 4349 | Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())))) { 4350 if (popupMenu != null) { 4351 popupMenu.show((JComponent) e.getSource(), e.getX(), e.getY()); 4352 } 4353 } 4354 else if (e.getClickCount() == 2) { 4355 // double click 4356 viewType = ViewType.TABLE; 4357 Object theData = null; 4358 try { 4359 theData = ((Dataset) getDataObject()).getData(); 4360 } 4361 catch (Exception ex) { 4362 JOptionPane.showMessageDialog(this, ex.getMessage(), getTitle(), JOptionPane.ERROR_MESSAGE); 4363 } 4364 4365 if (theData == null) { 4366 toolkit.beep(); 4367 JOptionPane.showMessageDialog(this, "No data selected.", getTitle(), JOptionPane.ERROR_MESSAGE); 4368 return; 4369 4370 } 4371 4372 int[] selectedRows = table.getSelectedRows(); 4373 if (selectedRows == null || selectedRows.length <= 0) { 4374 return; 4375 } 4376 int len = Array.getLength(selectedRows); 4377 for (int i = 0; i < len; i++) { 4378 if (isRegRef) 4379 showRegRefData((String) Array.get(theData, selectedRows[i])); 4380 else if (isObjRef) showObjRefData(Array.getLong(theData, selectedRows[i])); 4381 } 4382 } 4383 } 4384 4385 @Override 4386 public void mouseEntered (MouseEvent e) { 4387 } 4388 4389 @Override 4390 public void mouseExited (MouseEvent e) { 4391 } 4392 4393 @Override 4394 public void mousePressed (MouseEvent e) { 4395 } 4396 4397 @Override 4398 public void mouseReleased (MouseEvent e) { 4399 } 4400 4401 /** creates a popup menu for a right mouse click on a data object */ 4402 private JPopupMenu createPopupMenu ( ) { 4403 JPopupMenu menu = new JPopupMenu(); 4404 JMenuItem item; 4405 4406 item = new JMenuItem("Show As Table"); 4407 item.setMnemonic(KeyEvent.VK_T); 4408 item.addActionListener(this); 4409 item.setActionCommand("Show data as table"); 4410 menu.add(item); 4411 4412 item = new JMenuItem("Show As Image"); 4413 item.setMnemonic(KeyEvent.VK_I); 4414 item.addActionListener(this); 4415 item.setActionCommand("Show data as image"); 4416 menu.add(item); 4417 4418 // item = new JMenuItem( "Show As Text"); 4419 // item.setMnemonic(KeyEvent.VK_I); 4420 // item.addActionListener(this); 4421 // item.setActionCommand("Show data as text"); 4422 // menu.add(item); 4423 4424 return menu; 4425 } 4426 4427 /** 4428 * Display data pointed by object references. Data of each object is shown in a separate 4429 * spreadsheet. 4430 * 4431 * @param ref 4432 * the array of strings that contain the object reference information. 4433 * 4434 */ 4435 private void showObjRefData (long ref) { 4436 long[] oid = { ref }; 4437 log.trace("DefaultTableView showObjRefData: ref={}", ref); 4438 4439 HObject obj = FileFormat.findObject(dataset.getFileFormat(), oid); 4440 if (obj == null || !(obj instanceof ScalarDS)) return; 4441 4442 ScalarDS dset = (ScalarDS) obj; 4443 ScalarDS dset_copy = null; 4444 4445 // create an instance of the dataset constructor 4446 Constructor<? extends ScalarDS> constructor = null; 4447 Object[] paramObj = null; 4448 Object data = null; 4449 4450 try { 4451 Class[] paramClass = { FileFormat.class, String.class, String.class }; 4452 constructor = dset.getClass().getConstructor(paramClass); 4453 paramObj = new Object[] { dset.getFileFormat(), dset.getName(), dset.getPath() }; 4454 dset_copy = (ScalarDS) constructor.newInstance(paramObj); 4455 data = dset_copy.getData(); 4456 } 4457 catch (Exception ex) { 4458 JOptionPane.showMessageDialog(this, ex, "Object Reference:" + getTitle(), JOptionPane.ERROR_MESSAGE); 4459 data = null; 4460 } 4461 4462 if (data == null) return; 4463 4464 JInternalFrame dataView = null; 4465 HashMap map = new HashMap(1); 4466 map.put(ViewProperties.DATA_VIEW_KEY.OBJECT, dset_copy); 4467 switch (viewType) { 4468 case TEXT: 4469 dataView = new DefaultTextView(viewer, map); 4470 break; 4471 case IMAGE: 4472 dataView = new DefaultImageView(viewer, map); 4473 break; 4474 default: 4475 dataView = new DefaultTableView(viewer, map); 4476 break; 4477 } 4478 4479 if (dataView != null) { 4480 viewer.addDataView((DataView) dataView); 4481 } 4482 } 4483 4484 /** 4485 * Display data pointed by region references. Data of each region is shown in a separate 4486 * spreadsheet. The reg. ref. information is stored in strings of the format below: 4487 * <p /> 4488 * <ul> 4489 * <li>For point selections: "file_id:obj_id { <point1> <point2> ...) }", where <point1> is in 4490 * the form of (location_of_dim0, location_of_dim1, ...). For example, 0:800 { (0,1) (2,11) 4491 * (1,0) (2,4) }</li> 4492 * <li>For rectangle selections: 4493 * "file_id:obj_id { <corner coordinates1> <corner coordinates2> ... }", where <corner 4494 * coordinates1> is in the form of (start_corner)-(oposite_corner). For example, 0:800 { 4495 * (0,0)-(0,2) (0,11)-(0,13) (2,0)-(2,2) (2,11)-(2,13) }</li> 4496 * </ul> 4497 * 4498 * @param reg 4499 * the array of strings that contain the reg. ref information. 4500 * 4501 */ 4502 @SuppressWarnings({ "rawtypes", "unchecked" }) 4503 private void showRegRefData (String reg) { 4504 boolean isPointSelection = false; 4505 4506 if (reg == null || (reg.length() <= 0) || (reg.compareTo("NULL") == 0)) return; 4507 log.trace("DefaultTableView showRegRefData: reg={}", reg); 4508 4509 isPointSelection = (reg.indexOf('-') <= 0); 4510 4511 // find the object location 4512 String oidStr = reg.substring(reg.indexOf('/'), reg.indexOf(' ')); 4513 log.trace("DefaultTableView showRegRefData: isPointSelection={} oidStr={}", isPointSelection, oidStr); 4514 4515 // decode the region selection 4516 String regStr = reg.substring(reg.indexOf('{') + 1, reg.indexOf('}')); 4517 if (regStr == null || regStr.length() <= 0) return; // no selection 4518 4519 reg.substring(reg.indexOf('}') + 1); 4520 4521 StringTokenizer st = new StringTokenizer(regStr); 4522 int nSelections = st.countTokens(); 4523 if (nSelections <= 0) return; // no selection 4524 log.trace("DefaultTableView showRegRefData: nSelections={}", nSelections); 4525 4526 HObject obj = FileFormat.findObject(dataset.getFileFormat(), oidStr); 4527 if (obj == null || !(obj instanceof ScalarDS)) return; 4528 4529 ScalarDS dset = (ScalarDS) obj; 4530 ScalarDS dset_copy = null; 4531 4532 // create an instance of the dataset constructor 4533 Constructor<? extends ScalarDS> constructor = null; 4534 Object[] paramObj = null; 4535 try { 4536 @SuppressWarnings("rawtypes") 4537 Class[] paramClass = { FileFormat.class, String.class, String.class }; 4538 constructor = dset.getClass().getConstructor(paramClass); 4539 paramObj = new Object[] { dset.getFileFormat(), dset.getName(), dset.getPath() }; 4540 } 4541 catch (Exception ex) { 4542 constructor = null; 4543 } 4544 4545 // load each selection into a separate dataset and display it in 4546 // a separate spreadsheet 4547 StringBuffer titleSB = new StringBuffer(); 4548 log.trace("DefaultTableView showRegRefData: titleSB created"); 4549 4550 while (st.hasMoreTokens()) { 4551 log.trace("DefaultTableView showRegRefData: st.hasMoreTokens() begin"); 4552 try { 4553 dset_copy = (ScalarDS) constructor.newInstance(paramObj); 4554 } 4555 catch (Exception ex) { 4556 continue; 4557 } 4558 4559 if (dset_copy == null) continue; 4560 4561 try { 4562 dset_copy.init(); 4563 } 4564 catch (Exception ex) { 4565 continue; 4566 } 4567 4568 dset_copy.getRank(); 4569 long start[] = dset_copy.getStartDims(); 4570 long count[] = dset_copy.getSelectedDims(); 4571 4572 // set the selected dimension sizes based on the region selection 4573 // info. 4574 int idx = 0; 4575 String sizeStr = null; 4576 String token = st.nextToken(); 4577 4578 titleSB.setLength(0); 4579 titleSB.append(token); 4580 titleSB.append(" at "); 4581 log.trace("DefaultTableView showRegRefData: titleSB={}", titleSB); 4582 4583 token = token.replace('(', ' '); 4584 token = token.replace(')', ' '); 4585 if (isPointSelection) { 4586 // point selection 4587 StringTokenizer tmp = new StringTokenizer(token, ","); 4588 while (tmp.hasMoreTokens()) { 4589 count[idx] = 1; 4590 sizeStr = tmp.nextToken().trim(); 4591 start[idx] = Long.valueOf(sizeStr); 4592 idx++; 4593 } 4594 } 4595 else { 4596 // rectangle selection 4597 String startStr = token.substring(0, token.indexOf('-')); 4598 String endStr = token.substring(token.indexOf('-') + 1); 4599 StringTokenizer tmp = new StringTokenizer(startStr, ","); 4600 while (tmp.hasMoreTokens()) { 4601 sizeStr = tmp.nextToken().trim(); 4602 start[idx] = Long.valueOf(sizeStr); 4603 idx++; 4604 } 4605 4606 idx = 0; 4607 tmp = new StringTokenizer(endStr, ","); 4608 while (tmp.hasMoreTokens()) { 4609 sizeStr = tmp.nextToken().trim(); 4610 count[idx] = Long.valueOf(sizeStr) - start[idx] + 1; 4611 idx++; 4612 } 4613 } 4614 log.trace("DefaultTableView showRegRefData: selection inited"); 4615 4616 try { 4617 dset_copy.getData(); 4618 } 4619 catch (Exception ex) { 4620 JOptionPane.showMessageDialog(this, ex, "Region Reference:" + getTitle(), JOptionPane.ERROR_MESSAGE); 4621 } 4622 4623 JInternalFrame dataView = null; 4624 HashMap map = new HashMap(1); 4625 map.put(ViewProperties.DATA_VIEW_KEY.OBJECT, dset_copy); 4626 switch (viewType) { 4627 case TEXT: 4628 dataView = new DefaultTextView(viewer, map); 4629 break; 4630 case IMAGE: 4631 dataView = new DefaultImageView(viewer, map); 4632 break; 4633 default: 4634 dataView = new DefaultTableView(viewer, map); 4635 break; 4636 } 4637 4638 if (dataView != null) { 4639 viewer.addDataView((DataView) dataView); 4640 dataView.setTitle(dataView.getTitle() + "; " + titleSB.toString()); 4641 } 4642 log.trace("DefaultTableView showRegRefData: st.hasMoreTokens() end"); 4643 } // while (st.hasMoreTokens()) 4644 } // private void showRegRefData(String reg) 4645}