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 file COPYING. * 009 * COPYING can be found at the root of the source code distribution tree. * 010 * If you do not have access to this file, you may request a copy from * 011 * help@hdfgroup.org. * 012 ****************************************************************************/ 013 014package hdf.view; 015 016import java.awt.BorderLayout; 017import java.awt.Color; 018import java.awt.Component; 019import java.awt.Cursor; 020import java.awt.GridLayout; 021import java.awt.Point; 022import java.awt.Toolkit; 023import java.awt.event.ActionEvent; 024import java.awt.event.ActionListener; 025import java.awt.event.KeyAdapter; 026import java.awt.event.KeyEvent; 027import java.awt.event.MouseAdapter; 028import java.awt.event.MouseEvent; 029import java.io.BufferedInputStream; 030import java.io.BufferedOutputStream; 031import java.io.File; 032import java.io.FileInputStream; 033import java.io.FileOutputStream; 034import java.io.FileNotFoundException; 035import java.io.Serializable; 036import java.lang.reflect.Constructor; 037import java.lang.reflect.Method; 038import java.util.BitSet; 039import java.util.Enumeration; 040import java.util.HashMap; 041import java.util.Iterator; 042import java.util.List; 043import java.util.Vector; 044 045import javax.swing.BorderFactory; 046import javax.swing.ButtonGroup; 047import javax.swing.Icon; 048import javax.swing.JButton; 049import javax.swing.JComboBox; 050import javax.swing.JComponent; 051import javax.swing.JDialog; 052import javax.swing.JFileChooser; 053import javax.swing.JFrame; 054import javax.swing.JInternalFrame; 055import javax.swing.JMenu; 056import javax.swing.JMenuItem; 057import javax.swing.JOptionPane; 058import javax.swing.JPanel; 059import javax.swing.JPopupMenu; 060import javax.swing.JRadioButton; 061import javax.swing.JSeparator; 062import javax.swing.JTree; 063import javax.swing.border.BevelBorder; 064import javax.swing.border.SoftBevelBorder; 065import javax.swing.border.TitledBorder; 066import javax.swing.tree.DefaultMutableTreeNode; 067import javax.swing.tree.DefaultTreeCellRenderer; 068import javax.swing.tree.DefaultTreeModel; 069import javax.swing.tree.MutableTreeNode; 070import javax.swing.tree.TreeNode; 071import javax.swing.tree.TreePath; 072 073import hdf.object.CompoundDS; 074import hdf.object.Dataset; 075import hdf.object.Datatype; 076import hdf.object.FileFormat; 077import hdf.object.Group; 078import hdf.object.HObject; 079import hdf.object.ScalarDS; 080import hdf.view.ViewProperties.DATA_VIEW_KEY; 081 082/** 083 * <p> 084 * TreeView defines APIs for opening files and displaying the file structure in 085 * a tree structure. 086 * 087 * <p> 088 * TreeView uses folders and leaf items to represent groups and data objects in 089 * the file. You can expand or collapse folders to navigate data objects in the 090 * file. 091 * 092 * <p> 093 * From the TreeView, you can open data content or metadata of the selected object. 094 * You can select object(s) to delete or add new objects to the file. 095 */ 096public class DefaultTreeView extends JPanel implements TreeView, ActionListener { 097 private static final long serialVersionUID = 4092566164712521186L; 098 099 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DefaultTreeView.class); 100 101 /** The owner of this TreeView */ 102 private ViewManager viewer; 103 104 /** 105 * The super root of tree: all open files start at this root. 106 */ 107 private final DefaultMutableTreeNode root; 108 109 /** 110 * The tree which holds file structures. 111 */ 112 private final JTree tree; 113 114 /** The currently selected tree node. */ 115 private DefaultMutableTreeNode selectedNode = null; 116 117 /** the list of current selected objects */ 118 private List<Object> objectsToCopy = null; 119 120 private TreePath[] currentSelectionsForMove = null; 121 122 /** The currently selected object */ 123 private HObject selectedObject; 124 125 /** The currently selected file */ 126 private FileFormat selectedFile; 127 128 /** The current selected TreePath. */ 129 private TreePath selectedTreePath; 130 131 /** The tree model */ 132 private final DefaultTreeModel treeModel; 133 134 /** A list of currently open files */ 135 private List<FileFormat> fileList = new Vector<>(); 136 137 /** A list of editing GUI components */ 138 private List<JMenuItem> editGUIs = new Vector<>(); 139 140 /** 141 * The popup menu used to display user choice of actions on data object. 142 */ 143 private final JPopupMenu popupMenu; 144 145 private JMenu exportDatasetMenu; 146 147 private JSeparator separator; 148 149 private JMenuItem addDatasetMenuItem; 150 private JMenuItem addTableMenuItem; 151 private JMenuItem addDatatypeMenuItem; 152 private JMenuItem addLinkMenuItem; 153 private JMenuItem setLibVerBoundsItem; 154 private JMenuItem changeIndexItem; 155 156 private final Toolkit toolkit; 157 158 /** Flag to indicate if the dataset is displayed as default */ 159 private boolean isDefaultDisplay = true; 160 161 /** Flag to indicate if TreeItems are being moved */ 162 private boolean moveFlag = false; 163 164 private boolean isApplyBitmaskOnly = false; 165 166 private int currentIndexType; 167 168 private int currentIndexOrder; 169 170 private int binaryOrder; 171 172 private String currentSearchPhrase = null; 173 174 private enum OBJECT_TYPE {GROUP, DATASET, IMAGE, TABLE, DATATYPE, LINK}; 175 176 public DefaultTreeView(ViewManager theView) { 177 viewer = theView; 178 179 root = new DefaultMutableTreeNode() { 180 private static final long serialVersionUID = -6829919815424470510L; 181 182 public boolean isLeaf() { 183 return false; 184 } 185 }; 186 187 fileList = new Vector<FileFormat>(); 188 toolkit = Toolkit.getDefaultToolkit(); 189 editGUIs = new Vector<JMenuItem>(); 190 objectsToCopy = null; 191 isDefaultDisplay = true; 192 selectedTreePath = null; 193 selectedNode = null; 194 moveFlag = false; 195 currentSelectionsForMove = null; 196 197 addDatasetMenuItem = new JMenuItem("Dataset", ViewProperties.getDatasetIcon()); 198 addDatasetMenuItem.addActionListener(this); 199 addDatasetMenuItem.setActionCommand("Add dataset"); 200 201 addTableMenuItem = new JMenuItem("Compound DS", ViewProperties.getTableIcon()); 202 addTableMenuItem.addActionListener(this); 203 addTableMenuItem.setActionCommand("Add table"); 204 205 addDatatypeMenuItem = new JMenuItem("Datatype", ViewProperties.getDatatypeIcon()); 206 addDatatypeMenuItem.addActionListener(this); 207 addDatatypeMenuItem.setActionCommand("Add datatype"); 208 209 addLinkMenuItem = new JMenuItem("Link", ViewProperties.getLinkIcon()); 210 addLinkMenuItem.addActionListener(this); 211 addLinkMenuItem.setActionCommand("Add link"); 212 213 setLibVerBoundsItem = new JMenuItem("Set Lib version bounds"); 214 setLibVerBoundsItem.addActionListener(this); 215 setLibVerBoundsItem.setActionCommand("Set Lib version bounds"); 216 217 changeIndexItem = new JMenuItem("Change file indexing"); 218 changeIndexItem.addActionListener(this); 219 changeIndexItem.setActionCommand("Change file indexing"); 220 221 // initialize the tree and root 222 treeModel = new DefaultTreeModel(root); 223 tree = new JTree(treeModel); 224 225 tree.setLargeModel(true); 226 tree.setCellRenderer(new HTreeCellRenderer()); 227 tree.addMouseListener(new HTreeMouseAdapter()); 228 tree.addKeyListener(new HTreeKeyAdapter()); 229 tree.setRootVisible(false); 230 // tree.setShowsRootHandles(true); 231 int rowheight = 23 + (int) ((tree.getFont().getSize() - 12) * 0.5); 232 tree.setRowHeight(rowheight); 233 234 // create the separator 235 separator = new JPopupMenu.Separator(); 236 237 // create the popupmenu 238 popupMenu = createPopupMenu(); 239 240 // reset the scroll increament 241 // layout GUI component 242 this.setLayout(new BorderLayout()); 243 this.add(tree, BorderLayout.CENTER); 244 } 245 246 /** Creates a popup menu for a right mouse click on a data object */ 247 private JPopupMenu createPopupMenu() { 248 JPopupMenu menu = new JPopupMenu(); 249 JMenuItem item; 250 251 item = new JMenuItem("Open"); 252 item.setMnemonic(KeyEvent.VK_O); 253 item.addActionListener(this); 254 item.setActionCommand("Open data"); 255 menu.add(item); 256 257 item = new JMenuItem("Open As"); 258 item.setMnemonic(KeyEvent.VK_A); 259 item.addActionListener(this); 260 item.setActionCommand("Open data as"); 261 menu.add(item); 262 263 menu.addSeparator(); 264 265 JMenu newOjbectMenu = new JMenu("New"); 266 menu.add(newOjbectMenu); 267 editGUIs.add(newOjbectMenu); 268 269 item = new JMenuItem("Group", ViewProperties.getFoldercloseIcon()); 270 item.addActionListener(this); 271 item.setActionCommand("Add group"); 272 newOjbectMenu.add(item); 273 274 newOjbectMenu.add(addDatasetMenuItem); 275 276 item = new JMenuItem("Image", ViewProperties.getImageIcon()); 277 item.addActionListener(this); 278 item.setActionCommand("Add image"); 279 newOjbectMenu.add(item); 280 281 newOjbectMenu.add(addTableMenuItem); 282 newOjbectMenu.add(addDatatypeMenuItem); 283 newOjbectMenu.add(addLinkMenuItem); 284 285 menu.addSeparator(); 286 287 item = new JMenuItem("Copy"); 288 item.setMnemonic(KeyEvent.VK_C); 289 item.addActionListener(this); 290 item.setActionCommand("Copy object"); 291 menu.add(item); 292 293 item = new JMenuItem("Paste"); 294 item.setMnemonic(KeyEvent.VK_P); 295 item.addActionListener(this); 296 item.setActionCommand("Paste object"); 297 menu.add(item); 298 editGUIs.add(item); 299 300 item = new JMenuItem("Delete"); 301 item.setMnemonic(KeyEvent.VK_D); 302 item.addActionListener(this); 303 item.setActionCommand("Cut object"); 304 menu.add(item); 305 editGUIs.add(item); 306 307 item = new JMenuItem("Cut"); 308 item.setMnemonic(KeyEvent.VK_T); 309 item.addActionListener(this); 310 item.setActionCommand("Move object"); 311 menu.add(item); 312 editGUIs.add(item); 313 314 exportDatasetMenu = new JMenu("Export Dataset"); 315 menu.add(exportDatasetMenu); 316 item = new JMenuItem("Export Data to Text File"); 317 item.addActionListener(this); 318 item.setActionCommand("Save table as text"); 319 exportDatasetMenu.add(item); 320 321 item = new JMenuItem("Export Data as Native Order"); 322 item.addActionListener(this); 323 item.setActionCommand("Save table as binary Native Order"); 324 exportDatasetMenu.add(item); 325 item = new JMenuItem("Export Data as Little Endian"); 326 item.addActionListener(this); 327 item.setActionCommand("Save table as binary Little Endian"); 328 exportDatasetMenu.add(item); 329 item = new JMenuItem("Export Data as Big Endian"); 330 item.addActionListener(this); 331 item.setActionCommand("Save table as binary Big Endian"); 332 exportDatasetMenu.add(item); 333 334 menu.addSeparator(); 335 336 item = new JMenuItem("Save to"); 337 item.setMnemonic(KeyEvent.VK_S); 338 item.addActionListener(this); 339 item.setActionCommand("Save object to file"); 340 menu.add(item); 341 342 item = new JMenuItem("Rename"); 343 item.setMnemonic(KeyEvent.VK_R); 344 item.addActionListener(this); 345 item.setActionCommand("Rename object"); 346 menu.add(item); 347 editGUIs.add(item); 348 349 menu.addSeparator(); 350 351 item = new JMenuItem("Show Properties"); 352 item.addActionListener(this); 353 item.setActionCommand("Show object properties"); 354 menu.add(item); 355 356 item = new JMenuItem("Show Properties As"); 357 item.addActionListener(this); 358 item.setActionCommand("Show object properties as"); 359 menu.add(item); 360 361 menu.add(changeIndexItem); 362 363 menu.addSeparator(); 364 365 item = new JMenuItem("Find"); 366 item.setMnemonic(KeyEvent.VK_F); 367 item.addActionListener(this); 368 item.setActionCommand("Find"); 369 menu.add(item); 370 371 // item = new JMenuItem( "Find Next"); 372 // item.setMnemonic(KeyEvent.VK_N); 373 // item.addActionListener(this); 374 // item.setActionCommand("Find next"); 375 // menu.add(item); 376 377 menu.addSeparator(); 378 379 item = new JMenuItem("Expand All"); 380 item.addActionListener(this); 381 item.setActionCommand("Expand all"); 382 menu.add(item); 383 item = new JMenuItem("Collapse All"); 384 item.addActionListener(this); 385 item.setActionCommand("Collapse all"); 386 menu.add(item); 387 388 menu.addSeparator(); 389 390 item = new JMenuItem("Close File"); 391 item.setMnemonic(KeyEvent.VK_E); 392 item.addActionListener(this); 393 item.setActionCommand("Close file"); 394 menu.add(item); 395 396 item = new JMenuItem("Reload File"); 397 // item.setMnemonic(KeyEvent.VK_R); 398 item.addActionListener(this); 399 item.setActionCommand("Reload file"); 400 menu.add(item); 401 402 menu.add(separator); 403 menu.add(setLibVerBoundsItem); 404 405 return menu; 406 } 407 408 /** display the popupmenu of data properties */ 409 private void showPopupMenu(MouseEvent e) { 410 int x = e.getX(); 411 int y = e.getY(); 412 413 HObject selectedObject = ((HObject) (selectedNode.getUserObject())); 414 boolean isReadOnly = selectedObject.getFileFormat().isReadOnly(); 415 boolean isWritable = !isReadOnly; 416 417 setEnabled(editGUIs, !isReadOnly); 418 419 if (selectedObject instanceof Group) { 420 boolean state = !(((Group) selectedObject).isRoot()); 421 422 popupMenu.getComponent(0).setEnabled(false); // "Open" menuitem 423 popupMenu.getComponent(1).setEnabled(false); // "Open as" menuitem 424 popupMenu.getComponent(8).setEnabled( 425 (selectedObject.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5))) 426 && state && isWritable); // "Cut" menuitem 427 popupMenu.getComponent(5).setEnabled(state); // "Copy" menuitem 428 popupMenu.getComponent(6).setEnabled(isWritable); // "Paste" menuitem 429 popupMenu.getComponent(7).setEnabled(state && isWritable); // "Delete" menuitem 430 popupMenu.getComponent(11).setEnabled(state); // "Save to" menuitem 431 popupMenu.getComponent(12).setEnabled(state && isWritable); // "Rename" menuitem 432 } 433 else { 434 popupMenu.getComponent(0).setEnabled(true); // "Open" menuitem 435 popupMenu.getComponent(1).setEnabled(true); // "Open as" menuitem 436 popupMenu.getComponent(8).setEnabled( 437 (selectedObject.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5))) 438 && isWritable); // "Cut" menuitem 439 popupMenu.getComponent(5).setEnabled(true); // "Copy" menuitem 440 popupMenu.getComponent(6).setEnabled(isWritable); // "Paste" menuitem 441 popupMenu.getComponent(7).setEnabled(isWritable); // "Delete" menuitem 442 popupMenu.getComponent(11).setEnabled(true); // "Save to" menuitem 443 popupMenu.getComponent(12).setEnabled(isWritable); // "Rename" menuitem 444 } 445 446 // Adding table is only supported by HDF5 447 if ((selectedFile != null) && selectedFile.isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5))) { 448 addDatasetMenuItem.setText("Dataset"); 449 addTableMenuItem.setVisible(true); 450 addDatatypeMenuItem.setVisible(true); 451 addLinkMenuItem.setVisible(true); 452 boolean state = false; 453 if ((selectedObject instanceof Group)) { 454 state = (((Group) selectedObject).isRoot()); 455 separator.setVisible(isWritable && state); 456 setLibVerBoundsItem.setVisible(isWritable && state); // added only if it is HDF5format, iswritable & isroot 457 } 458 else { 459 separator.setVisible(false); 460 setLibVerBoundsItem.setVisible(false); 461 } 462 changeIndexItem.setVisible(state); 463 } 464 else { 465 addDatasetMenuItem.setText("SDS"); 466 addTableMenuItem.setVisible(false); 467 addDatatypeMenuItem.setVisible(false); 468 addLinkMenuItem.setVisible(false); 469 separator.setVisible(false); 470 setLibVerBoundsItem.setVisible(false); 471 changeIndexItem.setVisible(false); 472 } 473 474 // Export table is only supported by HDF5 475 if ((selectedObject != null) && selectedObject.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5))) { 476 if ((selectedObject instanceof Dataset)) { 477 Dataset dataset = (Dataset) selectedObject; 478 if ((dataset instanceof ScalarDS)) { 479 exportDatasetMenu.setVisible(true); 480 } 481 } 482 else { 483 exportDatasetMenu.setVisible(false); 484 } 485 } 486 else { 487 exportDatasetMenu.setVisible(false); 488 } 489 490 popupMenu.show((JComponent) e.getSource(), x, y); 491 } 492 493 // Implementing java.io.ActionListener 494 public void actionPerformed(ActionEvent e) { 495 String cmd = e.getActionCommand(); 496 497 if (cmd.equals("Close file")) { 498 ((HDFView) viewer).actionPerformed(e); 499 } 500 else if (cmd.equals("Reload file")) { 501 ((HDFView) viewer).actionPerformed(e); 502 } 503 else if (cmd.equals("Add group")) { 504 addGroup(); 505 } 506 else if (cmd.equals("Add dataset")) { 507 addDataset(); 508 } 509 else if (cmd.equals("Add image")) { 510 addImage(); 511 } 512 else if (cmd.equals("Add table")) { 513 addTable(); 514 } 515 else if (cmd.equals("Add datatype")) { 516 addDatatype(); 517 } 518 else if (cmd.equals("Add link")) { 519 addLink(); 520 } 521 else if (cmd.equals("Save table as text")) { 522 binaryOrder = 99; 523 try { 524 saveAsFile(); 525 } 526 catch (Exception ex) { 527 toolkit.beep(); 528 JOptionPane.showMessageDialog((JFrame) viewer, ex, "Export Dataset", JOptionPane.ERROR_MESSAGE); 529 } 530 } 531 else if (cmd.startsWith("Save table as binary")) { 532 if (cmd.equals("Save table as binary Native Order")) binaryOrder = 1; 533 if (cmd.equals("Save table as binary Little Endian")) binaryOrder = 2; 534 if (cmd.equals("Save table as binary Big Endian")) binaryOrder = 3; 535 try { 536 saveAsFile(); 537 } 538 catch (Exception ex) { 539 toolkit.beep(); 540 JOptionPane.showMessageDialog((JFrame) viewer, ex, "Export Dataset", JOptionPane.ERROR_MESSAGE); 541 } 542 } 543 else if (cmd.startsWith("Open data")) { 544 if (cmd.equals("Open data")) { 545 isDefaultDisplay = true; 546 } 547 else { 548 isDefaultDisplay = false; 549 } 550 551 try { 552 showDataContent(selectedObject); 553 } 554 catch (Throwable err) { 555 toolkit.beep(); 556 JOptionPane.showMessageDialog(this, err, "HDFView", JOptionPane.ERROR_MESSAGE); 557 return; 558 } 559 } 560 else if (cmd.equals("Copy object")) { 561 copyObject(); 562 } 563 else if (cmd.equals("Paste object")) { 564 pasteObject(); 565 } 566 else if (cmd.equals("Cut object")) { 567 cutObject(); 568 } 569 else if (cmd.equals("Move object")) { 570 moveObject(); 571 } 572 else if (cmd.equals("Save object to file")) { 573 if (selectedObject == null) { 574 return; 575 } 576 577 if ((selectedObject instanceof Group) && ((Group) selectedObject).isRoot()) { 578 toolkit.beep(); 579 JOptionPane.showMessageDialog(this, 580 "Cannot save the root group.\nUse \"Save As\" from file menu to save the whole file", 581 "HDFView", JOptionPane.ERROR_MESSAGE); 582 return; 583 } 584 585 String filetype = FileFormat.FILE_TYPE_HDF4; 586 boolean isH5 = selectedObject.getFileFormat().isThisType( 587 FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5)); 588 if (isH5) { 589 filetype = FileFormat.FILE_TYPE_HDF5; 590 } 591 592 NewFileDialog dialog = new NewFileDialog((JFrame) viewer, selectedObject.getFileFormat().getParent(), 593 filetype, fileList); 594 // dialog.show(); 595 596 if (!dialog.isFileCreated()) { 597 return; 598 } 599 600 String filename = dialog.getFile(); 601 FileFormat dstFile = null; 602 try { 603 dstFile = openFile(filename, FileFormat.WRITE); 604 } 605 catch (Exception ex) { 606 toolkit.beep(); 607 JOptionPane.showMessageDialog(this, ex.getMessage() + "\n" + filename, "HDFView", 608 JOptionPane.ERROR_MESSAGE); 609 } 610 List<Object> objList = new Vector<Object>(2); 611 objList.add(selectedObject); 612 pasteObject(objList, dstFile.getRootNode(), dstFile); 613 } 614 else if (cmd.equals("Rename object")) { 615 renameObject(); 616 } 617 else if (cmd.startsWith("Show object properties")) { 618 if (cmd.equals("Show object properties")) { 619 isDefaultDisplay = true; 620 } 621 else { 622 isDefaultDisplay = false; 623 } 624 625 try { 626 showMetaData(selectedObject); 627 } 628 catch (Exception ex) { 629 toolkit.beep(); 630 JOptionPane.showMessageDialog(this, ex, "HDFView", JOptionPane.ERROR_MESSAGE); 631 } 632 } 633 else if (cmd.startsWith("Find")) { 634 if (cmd.equals("Find")) { 635 String findStr = currentSearchPhrase; 636 if (findStr == null) findStr = ""; 637 638 findStr = (String) JOptionPane.showInputDialog(this, "Find (e.g. O3Quality, O3*, or *Quality):", 639 "Find Object by Name", JOptionPane.PLAIN_MESSAGE, null, null, findStr); 640 641 if (findStr != null && findStr.length() > 0) currentSearchPhrase = findStr; 642 } 643 644 find(currentSearchPhrase, selectedTreePath, tree); 645 } 646 else if (cmd.startsWith("Expand all")) { 647 int row = 0; 648 while (row < tree.getRowCount()) { 649 tree.expandRow(row); 650 row++; 651 } 652 } 653 else if (cmd.startsWith("Collapse all")) { 654 int row = tree.getRowCount() - 1; 655 while (row >= 0) { 656 tree.collapseRow(row); 657 row--; 658 } 659 } 660 else if (cmd.startsWith("Set Lib version bounds")) { 661 setLibVersionBounds(); 662 } 663 else if (cmd.startsWith("Change file indexing")) { 664 ChangeIndexingDialog dialog = new ChangeIndexingDialog((JFrame) viewer, selectedFile); 665 dialog.setVisible(true); 666 if (dialog.isreloadFile()) { 667 selectedFile.setIndexType(dialog.getIndexType()); 668 selectedFile.setIndexOrder(dialog.getIndexOrder()); 669 ((HDFView) viewer).reloadFile(); 670 } 671 } 672 } 673 674 private void addGroup() { 675 if ((selectedObject == null) || (selectedNode == null)) { 676 return; 677 } 678 679 Group pGroup = null; 680 if (selectedObject instanceof Group) { 681 pGroup = (Group) selectedObject; 682 } 683 else { 684 pGroup = (Group) ((DefaultMutableTreeNode) selectedNode.getParent()).getUserObject(); 685 } 686 687 NewGroupDialog dialog = new NewGroupDialog((JFrame) viewer, pGroup, 688 breadthFirstUserObjects(selectedObject.getFileFormat().getRootNode())); 689 dialog.setVisible(true); 690 691 HObject obj = (HObject) dialog.getObject(); 692 if (obj == null) { 693 return; 694 } 695 696 Group pgroup = dialog.getParentGroup(); 697 try { 698 this.addObject(obj, pgroup); 699 } 700 catch (Exception ex) { 701 toolkit.beep(); 702 JOptionPane.showMessageDialog(this, ex, "HDFView", JOptionPane.ERROR_MESSAGE); 703 return; 704 } 705 } 706 707 private void addDataset() { 708 if ((selectedObject == null) || (selectedNode == null)) { 709 return; 710 } 711 712 Group pGroup = null; 713 if (selectedObject instanceof Group) { 714 pGroup = (Group) selectedObject; 715 } 716 else { 717 pGroup = (Group) ((DefaultMutableTreeNode) selectedNode.getParent()).getUserObject(); 718 } 719 720 NewDatasetDialog dialog = new NewDatasetDialog((JFrame) viewer, pGroup, 721 breadthFirstUserObjects(selectedObject.getFileFormat().getRootNode())); 722 dialog.setVisible(true); 723 724 HObject obj = (HObject) dialog.getObject(); 725 if (obj == null) { 726 return; 727 } 728 729 Group pgroup = dialog.getParentGroup(); 730 try { 731 addObject(obj, pgroup); 732 } 733 catch (Exception ex) { 734 toolkit.beep(); 735 JOptionPane.showMessageDialog(this, ex, "HDFView", JOptionPane.ERROR_MESSAGE); 736 return; 737 } 738 } 739 740 private void addImage() { 741 if ((selectedObject == null) || (selectedNode == null)) { 742 return; 743 } 744 745 Group pGroup = null; 746 if (selectedObject instanceof Group) { 747 pGroup = (Group) selectedObject; 748 } 749 else { 750 pGroup = (Group) ((DefaultMutableTreeNode) selectedNode.getParent()).getUserObject(); 751 } 752 753 NewImageDialog dialog = new NewImageDialog((JFrame) viewer, pGroup, breadthFirstUserObjects(selectedObject 754 .getFileFormat().getRootNode())); 755 dialog.setVisible(true); 756 757 HObject obj = (HObject) dialog.getObject(); 758 if (obj == null) { 759 return; 760 } 761 762 Group pgroup = dialog.getParentGroup(); 763 try { 764 this.addObject(obj, pgroup); 765 } 766 catch (Exception ex) { 767 toolkit.beep(); 768 JOptionPane.showMessageDialog(this, ex, "HDFView", JOptionPane.ERROR_MESSAGE); 769 return; 770 } 771 } 772 773 private void addTable() { 774 if ((selectedObject == null) || (selectedNode == null)) { 775 return; 776 } 777 778 Group pGroup = null; 779 if (selectedObject instanceof Group) { 780 pGroup = (Group) selectedObject; 781 } 782 else { 783 pGroup = (Group) ((DefaultMutableTreeNode) selectedNode.getParent()).getUserObject(); 784 } 785 786 NewTableDataDialog dialog = new NewTableDataDialog((JFrame) viewer, pGroup, 787 breadthFirstUserObjects(selectedObject.getFileFormat().getRootNode())); 788 dialog.setVisible(true); 789 790 HObject obj = (HObject) dialog.getObject(); 791 if (obj == null) { 792 return; 793 } 794 795 Group pgroup = dialog.getParentGroup(); 796 try { 797 addObject(obj, pgroup); 798 } 799 catch (Exception ex) { 800 toolkit.beep(); 801 JOptionPane.showMessageDialog(this, ex, "HDFView", JOptionPane.ERROR_MESSAGE); 802 return; 803 } 804 } 805 806 private void addDatatype() { 807 if ((selectedObject == null) || (selectedNode == null)) { 808 return; 809 } 810 811 Group pGroup = null; 812 if (selectedObject instanceof Group) { 813 pGroup = (Group) selectedObject; 814 } 815 else { 816 pGroup = (Group) ((DefaultMutableTreeNode) selectedNode.getParent()).getUserObject(); 817 } 818 819 NewDatatypeDialog dialog = new NewDatatypeDialog((JFrame) viewer, pGroup, 820 breadthFirstUserObjects(selectedObject.getFileFormat().getRootNode())); 821 dialog.setVisible(true); 822 823 HObject obj = (HObject) dialog.getObject(); 824 if (obj == null) { 825 return; 826 } 827 828 Group pgroup = dialog.getParentGroup(); 829 try { 830 addObject(obj, pgroup); 831 } 832 catch (Exception ex) { 833 toolkit.beep(); 834 JOptionPane.showMessageDialog(this, ex, "HDFView", JOptionPane.ERROR_MESSAGE); 835 return; 836 } 837 } 838 839 private void addLink() { 840 if ((selectedObject == null) || (selectedNode == null)) { 841 return; 842 } 843 844 Group pGroup = null; 845 if (selectedObject instanceof Group) { 846 pGroup = (Group) selectedObject; 847 } 848 else { 849 pGroup = (Group) ((DefaultMutableTreeNode) selectedNode.getParent()).getUserObject(); 850 } 851 852 NewLinkDialog dialog = new NewLinkDialog((JFrame) viewer, pGroup, breadthFirstUserObjects(selectedObject 853 .getFileFormat().getRootNode())); 854 dialog.setVisible(true); 855 856 HObject obj = (HObject) dialog.getObject(); 857 if (obj == null) { 858 return; 859 } 860 861 Group pgroup = dialog.getParentGroup(); 862 try { 863 addObject(obj, pgroup); 864 } 865 catch (Exception ex) { 866 toolkit.beep(); 867 JOptionPane.showMessageDialog(this, ex, "HDFView", JOptionPane.ERROR_MESSAGE); 868 return; 869 } 870 } 871 872 /** 873 * Adds a new data object to the file. 874 * 875 * @param newObject 876 * the object to add. 877 * @param parentGroup 878 * the parent group to add the object to. 879 * 880 * @throws Exception if an exception occurs while adding a new data object to the file 881 */ 882 public void addObject(HObject newObject, Group parentGroup) throws Exception { 883 if ((newObject == null) || (parentGroup == null)) { 884 return; 885 } 886 887 TreeNode pnode = findTreeNode(parentGroup); 888 TreeNode newnode = null; 889 if (newObject instanceof Group) { 890 newnode = new DefaultMutableTreeNode(newObject) { 891 private static final long serialVersionUID = -8852535261445958398L; 892 893 public boolean isLeaf() { 894 return false; 895 } 896 }; 897 } 898 else { 899 newnode = new DefaultMutableTreeNode(newObject); 900 } 901 902 treeModel.insertNodeInto((DefaultMutableTreeNode) newnode, (DefaultMutableTreeNode) pnode, 903 pnode.getChildCount()); 904 } 905 906 /** 907 * Insert an object into the tree. 908 * 909 * @param obj 910 * the object to insert. 911 * @param pobj 912 * the parent node. 913 */ 914 private void insertNode(TreeNode obj, TreeNode pobj) { 915 if ((obj == null) || (pobj == null)) { 916 return; 917 } 918 919 treeModel.insertNodeInto((DefaultMutableTreeNode) obj, (DefaultMutableTreeNode) pobj, pobj.getChildCount()); 920 } 921 922 /** Move selected objects */ 923 private void moveObject() { 924 log.trace("moveObject: start"); 925 objectsToCopy = getSelectedObjects(); 926 moveFlag = true; 927 currentSelectionsForMove = tree.getSelectionPaths(); 928 } 929 930 /** Copy selected objects */ 931 private void copyObject() { 932 log.trace("copyObject: start"); 933 int op = -1; 934 if (moveFlag == true) { 935 String moveMsg = "Do you want to copy all the selected object(s) instead of move?"; 936 op = JOptionPane.showConfirmDialog(this, moveMsg, "Copy object", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); 937 } 938 939 log.trace("cutObject(): op={}", op); 940 if (op == JOptionPane.NO_OPTION) { 941 return; 942 } 943 moveFlag = false; 944 currentSelectionsForMove = null; 945 objectsToCopy = getSelectedObjects(); 946 } 947 948 /** Delete selected objects */ 949 private void cutObject() { 950 log.trace("cutObject: start"); 951 int op = -1; 952 if (moveFlag == true) { 953 String moveMsg = "Do you want to delete all the selected object(s) instead of move?"; 954 op = JOptionPane.showConfirmDialog(this, moveMsg, "Delete object", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); 955 } 956 957 log.trace("cutObject(): op={}", op); 958 if (op == JOptionPane.NO_OPTION) { 959 return; 960 } 961 moveFlag = false; 962 currentSelectionsForMove = null; 963 objectsToCopy = getSelectedObjects(); 964 removeSelectedObjects(); 965 } 966 967 /** Paste selected objects */ 968 private void pasteObject() { 969 log.trace("pasteObject(): start"); 970 if (moveFlag == true) { 971 log.trace("pasteObject: move"); 972 HObject theObj = null; 973 for (int i = 0; i < currentSelectionsForMove.length; i++) { 974 DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode) (currentSelectionsForMove[i].getLastPathComponent()); 975 theObj = (HObject) currentNode.getUserObject(); 976 977 log.trace("pasteObject(): check if currentSelectionsForMove[{}] is open", i); 978 if (isObjectOpen(theObj)) { 979 toolkit.beep(); 980 JOptionPane.showMessageDialog(this, "Cannot move the selected object: " + theObj 981 + "\nThe dataset or dataset in the group is in use." 982 + "\n\nPlease close the dataset(s) and try again.\n", "HDFView", JOptionPane.ERROR_MESSAGE); 983 moveFlag = false; 984 currentSelectionsForMove = null; 985 objectsToCopy = null; 986 return; 987 } 988 } 989 } 990 991 TreeNode pitem = selectedNode; 992 993 if ((objectsToCopy == null) || (objectsToCopy.size() <= 0) || (pitem == null)) { 994 return; 995 } 996 997 log.trace("pasteObject(): verify file properties"); 998 FileFormat srcFile = ((HObject) objectsToCopy.get(0)).getFileFormat(); 999 FileFormat dstFile = getSelectedFile(); 1000 FileFormat h5file = FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5); 1001 FileFormat h4file = FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF4); 1002 1003 if (srcFile == null) { 1004 toolkit.beep(); 1005 JOptionPane.showMessageDialog(this, "Source file is null.", "HDFView", JOptionPane.ERROR_MESSAGE); 1006 return; 1007 } 1008 else if (dstFile == null) { 1009 toolkit.beep(); 1010 JOptionPane.showMessageDialog(this, "Destination file is null.", "HDFView", JOptionPane.ERROR_MESSAGE); 1011 return; 1012 } 1013 else if (srcFile.isThisType(h4file) && dstFile.isThisType(h5file)) { 1014 toolkit.beep(); 1015 JOptionPane.showMessageDialog(this, "Unsupported operation: cannot copy HDF4 object to HDF5 file", 1016 "HDFView", JOptionPane.ERROR_MESSAGE); 1017 return; 1018 } 1019 else if (srcFile.isThisType(h5file) && dstFile.isThisType(h4file)) { 1020 toolkit.beep(); 1021 JOptionPane.showMessageDialog(this, "Unsupported operation: cannot copy HDF5 object to HDF4 file", 1022 "HDFView", JOptionPane.ERROR_MESSAGE); 1023 return; 1024 } 1025 1026 if (moveFlag == true) { 1027 log.trace("pasteObject(): check if src and dest are different files"); 1028 if (srcFile != dstFile) { 1029 toolkit.beep(); 1030 JOptionPane.showMessageDialog(this, "Cannot move the selected object to different file", "HDFView", 1031 JOptionPane.ERROR_MESSAGE); 1032 moveFlag = false; 1033 currentSelectionsForMove = null; 1034 objectsToCopy = null; 1035 return; 1036 } 1037 } 1038 1039 if (pitem.isLeaf()) { 1040 pitem = pitem.getParent(); 1041 } 1042 1043 Group pgroup = (Group) ((DefaultMutableTreeNode) pitem).getUserObject(); 1044 String fullPath = pgroup.getPath() + pgroup.getName(); 1045 if (pgroup.isRoot()) { 1046 fullPath = HObject.separator; 1047 } 1048 log.trace("pasteObject(): fullPath={}",fullPath); 1049 1050 String msg = ""; 1051 int msgType = JOptionPane.QUESTION_MESSAGE; 1052 if (srcFile.isThisType(h4file)) { 1053 msg = "WARNING: object can not be deleted after it is copied.\n\n"; 1054 msgType = JOptionPane.WARNING_MESSAGE; 1055 } 1056 1057 msg += "Do you want to copy the selected object(s) to \nGroup: " + fullPath + "\nFile: " 1058 + dstFile.getFilePath(); 1059 1060 int op = -1; 1061 if (moveFlag == true) { 1062 String moveMsg = "Do you want to move the selected object(s) to \nGroup: " + fullPath + "\nFile: " 1063 + dstFile.getFilePath(); 1064 op = JOptionPane.showConfirmDialog(this, moveMsg, "Move Object", JOptionPane.YES_NO_OPTION, msgType); 1065 } 1066 else { 1067 op = JOptionPane.showConfirmDialog(this, msg, "Copy object", JOptionPane.YES_NO_OPTION, msgType); 1068 } 1069 1070 log.trace("pasteObject(): op={}", op); 1071 if (op == JOptionPane.NO_OPTION) { 1072 return; 1073 } 1074 1075 pasteObject(objectsToCopy, pitem, dstFile); 1076 1077 if (moveFlag == true) { 1078 removeSelectedObjects(); 1079 moveFlag = false; 1080 currentSelectionsForMove = null; 1081 objectsToCopy = null; 1082 } 1083 log.trace("pasteObject(): finish"); 1084 } 1085 1086 /** Paste selected objects */ 1087 private void pasteObject(List<Object> objList, TreeNode pobj, FileFormat dstFile) { 1088 if ((objList == null) || (objList.size() <= 0) || (pobj == null)) return; 1089 1090 FileFormat srcFile = ((HObject) objList.get(0)).getFileFormat(); 1091 Group pgroup = (Group) ((DefaultMutableTreeNode) pobj).getUserObject(); 1092 log.trace("pasteObject(...): start"); 1093 1094 HObject theObj = null; 1095 Iterator<Object> iterator = objList.iterator(); 1096 while (iterator.hasNext()) { 1097 theObj = (HObject) iterator.next(); 1098 1099 if ((theObj instanceof Group) && ((Group) theObj).isRoot()) { 1100 toolkit.beep(); 1101 JOptionPane.showMessageDialog(this, "Unsupported operation: cannot copy the root group", "HDFView", 1102 JOptionPane.ERROR_MESSAGE); 1103 return; 1104 } 1105 1106 // Check if it creates infinite loop 1107 Group pg = pgroup; 1108 while (!pg.isRoot()) { 1109 if (theObj.equals(pg)) { 1110 toolkit.beep(); 1111 JOptionPane.showMessageDialog(this, "Unsupported operation: cannot copy a group to itself.", 1112 "HDFView", JOptionPane.ERROR_MESSAGE); 1113 return; 1114 } 1115 pg = pg.getParent(); 1116 } 1117 1118 try { 1119 log.trace("pasteObject(...): dstFile.copy({}, {}, null)", theObj, pgroup); 1120 1121 TreeNode newObj = null; 1122 if((newObj = srcFile.copy(theObj, pgroup, null)) != null) { 1123 // Add the node to the tree 1124 insertNode(newObj, pobj); 1125 } 1126 } 1127 catch (Exception ex) { 1128 toolkit.beep(); 1129 JOptionPane.showMessageDialog(this, ex, "HDFView", JOptionPane.ERROR_MESSAGE); 1130 // newNode = null; 1131 } 1132 } // while (iterator.hasNext()) 1133 log.trace("pasteObject(...): finish"); 1134 } 1135 1136 private void renameObject() { 1137 int op = -1; 1138 if (moveFlag == true) { 1139 String moveMsg = "Do you want to rename all the selected object(s) instead of move?"; 1140 op = JOptionPane.showConfirmDialog(this, moveMsg, "Rename object", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); 1141 } 1142 1143 log.trace("renameObject(): op={}", op); 1144 if (op == JOptionPane.NO_OPTION) { 1145 return; 1146 } 1147 moveFlag = false; 1148 currentSelectionsForMove = null; 1149 1150 if (selectedObject == null) return; 1151 1152 if ((selectedObject instanceof Group) && ((Group) selectedObject).isRoot()) { 1153 toolkit.beep(); 1154 JOptionPane.showMessageDialog(this, "Cannot rename the root.", "HDFView", JOptionPane.ERROR_MESSAGE); 1155 return; 1156 } 1157 1158 boolean isH4 = selectedObject.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF4)); 1159 1160 if (isH4) { 1161 toolkit.beep(); 1162 JOptionPane.showMessageDialog(this, "Cannot rename HDF4 object.", "HDFView", JOptionPane.ERROR_MESSAGE); 1163 return; 1164 } 1165 1166 String oldName = selectedObject.getName(); 1167 String newName = (String) JOptionPane.showInputDialog(this, "Rename \"" + oldName + "\" to:", "Rename...", 1168 JOptionPane.INFORMATION_MESSAGE, null, null, oldName); 1169 1170 if (newName == null) return; 1171 1172 newName = newName.trim(); 1173 if ((newName == null) || (newName.length() == 0) || newName.equals(oldName)) { 1174 return; 1175 } 1176 1177 try { 1178 selectedObject.setName(newName); 1179 } 1180 catch (Exception ex) { 1181 toolkit.beep(); 1182 JOptionPane.showMessageDialog(this, ex.getMessage(), "HDFView", JOptionPane.ERROR_MESSAGE); 1183 } 1184 } 1185 1186 private void removeSelectedObjects() { 1187 FileFormat theFile = getSelectedFile(); 1188 if (theFile.isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF4))) { 1189 toolkit.beep(); 1190 JOptionPane.showMessageDialog(this, "Unsupported operation: cannot delete HDF4 object.", "HDFView", 1191 JOptionPane.ERROR_MESSAGE); 1192 return; 1193 } 1194 log.trace("removeSelectedObjects: start"); 1195 1196 TreePath[] currentSelections = tree.getSelectionPaths(); 1197 1198 if (moveFlag == true) { 1199 currentSelections = currentSelectionsForMove; 1200 } 1201 if ((currentSelections == null) || (currentSelections.length <= 0)) { 1202 return; 1203 } 1204 if (moveFlag != true) { 1205 int op = JOptionPane.showConfirmDialog(this, "Do you want to remove all the selected object(s) ?", 1206 "Remove object", JOptionPane.YES_NO_OPTION); 1207 1208 if (op == JOptionPane.NO_OPTION) { 1209 return; 1210 } 1211 } 1212 HObject theObj = null; 1213 for (int i = 0; i < currentSelections.length; i++) { 1214 log.trace("removeSelectedObjects: loop[{}]",i); 1215 DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode) (currentSelections[i].getLastPathComponent()); 1216 theObj = (HObject) currentNode.getUserObject(); 1217 1218 // cannot delete root 1219 if (theObj instanceof Group) { 1220 Group g = (Group) theObj; 1221 if (g.isRoot()) { 1222 toolkit.beep(); 1223 JOptionPane.showMessageDialog(this, "Unsupported operation: cannot delete the file root.", 1224 "HDFView", JOptionPane.ERROR_MESSAGE); 1225 log.trace("removeSelectedObjects: cannot delete root"); 1226 return; 1227 } 1228 } 1229 1230 if (moveFlag != true) { 1231 if (isObjectOpen(theObj)) { 1232 toolkit.beep(); 1233 JOptionPane.showMessageDialog(this, "Cannot delete the selected object: " + theObj 1234 + "\nThe dataset or dataset in the group is in use." 1235 + "\n\nPlease close the dataset(s) and try again.\n", "HDFView", JOptionPane.ERROR_MESSAGE); 1236 log.trace("removeSelectedObjects: object in use"); 1237 continue; 1238 } 1239 } 1240 1241 try { 1242 theFile.delete(theObj); 1243 } 1244 catch (Exception ex) { 1245 toolkit.beep(); 1246 JOptionPane.showMessageDialog(this, ex, "HDFView", JOptionPane.ERROR_MESSAGE); 1247 continue; 1248 } 1249 1250 if (theObj.equals(selectedObject)) { 1251 selectedObject = null; 1252 } 1253 1254 removeNode(currentNode); 1255 } // for (int i=0; i< currentSelections.length; i++) { 1256 log.trace("removeSelectedObjects: finish"); 1257 } 1258 1259 private void removeNode(DefaultMutableTreeNode node) { 1260 if (node == null) { 1261 return; 1262 } 1263 log.trace("removeNode: start"); 1264 1265 DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) (node.getParent()); 1266 if (parentNode != null) { 1267 treeModel.removeNodeFromParent(node); 1268 1269 // add the two lines to fix bug in HDFView 1.2. Delete a subgroup and 1270 // then copy the group to another group, the deleted group still exists. 1271 Group pgroup = (Group) parentNode.getUserObject(); 1272 pgroup.removeFromMemberList((HObject) node.getUserObject()); 1273 1274 if (node.equals(selectedNode)) { 1275 selectedNode = null; 1276 selectedFile = null; 1277 } 1278 } // if (parentNode != null) { 1279 log.trace("removeNode: finish"); 1280 } 1281 1282 /** 1283 * Checks if a file is already open. 1284 * 1285 * @param filename the file to query 1286 * 1287 * @return true if the file is open 1288 */ 1289 private boolean isFileOpen(String filename) { 1290 boolean isOpen = false; 1291 1292 // Find the file by matching its file name from the list of open files 1293 FileFormat theFile = null; 1294 Iterator<FileFormat> iterator = fileList.iterator(); 1295 while (iterator.hasNext()) { 1296 theFile = iterator.next(); 1297 if (theFile.getFilePath().equals(filename)) { 1298 isOpen = true; 1299 break; 1300 } 1301 } 1302 1303 return isOpen; 1304 } 1305 1306 /** 1307 * Checks if an object is already open. 1308 */ 1309 private boolean isObjectOpen(HObject obj) { 1310 boolean isOpen = false; 1311 1312 if (obj instanceof Group) { 1313 Group g = (Group) obj; 1314 List<?> members = g.getMemberList(); 1315 if ((members == null) || (members.size() == 0)) { 1316 isOpen = false; 1317 } 1318 else { 1319 int n = members.size(); 1320 for (int i = 0; i < n; i++) { 1321 HObject theObj = (HObject) members.get(i); 1322 isOpen = (((HDFView) viewer).getDataView(theObj) != null); 1323 if (isOpen) { 1324 break; 1325 } 1326 } 1327 } 1328 } 1329 else { 1330 return !(((HDFView) viewer).getDataView(obj) == null); 1331 } 1332 1333 return isOpen; 1334 } 1335 1336 /** 1337 * Returns a list of all user objects that traverses the subtree rooted at 1338 * this item in breadth-first order.. 1339 * 1340 * @param item 1341 * the item to start with. 1342 * 1343 * @return list of TreeNodes 1344 */ 1345 private final List<Object> breadthFirstUserObjects(TreeNode item) { 1346 if (item == null) return null; 1347 1348 Vector<Object> list = new Vector<Object>(); 1349 DefaultMutableTreeNode theItem = null; 1350 Enumeration<?> local_enum = ((DefaultMutableTreeNode) item).breadthFirstEnumeration(); 1351 while (local_enum.hasMoreElements()) { 1352 theItem = (DefaultMutableTreeNode) local_enum.nextElement(); 1353 list.add(theItem.getUserObject()); 1354 } 1355 1356 return list; 1357 } 1358 1359 /** 1360 * Find first object that is matched by name under the specified 1361 * TreeNode. 1362 * 1363 * @param objName 1364 * -- the object name. 1365 * @return the object if found, otherwise, returns null. 1366 */ 1367 private final static HObject find(String objName, TreePath treePath, JTree tree) { 1368 if (objName == null || objName.length() <= 0 || treePath == null) return null; 1369 1370 HObject retObj = null; 1371 boolean isFound = false, isPrefix = false, isSuffix = false, isContain = false; 1372 1373 if (objName.equals("*")) return null; 1374 1375 if (objName.startsWith("*")) { 1376 isSuffix = true; 1377 objName = objName.substring(1, objName.length()); 1378 } 1379 1380 if (objName.endsWith("*")) { 1381 isPrefix = true; 1382 objName = objName.substring(0, objName.length() - 1); 1383 } 1384 1385 if (isPrefix && isSuffix) { 1386 isContain = true; 1387 isPrefix = isSuffix = false; 1388 } 1389 1390 if (objName == null || objName.length() <= 0) return null; 1391 1392 DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath.getLastPathComponent(); 1393 if (node == null) return null; 1394 1395 HObject obj = null; 1396 String theName = null; 1397 DefaultMutableTreeNode theItem = null; 1398 Enumeration<?> local_enum = node.breadthFirstEnumeration(); 1399 while (local_enum.hasMoreElements()) { 1400 theItem = (DefaultMutableTreeNode) local_enum.nextElement(); 1401 obj = (HObject) theItem.getUserObject(); 1402 if (obj != null && (theName = obj.getName()) != null) { 1403 if (isPrefix) 1404 isFound = theName.startsWith(objName); 1405 else if (isSuffix) 1406 isFound = theName.endsWith(objName); 1407 else if (isContain) 1408 isFound = theName.contains(objName); 1409 else 1410 isFound = theName.equals(objName); 1411 1412 if (isFound) { 1413 retObj = obj; 1414 break; 1415 } 1416 } 1417 } 1418 1419 if (retObj != null) { 1420 TreePath dstPath = getTreePath(treePath, theItem, 0); 1421 tree.setSelectionPath(dstPath); 1422 tree.scrollPathToVisible(dstPath); 1423 } 1424 1425 return retObj; 1426 } 1427 1428 /** 1429 * Get the TreePath from the parent to the target node. 1430 * 1431 * @param parent 1432 * -- the parent TreePath 1433 * @param node 1434 * -- the target node 1435 * @param depth 1436 * @return the tree path if target node found, otherwise; returns null; 1437 */ 1438 private static TreePath getTreePath(TreePath parent, TreeNode node, int depth) { 1439 if (node == null || parent == null || depth < 0) return null; 1440 1441 TreeNode theNode = (TreeNode) parent.getLastPathComponent(); 1442 if (node == theNode) return parent; 1443 1444 if (theNode.getChildCount() >= 0) { 1445 for (Enumeration<?> e = theNode.children(); e.hasMoreElements();) { 1446 TreeNode n = (TreeNode) e.nextElement(); 1447 TreePath path = parent.pathByAddingChild(n); 1448 TreePath result = getTreePath(path, node, depth + 1); 1449 1450 if (result != null) { 1451 return result; 1452 } 1453 } 1454 } 1455 1456 return null; 1457 } 1458 1459 /** 1460 * Save the current file into a new HDF4 file. Since HDF4 does not 1461 * support packing, the source file is copied into the new file with 1462 * the exact same content. 1463 */ 1464 private final void saveAsHDF4(FileFormat srcFile) { 1465 if (srcFile == null) { 1466 toolkit.beep(); 1467 JOptionPane.showMessageDialog(this, "Select a file to save.", "HDFView", JOptionPane.ERROR_MESSAGE); 1468 return; 1469 } 1470 1471 TreeNode root = srcFile.getRootNode(); 1472 if (root == null) { 1473 toolkit.beep(); 1474 JOptionPane.showMessageDialog(this, "The file is empty.", "HDFView", JOptionPane.ERROR_MESSAGE); 1475 return; 1476 } 1477 1478 JFrame owner = (viewer == null) ? new JFrame() : (JFrame) viewer; 1479 String currentDir = srcFile.getParent(); 1480 1481 if (currentDir != null) { 1482 currentDir += File.separator; 1483 } 1484 else { 1485 currentDir = ""; 1486 } 1487 1488 NewFileDialog dialog = new NewFileDialog(owner, currentDir, FileFormat.FILE_TYPE_HDF4, getCurrentFiles()); 1489 // dialog.show(); 1490 1491 if (!dialog.isFileCreated()) return; 1492 1493 String filename = dialog.getFile(); 1494 1495 if(filename == null) return; 1496 1497 // Since cannot pack hdf4, simply copy the whole physical file 1498 int length = 0; 1499 int bsize = 512; 1500 byte[] buffer; 1501 BufferedInputStream bi = null; 1502 BufferedOutputStream bo = null; 1503 1504 try { 1505 bi = new BufferedInputStream(new FileInputStream(srcFile.getFilePath())); 1506 } 1507 catch (Exception ex) { 1508 toolkit.beep(); 1509 JOptionPane.showMessageDialog(this, ex.getMessage() + "\n" + filename, "HDFView", JOptionPane.ERROR_MESSAGE); 1510 return; 1511 } 1512 1513 try { 1514 bo = new BufferedOutputStream(new FileOutputStream(filename)); 1515 } 1516 catch (Exception ex) { 1517 try { 1518 bi.close(); 1519 } 1520 catch (Exception ex2) { 1521 log.debug("Output file force input close:", ex2); 1522 } 1523 toolkit.beep(); 1524 JOptionPane.showMessageDialog(this, ex, "HDFView", JOptionPane.ERROR_MESSAGE); 1525 return; 1526 } 1527 1528 buffer = new byte[bsize]; 1529 try { 1530 length = bi.read(buffer, 0, bsize); 1531 } 1532 catch (Exception ex) { 1533 length = 0; 1534 } 1535 while (length > 0) { 1536 try { 1537 bo.write(buffer, 0, length); 1538 length = bi.read(buffer, 0, bsize); 1539 } 1540 catch (Exception ex) { 1541 length = 0; 1542 } 1543 } 1544 1545 try { 1546 bo.flush(); 1547 } 1548 catch (Exception ex) { 1549 log.debug("Output file:", ex); 1550 } 1551 try { 1552 bi.close(); 1553 } 1554 catch (Exception ex) { 1555 log.debug("Input file:", ex); 1556 } 1557 try { 1558 bo.close(); 1559 } 1560 catch (Exception ex) { 1561 log.debug("Output file:", ex); 1562 } 1563 1564 try { 1565 openFile(filename, FileFormat.WRITE); 1566 } 1567 catch (Exception ex) { 1568 toolkit.beep(); 1569 JOptionPane .showMessageDialog(this, ex.getMessage() + "\n" + filename, "HDFView", JOptionPane.ERROR_MESSAGE); 1570 } 1571 } 1572 1573 /** 1574 * Copy the current file into a new HDF5 file. The new file does not include the 1575 * inaccessible objects. Values of reference dataset are not updated in the 1576 * new file. 1577 */ 1578 private void saveAsHDF5(FileFormat srcFile) { 1579 if (srcFile == null) { 1580 toolkit.beep(); 1581 JOptionPane.showMessageDialog(this, "Select a file to save.", "HDFView", JOptionPane.ERROR_MESSAGE); 1582 return; 1583 } 1584 1585 TreeNode root = srcFile.getRootNode(); 1586 if (root == null) { 1587 toolkit.beep(); 1588 JOptionPane.showMessageDialog(this, "The file is empty.", "HDFView", JOptionPane.ERROR_MESSAGE); 1589 return; 1590 } 1591 1592 JFrame owner = (viewer == null) ? new JFrame() : (JFrame) viewer; 1593 NewFileDialog dialog = new NewFileDialog(owner, srcFile.getParent(), FileFormat.FILE_TYPE_HDF5, 1594 getCurrentFiles()); 1595 // dialog.show(); 1596 1597 if (!dialog.isFileCreated()) { 1598 return; 1599 } 1600 1601 String filename = dialog.getFile(); 1602 1603 if(filename == null) return; 1604 1605 int n = root.getChildCount(); 1606 Vector<Object> objList = new Vector<Object>(n); 1607 DefaultMutableTreeNode node = null; 1608 for (int i = 0; i < n; i++) { 1609 node = (DefaultMutableTreeNode) root.getChildAt(i); 1610 objList.add(node.getUserObject()); 1611 } 1612 1613 FileFormat newFile = null; 1614 try { 1615 newFile = openFile(filename, FileFormat.WRITE); 1616 } 1617 catch (Exception ex) { 1618 toolkit.beep(); 1619 JOptionPane .showMessageDialog(this, ex.getMessage() + "\n" + filename, "HDFView", JOptionPane.ERROR_MESSAGE); 1620 return; 1621 } 1622 1623 if (newFile == null) return; 1624 1625 TreeNode pnode = newFile.getRootNode(); 1626 1627 pasteObject(objList, pnode, newFile); 1628 objList.setSize(0); 1629 1630 Group srcGroup = (Group) ((DefaultMutableTreeNode) root).getUserObject(); 1631 Group dstGroup = (Group) ((DefaultMutableTreeNode) newFile.getRootNode()).getUserObject(); 1632 Object[] parameter = new Object[2]; 1633 Class<?> classHOjbect = null; 1634 Class<?>[] parameterClass = new Class[2]; 1635 Method method = null; 1636 1637 // Copy attributes of the root group 1638 try { 1639 parameter[0] = srcGroup; 1640 parameter[1] = dstGroup; 1641 classHOjbect = Class.forName("hdf.object.HObject"); 1642 parameterClass[0] = parameterClass[1] = classHOjbect; 1643 method = newFile.getClass().getMethod("copyAttributes", parameterClass); 1644 method.invoke(newFile, parameter); 1645 } 1646 catch (Exception ex) { 1647 toolkit.beep(); 1648 JOptionPane.showMessageDialog(this, ex, "HDFView", JOptionPane.ERROR_MESSAGE); 1649 } 1650 1651 // Update reference datasets 1652 parameter[0] = srcGroup.getFileFormat(); 1653 parameter[1] = newFile; 1654 parameterClass[0] = parameterClass[1] = parameter[0].getClass(); 1655 try { 1656 method = newFile.getClass().getMethod("updateReferenceDataset", parameterClass); 1657 method.invoke(newFile, parameter); 1658 } 1659 catch (Exception ex) { 1660 toolkit.beep(); 1661 JOptionPane.showMessageDialog(this, ex, "HDFView", JOptionPane.ERROR_MESSAGE); 1662 } 1663 } 1664 1665 /** Save data as file. 1666 * 1667 * @throws Exception if a failure occurred 1668 */ 1669 private void saveAsFile() throws Exception { 1670 if (!(selectedObject instanceof Dataset) || (selectedObject == null) || (selectedNode == null)) return; 1671 1672 File chosenFile = null; 1673 Dataset dataset = (Dataset) selectedObject; 1674 final JFileChooser fchooser = new JFileChooser(dataset.getFile()); 1675 fchooser.setFileFilter(DefaultFileFilter.getFileFilterText()); 1676 // fchooser.changeToParentDirectory(); 1677 1678 if(binaryOrder == 99) { 1679 fchooser.setDialogTitle("Save Dataset Data To Text File --- " + dataset.getName()); 1680 1681 chosenFile = new File(dataset.getName() + ".txt"); 1682 } 1683 else { 1684 fchooser.setDialogTitle("Save Current Data To Binary File --- " + dataset.getName()); 1685 1686 chosenFile = new File(dataset.getName() + ".bin"); 1687 } 1688 1689 fchooser.setSelectedFile(chosenFile); 1690 int returnVal = fchooser.showSaveDialog(this); 1691 1692 if (returnVal != JFileChooser.APPROVE_OPTION) { 1693 return; 1694 } 1695 1696 chosenFile = fchooser.getSelectedFile(); 1697 if (chosenFile == null) { 1698 return; 1699 } 1700 String filename = chosenFile.getAbsolutePath(); 1701 if(filename == null) return; 1702 1703 // Check if the file is in use 1704 List<?> fileList = viewer.getTreeView().getCurrentFiles(); 1705 if (fileList != null) { 1706 FileFormat theFile = null; 1707 Iterator<?> iterator = fileList.iterator(); 1708 while (iterator.hasNext()) { 1709 theFile = (FileFormat) iterator.next(); 1710 if (theFile.getFilePath().equals(filename)) { 1711 toolkit.beep(); 1712 JOptionPane.showMessageDialog(this, 1713 "Unable to save data to file \"" + filename + "\". \nThe file is being used.", 1714 "Export Dataset", JOptionPane.ERROR_MESSAGE); 1715 return; 1716 } 1717 } 1718 } 1719 1720 if (chosenFile.exists()) { 1721 int newFileFlag = JOptionPane.showConfirmDialog(this, 1722 "File exists. Do you want to replace it ?", 1723 "Export Dataset", JOptionPane.YES_NO_OPTION); 1724 if (newFileFlag == JOptionPane.NO_OPTION) { 1725 return; 1726 } 1727 } 1728 1729 boolean isH4 = selectedObject.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF4)); 1730 1731 if (isH4) { 1732 toolkit.beep(); 1733 JOptionPane.showMessageDialog(this, "Cannot export HDF4 object.", "HDFView", JOptionPane.ERROR_MESSAGE); 1734 return; 1735 } 1736 1737 try { 1738 selectedObject.getFileFormat().exportDataset(filename, dataset.getFile(), dataset.getFullName(), binaryOrder); 1739 } 1740 catch (Exception ex) { 1741 toolkit.beep(); 1742 JOptionPane.showMessageDialog(this, ex.getMessage(), "HDFView", JOptionPane.ERROR_MESSAGE); 1743 } 1744 1745 viewer.showStatus("Data saved to: " + filename); 1746 } 1747 1748 /** disable/enable GUI components */ 1749 private static void setEnabled(List<JMenuItem> list, boolean b) { 1750 Component item = null; 1751 Iterator<JMenuItem> it = list.iterator(); 1752 while (it.hasNext()) { 1753 item = it.next(); 1754 item.setEnabled(b); 1755 } 1756 } 1757 1758 /** 1759 * Opens a file and retrieves the file structure of the file. It also can be 1760 * used to create a new file by setting the accessID to FileFormat.CREATE. 1761 * 1762 * <p> 1763 * Subclasses must implement this function to take appropriate steps to open 1764 * a file. 1765 * </p> 1766 * 1767 * @param filename 1768 * the name of the file to open. 1769 * @param accessID 1770 * identifier for the file access. Valid value of accessID is: 1771 * <ul> 1772 * <li>FileFormat.READ --- allow read-only access to file.</li> 1773 * <li>FileFormat.WRITE --- allow read and write access to file.</li> 1774 * <li>FileFormat.CREATE --- create a new file.</li> 1775 * </ul> 1776 * 1777 * @return the FileFormat of this file if successful; otherwise returns 1778 * null. 1779 * 1780 * @throws Exception if a failure occurred 1781 */ 1782 public FileFormat openFile(String filename, int accessID) throws Exception { 1783 log.trace("openFile: {},{}", filename, accessID); 1784 FileFormat fileFormat = null; 1785 MutableTreeNode fileRoot = null; 1786 boolean isNewFile = (FileFormat.OPEN_NEW == (accessID & FileFormat.OPEN_NEW)); 1787 if (isNewFile) accessID = accessID - FileFormat.OPEN_NEW; 1788 1789 if (isFileOpen(filename)) { 1790 ((HDFView) viewer).showStatus("File is in use."); 1791 return null; 1792 } 1793 1794 File tmpFile = new File(filename); 1795 if (!tmpFile.exists()) { 1796 throw new FileNotFoundException("File does not exist."); 1797 } 1798 1799 if (!tmpFile.canWrite()) { 1800 accessID = FileFormat.READ; 1801 } 1802 1803 Enumeration<?> keys = FileFormat.getFileFormatKeys(); 1804 1805 String theKey = null; 1806 while (keys.hasMoreElements()) { 1807 theKey = (String) keys.nextElement(); 1808 if (theKey.equals(FileFormat.FILE_TYPE_HDF4)) { 1809 log.trace("openFile: {} FILE_TYPE_HDF4", filename); 1810 try { 1811 FileFormat h4format = FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF4); 1812 if ((h4format != null) && h4format.isThisType(filename)) { 1813 fileFormat = h4format.createInstance(filename, accessID); 1814 break; 1815 } 1816 } 1817 catch (Throwable err) { 1818 log.debug("openFile: Error retrieving the file structure of {}: {}", filename, err); 1819 } 1820 continue; 1821 } 1822 else if (theKey.equals(FileFormat.FILE_TYPE_HDF5)) { 1823 log.trace("openFile: {} FILE_TYPE_HDF5", filename); 1824 try { 1825 FileFormat h5format = FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5); 1826 if ((h5format != null) && h5format.isThisType(filename)) { 1827 fileFormat = h5format.createInstance(filename, accessID); 1828 break; 1829 } 1830 } 1831 catch (Throwable err) { 1832 log.debug("openFile: Error retrieving the file structure of {}: {}", filename, err); 1833 } 1834 continue; 1835 } 1836 else { 1837 log.trace("openFile: {} Other", filename); 1838 try { 1839 1840 FileFormat theformat = FileFormat.getFileFormat(theKey); 1841 if (theformat.isThisType(filename)) { 1842 fileFormat = theformat.createInstance(filename, accessID); 1843 break; 1844 } 1845 } 1846 catch (Throwable err) { 1847 log.debug("openFile: Error retrieving the file structure of {}: {}", filename, err); 1848 } 1849 } 1850 } 1851 1852 if (fileFormat == null) throw new java.io.IOException("Unsupported fileformat - " + filename); 1853 1854 ((JFrame) viewer).setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 1855 try { 1856 fileFormat.setMaxMembers(ViewProperties.getMaxMembers()); 1857 fileFormat.setStartMembers(ViewProperties.getStartMembers()); 1858 if (fileFormat.isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5))) { 1859 if(isNewFile) { 1860 currentIndexType = fileFormat.getIndexType(ViewProperties.getIndexType()); 1861 currentIndexOrder = fileFormat.getIndexOrder(ViewProperties.getIndexOrder()); 1862 } 1863 fileFormat.setIndexType(currentIndexType); 1864 fileFormat.setIndexOrder(currentIndexOrder); 1865 } 1866 1867 fileFormat.open(); 1868 } 1869 catch (Exception ex) { 1870 log.debug("openFile: FileFormat init and open: {}", ex); 1871 fileFormat = null; 1872 } 1873 finally { 1874 ((JFrame) viewer).setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 1875 } 1876 1877 if (fileFormat == null) { 1878 throw new java.io.IOException("openFile: Failed to open file - " + filename); 1879 } 1880 else { 1881 fileRoot = (MutableTreeNode) fileFormat.getRootNode(); 1882 1883 if (fileRoot != null) { 1884 insertNode(fileRoot, root); 1885 /* Expand top level items of root object */ 1886 int currentRowCount = tree.getRowCount(); 1887 if (currentRowCount > 0) { 1888 tree.expandRow(tree.getRowCount() - 1); 1889 } 1890 1891 fileList.add(fileFormat); 1892 } 1893 } 1894 1895 return fileFormat; 1896 } 1897 1898 public FileFormat reopenFile(FileFormat fileFormat) throws Exception { 1899 if (fileFormat.isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5))) { 1900 this.currentIndexType = fileFormat.getIndexType(null); 1901 this.currentIndexOrder = fileFormat.getIndexOrder(null); 1902 } 1903 if (fileFormat.isReadOnly()) 1904 return openFile(fileFormat.getAbsolutePath(), FileFormat.READ); 1905 else 1906 return openFile(fileFormat.getAbsolutePath(), FileFormat.WRITE); 1907 } 1908 1909 /** 1910 * Close a file 1911 * 1912 * @param file 1913 * the file to close 1914 * 1915 * @throws Exception if a failure occurred 1916 */ 1917 @Override 1918 public void closeFile(FileFormat file) throws Exception { 1919 if (file == null) return; 1920 1921 log.trace("DefaultTreeView:closeFile start"); 1922 // Find the file item in the tree and remove it 1923 FileFormat theFile = null; 1924 DefaultMutableTreeNode theNode = null; 1925 Enumeration<?> enumeration = root.children(); 1926 while (enumeration.hasMoreElements()) { 1927 theNode = (DefaultMutableTreeNode) enumeration.nextElement(); 1928 Group g = (Group) theNode.getUserObject(); 1929 theFile = g.getFileFormat(); 1930 1931 if (theFile.equals(file)) { 1932 treeModel.removeNodeFromParent(theNode); 1933 try { 1934 theFile.close(); 1935 } 1936 catch (Exception ex) { 1937 log.debug("DefaultTreeView: closeFile({}): {}:", theFile.getFilePath(), ex); 1938 } 1939 fileList.remove(theFile); 1940 if (theFile.equals(selectedFile)) { 1941 selectedFile = null; 1942 selectedNode = null; 1943 } 1944 break; 1945 } 1946 } // while(enumeration.hasMoreElements()) 1947 log.trace("DefaultTreeView:closeFile finish"); 1948 } 1949 1950 /** 1951 * Save a file 1952 * 1953 * @param file 1954 * the file to save 1955 * 1956 * @throws Exception if a failure occurred 1957 */ 1958 @Override 1959 public void saveFile(FileFormat file) throws Exception { 1960 if (file == null) { 1961 toolkit.beep(); 1962 JOptionPane.showMessageDialog(this, "Select a file to save.", "HDFView", JOptionPane.ERROR_MESSAGE); 1963 return; 1964 } 1965 1966 boolean isH4 = file.isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF4)); 1967 boolean isH5 = file.isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5)); 1968 1969 if (!(isH4 || isH5)) { 1970 toolkit.beep(); 1971 JOptionPane.showMessageDialog(this, "Saving file is not supported for this file type", "HDFView", 1972 JOptionPane.ERROR_MESSAGE); 1973 return; 1974 } 1975 1976 // Write the change of the data into the file before saving the file 1977 List<?> views = ((HDFView) viewer).getDataViews(); 1978 Object theView = null; 1979 TableView tableView = null; 1980 TextView textView = null; 1981 FileFormat theFile = null; 1982 if (views != null) { 1983 int n = views.size(); 1984 for (int i = 0; i < n; i++) { 1985 theView = views.get(i); 1986 if (theView instanceof TableView) { 1987 tableView = (TableView) theView; 1988 theFile = tableView.getDataObject().getFileFormat(); 1989 if (file.equals(theFile)) { 1990 tableView.updateValueInFile(); 1991 } 1992 } 1993 else if (theView instanceof TextView) { 1994 textView = (TextView) theView; 1995 theFile = textView.getDataObject().getFileFormat(); 1996 if (file.equals(theFile)) { 1997 textView.updateValueInFile(); 1998 } 1999 } 2000 } 2001 } 2002 2003 if (isH5) { 2004 saveAsHDF5(file); 2005 } 2006 else if (isH4) { 2007 saveAsHDF4(file); 2008 } 2009 } 2010 2011 /** 2012 * Returns the tree node that contains the given data object. 2013 */ 2014 @Override 2015 public TreeNode findTreeNode(HObject obj) { 2016 if (obj == null) return null; 2017 2018 TreeNode theFileRoot = obj.getFileFormat().getRootNode(); 2019 if (theFileRoot == null) return null; 2020 2021 DefaultMutableTreeNode theNode = null; 2022 HObject theObj = null; 2023 Enumeration<?> local_enum = ((DefaultMutableTreeNode) theFileRoot).breadthFirstEnumeration(); 2024 while(local_enum.hasMoreElements()) { 2025 theNode = (DefaultMutableTreeNode) local_enum.nextElement(); 2026 theObj = (HObject) theNode.getUserObject(); 2027 if (theObj == null) { 2028 continue; 2029 } 2030 2031 if(theObj.equals(obj)) { 2032 return theNode; 2033 } 2034 } 2035 2036 return null; 2037 } 2038 2039 /** 2040 * Gets the selected file. When multiple files are open, we need to know 2041 * which file is currently selected. 2042 * 2043 * @return the FileFormat of the currently selected file. 2044 */ 2045 @Override 2046 public FileFormat getSelectedFile() { 2047 return selectedFile; 2048 } 2049 2050 /** 2051 * Gets a list of selected object in the tree. Obtaining a list of current 2052 * selected objects is necessary for copy/paste/delete objects. 2053 * 2054 * @return a list of selected object in the tree. 2055 */ 2056 public List<Object> getSelectedObjects() { 2057 TreePath[] paths = tree.getSelectionPaths(); 2058 if ((paths == null) || (paths.length <= 0)) { 2059 return null; 2060 } 2061 log.trace("getSelectedObjects: start"); 2062 2063 List<Object> objs = new Vector<Object>(paths.length); 2064 HObject theObject = null, parentObject; 2065 DefaultMutableTreeNode currentNode = null, parentNode = null; 2066 for (int i = 0; i < paths.length; i++) { 2067 currentNode = (DefaultMutableTreeNode) (paths[i].getLastPathComponent()); 2068 theObject = (HObject) currentNode.getUserObject(); 2069 2070 if (theObject != null) { 2071 log.trace("getSelectedObjects: theObject={}",theObject); 2072 objs.add(theObject); 2073 // removed the group from the selected list if some of its 2074 // members are selected 2075 // to avoid duplicated copy/paste when a group is pasted. 2076 parentNode = (DefaultMutableTreeNode) currentNode.getParent(); 2077 parentObject = (HObject) parentNode.getUserObject(); 2078 log.trace("getSelectedObjects: parentObject={}",parentObject); 2079 objs.remove(parentObject); 2080 } 2081 } 2082 2083 log.trace("getSelectedObjects: finish"); 2084 return objs; 2085 } 2086 2087 /** 2088 * @return the currently selected object in the tree. 2089 */ 2090 @Override 2091 public HObject getCurrentObject() { 2092 return selectedObject; 2093 } 2094 2095 /** 2096 * @return the JTree which holds the file structure. 2097 */ 2098 @Override 2099 public JTree getTree() { 2100 return tree; 2101 } 2102 2103 /** 2104 * @return the list of currently open files. 2105 */ 2106 @Override 2107 public List<FileFormat> getCurrentFiles() { 2108 return fileList; 2109 } 2110 2111 /** 2112 * Display the content of a data object. 2113 * 2114 * @param dataObject 2115 * the data object 2116 * 2117 * @return the DataView that displays the data content 2118 * 2119 * @throws Exception if a failure occurred 2120 */ 2121 @Override 2122 public DataView showDataContent(HObject dataObject) throws Exception { 2123 log.trace("showDataContent({}): start", dataObject.getName()); 2124 2125 if ((dataObject == null) || !(dataObject instanceof Dataset)) { 2126 return null; // can only display dataset 2127 } 2128 2129 Dataset d = (Dataset) dataObject; 2130 2131 if (d.getRank() <= 0) d.init(); 2132 2133 boolean isText = ((d instanceof ScalarDS) && ((ScalarDS) d).isText()); 2134 boolean isImage = ((d instanceof ScalarDS) && ((ScalarDS) d).isImage()); 2135 boolean isDisplayTypeChar = false; 2136 boolean isTransposed = false; 2137 boolean isIndexBase1 = ViewProperties.isIndexBase1(); 2138 BitSet bitmask = null; 2139 String dataViewName = null; 2140 log.trace("showDataContent: inited"); 2141 2142 JInternalFrame theFrame = (JInternalFrame) viewer.getDataView(d); 2143 2144 if (isDefaultDisplay) { 2145 2146 if (theFrame != null) { 2147 theFrame.toFront(); 2148 return null; 2149 } 2150 2151 if (isText) { 2152 dataViewName = (String) HDFView.getListOfTextView().get(0); 2153 } 2154 else if (isImage) { 2155 dataViewName = (String) HDFView.getListOfImageView().get(0); 2156 } 2157 else { 2158 dataViewName = (String) HDFView.getListOfTableView().get(0); 2159 } 2160 } 2161 else { 2162 DataOptionDialog dialog = new DataOptionDialog(viewer, d); 2163 2164 dialog.setVisible(true); 2165 if (dialog.isCancelled()) { 2166 return null; 2167 } 2168 2169 isImage = dialog.isImageDisplay(); 2170 isDisplayTypeChar = dialog.isDisplayTypeChar(); 2171 dataViewName = dialog.getDataViewName(); 2172 isTransposed = dialog.isTransposed(); 2173 bitmask = dialog.getBitmask(); 2174 isIndexBase1 = dialog.isIndexBase1(); 2175 isApplyBitmaskOnly = dialog.isApplyBitmaskOnly(); 2176 } 2177 log.trace("showDataContent: {}", dataViewName); 2178 2179 // Enables use of JHDF5 in JNLP (Web Start) applications, the system 2180 // class loader with reflection first. 2181 Class<?> theClass = null; 2182 try { 2183 theClass = Class.forName(dataViewName); 2184 } 2185 catch (Exception ex) { 2186 try { 2187 theClass = ViewProperties.loadExtClass().loadClass(dataViewName); 2188 } 2189 catch (Exception ex2) { 2190 theClass = null; 2191 } 2192 } 2193 2194 // Use default dataview 2195 if (theClass == null) { 2196 log.trace("showDataContent: Using default dataview"); 2197 if (isText) 2198 dataViewName = "hdf.view.DefaultTextView"; 2199 else if (isImage) 2200 dataViewName = "hdf.view.DefaultImageView"; 2201 else 2202 dataViewName = "hdf.view.DefaultTableView"; 2203 try { 2204 theClass = Class.forName(dataViewName); 2205 } 2206 catch (Exception ex) { 2207 log.debug("Class.forName {} failure: ", dataViewName, ex); 2208 } 2209 } 2210 Object theView = null; 2211 Object[] initargs = { viewer }; 2212 HashMap<DATA_VIEW_KEY, Serializable> map = new HashMap<DATA_VIEW_KEY, Serializable>(8); 2213 map.put(ViewProperties.DATA_VIEW_KEY.INDEXBASE1, new Boolean(isIndexBase1)); 2214 if (bitmask != null) { 2215 map.put(ViewProperties.DATA_VIEW_KEY.BITMASK, bitmask); 2216 if (isApplyBitmaskOnly) map.put(ViewProperties.DATA_VIEW_KEY.BITMASKOP, ViewProperties.BITMASK_OP.AND); 2217 2218 // Create a copy of the dataset 2219 ScalarDS d_copy = null; 2220 Constructor<? extends Dataset> constructor = null; 2221 Object[] paramObj = null; 2222 try { 2223 Class<?>[] paramClass = { FileFormat.class, String.class, String.class, long[].class }; 2224 constructor = d.getClass().getConstructor(paramClass); 2225 2226 paramObj = new Object[] { d.getFileFormat(), d.getName(), d.getPath(), d.getOID() }; 2227 } 2228 catch (Exception ex) { 2229 constructor = null; 2230 } 2231 2232 try { 2233 d_copy = (ScalarDS) constructor.newInstance(paramObj); 2234 } 2235 catch (Exception ex) { 2236 d_copy = null; 2237 } 2238 if (d_copy != null) { 2239 try { 2240 d_copy.init(); 2241 log.trace("showDataContent: d_copy inited"); 2242 int rank = d.getRank(); 2243 System.arraycopy(d.getDims(), 0, d_copy.getDims(), 0, rank); 2244 System.arraycopy(d.getStartDims(), 0, d_copy.getStartDims(), 0, rank); 2245 System.arraycopy(d.getSelectedDims(), 0, d_copy.getSelectedDims(), 0, rank); 2246 System.arraycopy(d.getStride(), 0, d_copy.getStride(), 0, rank); 2247 System.arraycopy(d.getSelectedIndex(), 0, d_copy.getSelectedIndex(), 0, 3); 2248 } 2249 catch (Throwable ex) { 2250 ex.printStackTrace(); 2251 } 2252 2253 map.put(ViewProperties.DATA_VIEW_KEY.OBJECT, d_copy); 2254 } 2255 } 2256 if (dataViewName.startsWith("hdf.view.DefaultTableView")) { 2257 map.put(ViewProperties.DATA_VIEW_KEY.CHAR, new Boolean(isDisplayTypeChar)); 2258 map.put(ViewProperties.DATA_VIEW_KEY.TRANSPOSED, new Boolean(isTransposed)); 2259 Object[] tmpargs = { viewer, map }; 2260 initargs = tmpargs; 2261 } 2262 else if (dataViewName.startsWith("hdf.view.DefaultImageView")) { 2263 map.put(ViewProperties.DATA_VIEW_KEY.CONVERTBYTE, new Boolean((bitmask != null))); 2264 Object[] tmpargs = { viewer, map }; 2265 initargs = tmpargs; 2266 } 2267 2268 try { 2269 ((JFrame) viewer).setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 2270 2271 theView = Tools.newInstance(theClass, initargs); 2272 log.trace("showDataContent: Tools.newInstance"); 2273 2274 viewer.addDataView((DataView) theView); 2275 } 2276 catch (Exception ex) { 2277 log.trace("showDataContent: Error instantiating class {}", theClass); 2278 } 2279 finally { 2280 ((JFrame) viewer).setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 2281 } 2282 2283 log.trace("showDataContent({}): finish", dataObject.getName()); 2284 return (DataView) theView; 2285 } 2286 2287 /** 2288 * Displays the meta data of a data object. 2289 * 2290 * @param dataObject 2291 * the data object 2292 * 2293 * @return the MetaDataView that displays the MetaData of the data object 2294 * 2295 * @throws Exception if a failure occurred 2296 */ 2297 @Override 2298 public MetaDataView showMetaData(HObject dataObject) throws Exception { 2299 if (dataObject == null) { 2300 return null; 2301 } 2302 2303 List<?> metaDataViewList = HDFView.getListOfMetaDataView(); 2304 if ((metaDataViewList == null) || (metaDataViewList.size() <= 0)) { 2305 return null; 2306 } 2307 2308 int n = metaDataViewList.size(); 2309 String className = (String) metaDataViewList.get(0); 2310 2311 if (!isDefaultDisplay && (n > 1)) { 2312 className = (String) JOptionPane.showInputDialog(this, "Select MetaDataView", "HDFView", 2313 JOptionPane.INFORMATION_MESSAGE, null, metaDataViewList.toArray(), className); 2314 } 2315 2316 // Enables use of JHDF5 in JNLP (Web Start) applications, the system 2317 // class loader with reflection first. 2318 Class<?> theClass = null; 2319 try { 2320 theClass = Class.forName(className); 2321 } 2322 catch (Exception ex) { 2323 theClass = ViewProperties.loadExtClass().loadClass(className); 2324 } 2325 2326 Object[] initargs = { viewer }; 2327 MetaDataView dataView = (MetaDataView) Tools.newInstance(theClass, initargs); 2328 2329 return dataView; 2330 } 2331 2332 /** 2333 * This class is used to change the default icons for tree nodes. 2334 * 2335 * @see javax.swing.tree.DefaultTreeCellRenderer 2336 */ 2337 private class HTreeCellRenderer extends DefaultTreeCellRenderer { 2338 private static final long serialVersionUID = -9030708781106435297L; 2339 private Icon h4Icon, h4IconR, h5Icon, h5IconR, datasetIcon, imageIcon, tableIcon, textIcon, openFolder, closeFolder, 2340 datasetIconA, imageIconA, tableIconA, textIconA, openFolderA, closeFolderA, datatypeIcon, 2341 datatypeIconA, questionIcon; 2342 2343 private HTreeCellRenderer() { 2344 super(); 2345 2346 openFolder = ViewProperties.getFolderopenIcon(); 2347 closeFolder = ViewProperties.getFoldercloseIcon(); 2348 datasetIcon = ViewProperties.getDatasetIcon(); 2349 imageIcon = ViewProperties.getImageIcon(); 2350 h4Icon = ViewProperties.getH4Icon(); 2351 h4IconR = ViewProperties.getH4IconR(); 2352 h5Icon = ViewProperties.getH5Icon(); 2353 h5IconR = ViewProperties.getH5IconR(); 2354 tableIcon = ViewProperties.getTableIcon(); 2355 textIcon = ViewProperties.getTextIcon(); 2356 2357 openFolderA = ViewProperties.getFolderopenIconA(); 2358 closeFolderA = ViewProperties.getFoldercloseIconA(); 2359 datasetIconA = ViewProperties.getDatasetIconA(); 2360 imageIconA = ViewProperties.getImageIconA(); 2361 tableIconA = ViewProperties.getTableIconA(); 2362 textIconA = ViewProperties.getTextIconA(); 2363 datatypeIcon = ViewProperties.getDatatypeIcon(); 2364 datatypeIconA = ViewProperties.getDatatypeIconA(); 2365 2366 questionIcon = ViewProperties.getQuestionIcon(); 2367 2368 if (openFolder != null) { 2369 openIcon = openFolder; 2370 } 2371 else { 2372 openFolder = this.openIcon; 2373 } 2374 2375 if (closeFolder != null) { 2376 closedIcon = closeFolder; 2377 } 2378 else { 2379 closeFolder = closedIcon; 2380 } 2381 2382 if (datasetIcon == null) { 2383 datasetIcon = leafIcon; 2384 } 2385 if (imageIcon == null) { 2386 imageIcon = leafIcon; 2387 } 2388 if (tableIcon == null) { 2389 tableIcon = leafIcon; 2390 } 2391 if (textIcon == null) { 2392 textIcon = leafIcon; 2393 } 2394 if (h4Icon == null) { 2395 h4Icon = leafIcon; 2396 } 2397 if (h4IconR == null) { 2398 h4IconR = leafIcon; 2399 } 2400 if (h5Icon == null) { 2401 h5Icon = leafIcon; 2402 } 2403 if (h5IconR == null) { 2404 h5IconR = leafIcon; 2405 } 2406 if (datatypeIcon == null) { 2407 datatypeIcon = leafIcon; 2408 } 2409 2410 if (questionIcon == null) { 2411 questionIcon = leafIcon; 2412 } 2413 2414 if (openFolderA == null) { 2415 openFolderA = openFolder; 2416 } 2417 if (closeFolderA == null) { 2418 closeFolderA = closeFolder; 2419 } 2420 if (datasetIconA == null) { 2421 datasetIconA = datasetIcon; 2422 } 2423 if (imageIconA == null) { 2424 imageIconA = imageIcon; 2425 } 2426 if (tableIconA == null) { 2427 tableIconA = tableIcon; 2428 } 2429 if (textIconA == null) { 2430 textIconA = textIcon; 2431 } 2432 if (datatypeIconA == null) { 2433 datatypeIconA = datatypeIcon; 2434 } 2435 } 2436 2437 public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, 2438 boolean leaf, int row, boolean hasFocus) { 2439 HObject theObject = (HObject) ((DefaultMutableTreeNode) value).getUserObject(); 2440 2441 if (theObject == null) 2442 return super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); 2443 2444 boolean hasAttribute = theObject.hasAttribute(); 2445 2446 if (theObject instanceof Dataset) { 2447 if (theObject instanceof ScalarDS) { 2448 ScalarDS sd = (ScalarDS) theObject; 2449 if (sd.isImage()) { 2450 if (hasAttribute) { 2451 leafIcon = imageIconA; 2452 } 2453 else { 2454 leafIcon = imageIcon; 2455 } 2456 } 2457 else if (sd.isText()) { 2458 if (hasAttribute) { 2459 leafIcon = textIconA; 2460 } 2461 else { 2462 leafIcon = textIcon; 2463 } 2464 } 2465 else { 2466 if (hasAttribute) { 2467 leafIcon = datasetIconA; 2468 } 2469 else { 2470 leafIcon = datasetIcon; 2471 } 2472 2473 } 2474 } 2475 else if (theObject instanceof CompoundDS) { 2476 if (hasAttribute) { 2477 leafIcon = tableIconA; 2478 } 2479 else { 2480 leafIcon = tableIcon; 2481 } 2482 } 2483 } 2484 else if (theObject instanceof Group) { 2485 Group g = (Group) theObject; 2486 2487 if (hasAttribute) { 2488 openIcon = openFolderA; 2489 closedIcon = closeFolderA; 2490 } 2491 else { 2492 openIcon = openFolder; 2493 closedIcon = closeFolder; 2494 } 2495 2496 if (g.isRoot()) { 2497 if (g.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5))) { 2498 if(g.getFileFormat().isReadOnly()) 2499 openIcon = closedIcon = h5IconR; 2500 else 2501 openIcon = closedIcon = h5Icon; 2502 } 2503 else if (g.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF4))) { 2504 if(g.getFileFormat().isReadOnly()) 2505 openIcon = closedIcon = h4IconR; 2506 else 2507 openIcon = closedIcon = h4Icon; 2508 } 2509 } 2510 } 2511 else if (theObject instanceof Datatype) { 2512 Datatype t = (Datatype) theObject; 2513 2514 if (hasAttribute) { 2515 leafIcon = datatypeIconA; 2516 } 2517 else { 2518 leafIcon = datatypeIcon; 2519 } 2520 } 2521 2522 else { 2523 leafIcon = questionIcon; 2524 } 2525 2526 return super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); 2527 } 2528 } // private class HTreeCellRenderer 2529 2530 /** 2531 * Handle mouse clicks on data object in the tree view. A right mouse-click 2532 * to show the popup menu for user choice. A double left-mouse-click to 2533 * display the data content. A single left-mouse-click to select the current 2534 * data object. 2535 */ 2536 private class HTreeMouseAdapter extends MouseAdapter { 2537 // public void mousePressed(MouseEvent e) 2538 public void mouseReleased(MouseEvent e) { 2539 TreePath selPath = tree.getPathForLocation(e.getX(), e.getY()); 2540 if (selPath == null) { 2541 return; 2542 } 2543 2544 DefaultMutableTreeNode theNode = (DefaultMutableTreeNode) selPath.getLastPathComponent(); 2545 if (!theNode.equals(selectedNode)) { 2546 selectedTreePath = selPath; 2547 selectedNode = theNode; 2548 selectedObject = ((HObject) (selectedNode.getUserObject())); 2549 FileFormat theFile = selectedObject.getFileFormat(); 2550 if ((theFile != null) && !theFile.equals(selectedFile)) { 2551 // a different file is selected, handle only one file a time 2552 selectedFile = theFile; 2553 tree.clearSelection(); 2554 tree.setSelectionPath(selPath); 2555 } 2556 2557 viewer.mouseEventFired(e); 2558 } 2559 2560 // *************************************************************** 2561 // Different platforms have different ways to show popups 2562 // if (e.getModifiers() == MouseEvent.BUTTON3_MASK) works for all 2563 // but mac 2564 // mouseReleased() and e.isPopupTrigger() work on windows and mac 2565 // but not unix, 2566 // mouseClicked() and e.isPopupTrigger() work on unix and mac but 2567 // not windows, 2568 // to solve the problem, we use both. 2569 // 7/25/06 bug 517. e.isPopupTrigger does not work on one mouse Mac. 2570 // add (MouseEvent.BUTTON1_MASK|MouseEvent.CTRL_MASK) for MAC 2571 int eMod = e.getModifiers(); 2572 if (e.isPopupTrigger() 2573 || (eMod == MouseEvent.BUTTON3_MASK) 2574 || (System.getProperty("os.name").startsWith("Mac") && (eMod == (MouseEvent.BUTTON1_MASK | Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())))) { 2575 int selRow = tree.getRowForLocation(e.getX(), e.getY()); 2576 2577 if (!tree.isRowSelected(selRow)) { 2578 // reselect the node 2579 tree.clearSelection(); 2580 tree.setSelectionRow(selRow); 2581 } 2582 showPopupMenu(e); 2583 } 2584 // double click to open data content 2585 else if (e.getClickCount() == 2) { 2586 isDefaultDisplay = true; 2587 try { 2588 showDataContent(selectedObject); 2589 } 2590 catch (Exception ex) { 2591 } 2592 } 2593 } // public void mousePressed(MouseEvent e) 2594 } // private class HTreeMouseAdapter extends MouseAdapter 2595 2596 /** 2597 * Handle key pressed event. 2598 */ 2599 private class HTreeKeyAdapter extends KeyAdapter { 2600 2601 @Override 2602 public void keyTyped(KeyEvent e) { 2603 } 2604 2605 @Override 2606 public void keyPressed(KeyEvent e) { 2607 } 2608 2609 @Override 2610 public void keyReleased(KeyEvent e) { 2611 int key = e.getKeyCode(); 2612 if (key == KeyEvent.VK_KP_LEFT || key == KeyEvent.VK_KP_RIGHT || key == KeyEvent.VK_KP_UP 2613 || key == KeyEvent.VK_KP_DOWN || key == KeyEvent.VK_LEFT || key == KeyEvent.VK_RIGHT 2614 || key == KeyEvent.VK_UP || key == KeyEvent.VK_DOWN) { 2615 2616 TreePath selPath = ((JTree) e.getComponent()).getSelectionPath(); 2617 if (selPath == null) { 2618 return; 2619 } 2620 2621 DefaultMutableTreeNode theNode = (DefaultMutableTreeNode) selPath.getLastPathComponent(); 2622 2623 if (!theNode.equals(selectedNode)) { 2624 selectedTreePath = selPath; 2625 selectedNode = theNode; 2626 selectedObject = ((HObject) (selectedNode.getUserObject())); 2627 FileFormat theFile = selectedObject.getFileFormat(); 2628 if ((theFile != null) && !theFile.equals(selectedFile)) { 2629 // a different file is selected, handle only one file a 2630 // time 2631 selectedFile = theFile; 2632 tree.clearSelection(); 2633 tree.setSelectionPath(selPath); 2634 } 2635 2636 ((HDFView) viewer).showMetaData(selectedObject); 2637 } 2638 } 2639 } 2640 } 2641 2642 /** 2643 * ChangeIndexingDialog displays file index options. 2644 */ 2645 private class ChangeIndexingDialog extends JDialog implements ActionListener { 2646 private static final long serialVersionUID = 1048114401768228742L; 2647 2648 private JRadioButton checkIndexType; 2649 private JRadioButton checkIndexOrder; 2650 private JRadioButton checkIndexNative; 2651 2652 private boolean reloadFile; 2653 2654 private FileFormat selectedFile; 2655 private int indexType; 2656 private int indexOrder; 2657 2658 /** 2659 * constructs an UserOptionsDialog. 2660 * 2661 * @param view 2662 * The HDFView. 2663 */ 2664 private ChangeIndexingDialog(JFrame view, FileFormat viewSelectedFile) { 2665 super(view, "Index Options", true); 2666 2667 selectedFile = viewSelectedFile; 2668 indexType = selectedFile.getIndexType(null); 2669 indexOrder = selectedFile.getIndexOrder(null); 2670 reloadFile = false; 2671 2672 JPanel contentPane = (JPanel) getContentPane(); 2673 contentPane.setLayout(new BorderLayout(8, 8)); 2674 contentPane.setBorder(BorderFactory.createEmptyBorder(15, 5, 5, 5)); 2675 2676 JPanel indexP = new JPanel(); 2677 TitledBorder tborder = new TitledBorder("Index Options"); 2678 tborder.setTitleColor(Color.darkGray); 2679 indexP.setBorder(tborder); 2680 indexP.setLayout(new GridLayout(2, 1, 10, 10)); 2681 indexP.setBorder(new SoftBevelBorder(BevelBorder.LOWERED)); 2682 contentPane.add(indexP); 2683 2684 JPanel pType = new JPanel(); 2685 tborder = new TitledBorder("Indexing Type"); 2686 tborder.setTitleColor(Color.darkGray); 2687 pType.setBorder(tborder); 2688 pType.setLayout(new GridLayout(1, 2, 8, 8)); 2689 checkIndexType = new JRadioButton("By Name", (indexType) == selectedFile.getIndexType("H5_INDEX_NAME")); 2690 checkIndexType.setName("Index by Name"); 2691 pType.add(checkIndexType); 2692 JRadioButton checkIndexCreateOrder = new JRadioButton("By Creation Order", (indexType) == selectedFile.getIndexType("H5_INDEX_CRT_ORDER")); 2693 checkIndexCreateOrder.setName("Index by Creation Order"); 2694 pType.add(checkIndexCreateOrder); 2695 ButtonGroup bTypegrp = new ButtonGroup(); 2696 bTypegrp.add(checkIndexType); 2697 bTypegrp.add(checkIndexCreateOrder); 2698 indexP.add(pType); 2699 2700 JPanel pOrder = new JPanel(); 2701 tborder = new TitledBorder("Indexing Order"); 2702 tborder.setTitleColor(Color.darkGray); 2703 pOrder.setBorder(tborder); 2704 pOrder.setLayout(new GridLayout(1, 3, 8, 8)); 2705 checkIndexOrder = new JRadioButton("Increments", (indexOrder) == selectedFile.getIndexOrder("H5_ITER_INC")); 2706 checkIndexOrder.setName("Index Increments"); 2707 pOrder.add(checkIndexOrder); 2708 JRadioButton checkIndexDecrement = new JRadioButton("Decrements", (indexOrder) == selectedFile.getIndexOrder("H5_ITER_DEC")); 2709 checkIndexDecrement.setName("Index Decrements"); 2710 pOrder.add(checkIndexDecrement); 2711 checkIndexNative = new JRadioButton("Native", (indexOrder) == selectedFile.getIndexOrder("H5_ITER_NATIVE")); 2712 checkIndexNative.setName("Index Native"); 2713 pOrder.add(checkIndexNative); 2714 ButtonGroup bOrdergrp = new ButtonGroup(); 2715 bOrdergrp.add(checkIndexOrder); 2716 bOrdergrp.add(checkIndexDecrement); 2717 bOrdergrp.add(checkIndexNative); 2718 indexP.add(pOrder); 2719 2720 JPanel buttonP = new JPanel(); 2721 JButton b = new JButton("Reload File"); 2722 b.setName("Reload File"); 2723 b.setActionCommand("Reload File"); 2724 b.addActionListener(this); 2725 buttonP.add(b); 2726 b = new JButton("Cancel"); 2727 b.setName("Cancel"); 2728 b.setActionCommand("Cancel"); 2729 b.addActionListener(this); 2730 buttonP.add(b); 2731 2732 contentPane.add("Center", indexP); 2733 contentPane.add("South", buttonP); 2734 2735 // locate the parent dialog 2736 Point l = getParent().getLocation(); 2737 l.x += 250; 2738 l.y += 80; 2739 setLocation(l); 2740 validate(); 2741 pack(); 2742 } 2743 2744 public void setVisible(boolean b) { 2745 super.setVisible(b); 2746 } 2747 2748 public void actionPerformed(ActionEvent e) { 2749 String cmd = e.getActionCommand(); 2750 2751 if (cmd.equals("Reload File")) { 2752 setIndexOptions(); 2753 setVisible(false); 2754 } 2755 else if (cmd.equals("Cancel")) { 2756 reloadFile = false; 2757 setVisible(false); 2758 } 2759 } 2760 2761 private void setIndexOptions() { 2762 if (checkIndexType.isSelected()) 2763 selectedFile.setIndexType(selectedFile.getIndexType("H5_INDEX_NAME")); 2764 else 2765 selectedFile.setIndexType(selectedFile.getIndexType("H5_INDEX_CRT_ORDER")); 2766 indexType = selectedFile.getIndexType(null); 2767 2768 if (checkIndexOrder.isSelected()) 2769 selectedFile.setIndexOrder(selectedFile.getIndexOrder("H5_ITER_INC")); 2770 else if (checkIndexNative.isSelected()) 2771 selectedFile.setIndexOrder(selectedFile.getIndexOrder("H5_ITER_NATIVE")); 2772 else 2773 selectedFile.setIndexOrder(selectedFile.getIndexOrder("H5_ITER_DEC")); 2774 indexOrder = selectedFile.getIndexOrder(null); 2775 2776 reloadFile = true; 2777 } 2778 2779 public int getIndexType() { 2780 return indexType; 2781 } 2782 2783 public int getIndexOrder() { 2784 return indexOrder; 2785 } 2786 2787 public boolean isreloadFile() { 2788 return reloadFile; 2789 } 2790 } 2791 2792 @SuppressWarnings("rawtypes") 2793 private void setLibVersionBounds() { 2794 Object[] lowValues = { "Earliest", "Latest" }; 2795 Object[] highValues = { "Latest" }; 2796 JComboBox lowComboBox = new JComboBox(lowValues); 2797 lowComboBox.setName("earliestversion"); 2798 JComboBox highComboBox = new JComboBox(highValues); 2799 highComboBox.setName("latestversion"); 2800 2801 Object[] msg = { "Earliest Version:", lowComboBox, "Latest Version:", highComboBox }; 2802 Object[] options = { "Ok", "Cancel" }; 2803 JOptionPane op = new JOptionPane(msg, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null, options); 2804 2805 op.setName("libselect"); 2806 JDialog dialog = op.createDialog(this, "Set the library version bounds: "); 2807 dialog.setVisible(true); 2808 2809 String result = null; 2810 try { 2811 result = (String) op.getValue(); 2812 } 2813 catch (Exception err) { 2814 // err.printStackTrace(); 2815 } 2816 2817 if ((result != null) && (result.equals("Ok"))) { 2818 int low = -1; 2819 int high = 1; 2820 if ((lowComboBox.getSelectedItem()).equals("Earliest")) 2821 low = 0; 2822 else 2823 low = 1; 2824 try { 2825 selectedObject.getFileFormat().setLibBounds(low, high); 2826 } 2827 catch (Throwable err) { 2828 toolkit.beep(); 2829 JOptionPane.showMessageDialog(this, err, "Error when setting lib version bounds", 2830 JOptionPane.ERROR_MESSAGE); 2831 return; 2832 } 2833 } 2834 else 2835 return; 2836 } 2837}