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 java.awt.BorderLayout; 018import java.awt.Color; 019import java.awt.Dimension; 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.ItemEvent; 026import java.awt.event.ItemListener; 027import java.awt.event.KeyEvent; 028import java.net.URL; 029import java.net.URLClassLoader; 030import java.util.Iterator; 031import java.util.List; 032import java.util.StringTokenizer; 033import java.util.Vector; 034 035import javax.swing.BorderFactory; 036import javax.swing.ButtonGroup; 037import javax.swing.JButton; 038import javax.swing.JCheckBox; 039import javax.swing.JComboBox; 040import javax.swing.JDialog; 041import javax.swing.JEditorPane; 042import javax.swing.JFrame; 043import javax.swing.JLabel; 044import javax.swing.JOptionPane; 045import javax.swing.JPanel; 046import javax.swing.JRadioButton; 047import javax.swing.JScrollPane; 048import javax.swing.JTextField; 049import javax.swing.border.TitledBorder; 050import javax.swing.event.HyperlinkEvent; 051import javax.swing.event.HyperlinkListener; 052import javax.swing.text.html.HTMLDocument; 053import javax.swing.text.html.HTMLFrameHyperlinkEvent; 054 055import hdf.object.DataFormat; 056import hdf.object.Dataset; 057import hdf.object.Datatype; 058import hdf.object.FileFormat; 059import hdf.object.Group; 060import hdf.object.HObject; 061import hdf.object.ScalarDS; 062 063/** 064 * NewDatasetDialog shows a message dialog requesting user input for creating a 065 * new HDF4/5 dataset. 066 * 067 * @author Peter X. Cao 068 * @version 2.4 9/6/2007 069 */ 070public class NewDatasetDialog extends JDialog implements ActionListener, ItemListener, HyperlinkListener { 071 private static final long serialVersionUID = 5381164938654184532L; 072 073 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NewDatasetDialog.class); 074 075 private JTextField nameField, currentSizeField, maxSizeField, chunkSizeField, stringLengthField, 076 fillValueField; 077 078 @SuppressWarnings("rawtypes") 079 private JComboBox parentChoice, classChoice, sizeChoice, endianChoice, rankChoice, compressionLevel; 080 081 private JCheckBox checkUnsigned, checkCompression, checkFillValue; 082 083 private JRadioButton checkContinguous, checkChunked; 084 085 private JDialog helpDialog; 086 087 private boolean isH5; 088 089 /** a list of current groups */ 090 private List<Object> groupList; 091 092 private HObject newObject; 093 094 private FileFormat fileFormat; 095 096 private final Toolkit toolkit; 097 098 private final DataView dataView; 099 100 /** 101 * Constructs NewDatasetDialog with specified list of possible parent 102 * groups. 103 * 104 * @param owner 105 * the owner of the input 106 * @param pGroup 107 * the parent group which the new group is added to. 108 * @param objs 109 * the list of all objects. 110 */ 111 @SuppressWarnings({ "rawtypes", "unchecked" }) 112 public NewDatasetDialog(JFrame owner, Group pGroup, List<?> objs) { 113 super(owner, "New Dataset...", true); 114 115 helpDialog = null; 116 newObject = null; 117 dataView = null; 118 119 fileFormat = pGroup.getFileFormat(); 120 toolkit = Toolkit.getDefaultToolkit(); 121 isH5 = pGroup.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5)); 122 123 parentChoice = new JComboBox(); 124 groupList = new Vector<Object>(); 125 Object obj = null; 126 Iterator<?> iterator = objs.iterator(); 127 while (iterator.hasNext()) { 128 obj = iterator.next(); 129 if (obj instanceof Group) { 130 Group g = (Group) obj; 131 groupList.add(obj); 132 if (g.isRoot()) { 133 parentChoice.addItem(HObject.separator); 134 } 135 else { 136 parentChoice.addItem(g.getPath() + g.getName() + HObject.separator); 137 } 138 } 139 } 140 141 if (pGroup.isRoot()) { 142 parentChoice.setSelectedItem(HObject.separator); 143 } 144 else { 145 parentChoice.setSelectedItem(pGroup.getPath() + pGroup.getName() + HObject.separator); 146 } 147 148 JPanel contentPane = (JPanel) getContentPane(); 149 contentPane.setLayout(new BorderLayout(5, 5)); 150 contentPane.setBorder(BorderFactory.createEmptyBorder(15, 5, 5, 5)); 151 int w = 600 + (ViewProperties.getFontSize() - 12) * 15; 152 int h = 350 + (ViewProperties.getFontSize() - 12) * 10; 153 contentPane.setPreferredSize(new Dimension(w, h)); 154 155 JButton okButton = new JButton(" Ok "); 156 okButton.setName("OK"); 157 okButton.setActionCommand("Ok"); 158 okButton.setMnemonic(KeyEvent.VK_O); 159 okButton.addActionListener(this); 160 161 JButton cancelButton = new JButton("Cancel"); 162 cancelButton.setName("Cancel"); 163 cancelButton.setMnemonic(KeyEvent.VK_C); 164 cancelButton.setActionCommand("Cancel"); 165 cancelButton.addActionListener(this); 166 167 JButton helplButton = new JButton("Help"); 168 helplButton.setName("Help"); 169 helplButton.setMnemonic(KeyEvent.VK_H); 170 helplButton.setActionCommand("Show help"); 171 helplButton.addActionListener(this); 172 173 // set OK and CANCEL buttons 174 JPanel buttonPanel = new JPanel(); 175 buttonPanel.add(okButton); 176 buttonPanel.add(cancelButton); 177 buttonPanel.add(helplButton); 178 contentPane.add(buttonPanel, BorderLayout.SOUTH); 179 180 // set NAME and PARENT GROUP panel 181 JPanel namePanel = new JPanel(); 182 namePanel.setLayout(new BorderLayout(5, 5)); 183 JPanel tmpP = new JPanel(); 184 tmpP.setLayout(new GridLayout(2, 1)); 185 tmpP.add(new JLabel("Dataset name: ")); 186 tmpP.add(new JLabel("Parent group: ")); 187 namePanel.add(tmpP, BorderLayout.WEST); 188 tmpP = new JPanel(); 189 tmpP.setLayout(new GridLayout(2, 1)); 190 tmpP.add(nameField = new JTextField()); 191 nameField.setName("datasetname"); 192 tmpP.add(parentChoice); 193 namePanel.add(tmpP, BorderLayout.CENTER); 194 contentPane.add(namePanel, BorderLayout.NORTH); 195 196 // set DATATYPE 197 JPanel typePanel = new JPanel(); 198 typePanel.setLayout(new GridLayout(2, 4, 15, 3)); 199 TitledBorder border = new TitledBorder("Datatype"); 200 border.setTitleColor(Color.gray); 201 typePanel.setBorder(border); 202 203 stringLengthField = new JTextField("String length"); 204 stringLengthField.setName("datasetstringlen"); 205 stringLengthField.setEnabled(false); 206 207 endianChoice = new JComboBox(); 208 endianChoice.setName("datasetendian"); 209 classChoice = new JComboBox(); 210 classChoice.setName("datasetclass"); 211 sizeChoice = new JComboBox(); 212 sizeChoice.setName("datasetsize"); 213 endianChoice.setEnabled(isH5); 214 215 classChoice.addItem("INTEGER"); 216 classChoice.addItem("FLOAT"); 217 classChoice.addItem("CHAR"); 218 219 if (isH5) { 220 classChoice.addItem("STRING"); 221 classChoice.addItem("REFERENCE"); 222 classChoice.addItem("ENUM"); 223 classChoice.addItem("VLEN_INTEGER"); 224 classChoice.addItem("VLEN_FLOAT"); 225 classChoice.addItem("VLEN_STRING"); 226 sizeChoice.addItem("NATIVE"); 227 endianChoice.addItem("NATIVE"); 228 endianChoice.addItem("LITTLE ENDIAN"); 229 endianChoice.addItem("BIG ENDIAN"); 230 } 231 else { 232 sizeChoice.addItem("DEFAULT"); 233 endianChoice.addItem("DEFAULT"); 234 } 235 sizeChoice.addItem("8"); 236 sizeChoice.addItem("16"); 237 sizeChoice.addItem("32"); 238 sizeChoice.addItem("64"); 239 240 typePanel.add(new JLabel("Datatype class")); 241 typePanel.add(new JLabel("Size (bits)")); 242 typePanel.add(new JLabel("Byte ordering")); 243 checkUnsigned = new JCheckBox("Unsigned"); 244 checkUnsigned.setName("datasetchkunsigned"); 245 typePanel.add(checkUnsigned); 246 247 typePanel.add(classChoice); 248 typePanel.add(sizeChoice); 249 typePanel.add(endianChoice); 250 typePanel.add(stringLengthField); 251 252 // set DATATSPACE 253 JPanel spacePanel = new JPanel(); 254 spacePanel.setLayout(new GridLayout(2, 3, 15, 3)); 255 border = new TitledBorder("Dataspace"); 256 border.setTitleColor(Color.gray); 257 spacePanel.setBorder(border); 258 259 rankChoice = new JComboBox(); 260 rankChoice.setName("datasetrank"); 261 for (int i = 1; i < 33; i++) { 262 rankChoice.addItem(String.valueOf(i)); 263 } 264 rankChoice.setSelectedIndex(1); 265 266 currentSizeField = new JTextField("1 x 1"); 267 currentSizeField.setName("currentsize"); 268 maxSizeField = new JTextField(""); 269 spacePanel.add(new JLabel("No. of dimensions")); 270 spacePanel.add(new JLabel("Current size")); 271 spacePanel.add(new JLabel("")); 272 spacePanel.add(rankChoice); 273 spacePanel.add(currentSizeField); 274 JButton jb = new JButton("Set Max Size"); 275 jb.setActionCommand("Set max size"); 276 jb.addActionListener(this); 277 spacePanel.add(jb); 278 // spacePanel.add(maxSizeField); 279 280 // set storage layout and data compression 281 JPanel layoutPanel = new JPanel(); 282 layoutPanel.setLayout(new BorderLayout()); 283 border = new TitledBorder("Storage Properties"); 284 border.setTitleColor(Color.gray); 285 layoutPanel.setBorder(border); 286 287 checkContinguous = new JRadioButton("Contiguous"); 288 checkContinguous.setName("datasetcontinguous"); 289 checkContinguous.setSelected(true); 290 checkChunked = new JRadioButton("Chunked (size) "); 291 checkChunked.setName("datasetchunk"); 292 ButtonGroup bgroup = new ButtonGroup(); 293 bgroup.add(checkChunked); 294 bgroup.add(checkContinguous); 295 chunkSizeField = new JTextField("1 x 1"); 296 chunkSizeField.setName("datasetchunksize"); 297 chunkSizeField.setEnabled(false); 298 checkCompression = new JCheckBox("gzip (level) "); 299 checkCompression.setName("datasetgzip"); 300 301 compressionLevel = new JComboBox(); 302 compressionLevel.setName("datasetlevel"); 303 for (int i = 0; i < 10; i++) { 304 compressionLevel.addItem(String.valueOf(i)); 305 } 306 compressionLevel.setSelectedIndex(6); 307 compressionLevel.setEnabled(false); 308 309 tmpP = new JPanel(); 310 tmpP.setLayout(new GridLayout(2, 1)); 311 tmpP.add(new JLabel("Storage layout: ")); 312 tmpP.add(new JLabel("Compression: ")); 313 layoutPanel.add(tmpP, BorderLayout.WEST); 314 315 tmpP = new JPanel(); 316 tmpP.setLayout(new GridLayout(2, 1)); 317 318 // storage layout 319 JPanel tmpP0 = new JPanel(); 320 tmpP0.setLayout(new GridLayout(1, 3, 0, 5)); 321 tmpP0.add(checkContinguous); 322 JPanel tmpP00 = new JPanel(); 323 tmpP00.setLayout(new BorderLayout()); 324 tmpP00.add(checkChunked, BorderLayout.WEST); 325 tmpP00.add(chunkSizeField, BorderLayout.CENTER); 326 tmpP0.add(tmpP00); 327 tmpP0.add(new JLabel("")); 328 tmpP.add(tmpP0); 329 330 tmpP0 = new JPanel(); 331 tmpP0.setLayout(new GridLayout(1, 2, 30, 5)); 332 333 // compression 334 tmpP00 = new JPanel(); 335 tmpP00.setLayout(new BorderLayout()); 336 tmpP00.add(checkCompression, BorderLayout.WEST); 337 tmpP00.add(compressionLevel, BorderLayout.CENTER); 338 tmpP0.add(tmpP00); 339 340 // fill values 341 checkFillValue = new JCheckBox("Fill Value "); 342 checkFillValue.setName("datasetchkfill"); 343 fillValueField = new JTextField("0"); 344 fillValueField.setName("datasetfillval"); 345 fillValueField.setEnabled(false); 346 checkFillValue.setSelected(false); 347 tmpP00 = new JPanel(); 348 tmpP00.setLayout(new BorderLayout()); 349 tmpP00.add(checkFillValue, BorderLayout.WEST); 350 tmpP00.add(fillValueField, BorderLayout.CENTER); 351 352 if (isH5) 353 tmpP0.add(tmpP00); 354 else 355 tmpP0.add(new JLabel("")); 356 357 tmpP.add(tmpP0); 358 359 layoutPanel.add(tmpP, BorderLayout.CENTER); 360 361 JPanel infoPanel = new JPanel(); 362 infoPanel.setLayout(new GridLayout(3, 1, 5, 10)); 363 infoPanel.add(typePanel); 364 infoPanel.add(spacePanel); 365 infoPanel.add(layoutPanel); 366 contentPane.add(infoPanel, BorderLayout.CENTER); 367 368 classChoice.addItemListener(this); 369 sizeChoice.addItemListener(this); 370 rankChoice.addItemListener(this); 371 checkCompression.addItemListener(this); 372 checkFillValue.addItemListener(this); 373 checkContinguous.addItemListener(this); 374 checkChunked.addItemListener(this); 375 376 // locate the H5Property dialog 377 Point l = owner.getLocation(); 378 l.x += 250; 379 l.y += 80; 380 setLocation(l); 381 validate(); 382 pack(); 383 } 384 385 /** 386 * Constructs NewDatasetDialog with specified list of possible parent 387 * groups. 388 * 389 * @param owner 390 * the owner of the input 391 * @param pGroup 392 * the parent group which the new group is added to. 393 * @param objs 394 * the list of all objects. 395 * @param observer 396 * the parent DataView 397 */ 398 @SuppressWarnings({ "rawtypes", "unchecked" }) 399 public NewDatasetDialog(JFrame owner, Group pGroup, List<?> objs, DataView observer) { 400 super(owner, "New Dataset...", true); 401 402 helpDialog = null; 403 newObject = null; 404 dataView = observer; 405 406 fileFormat = pGroup.getFileFormat(); 407 toolkit = Toolkit.getDefaultToolkit(); 408 isH5 = pGroup.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5)); 409 410 parentChoice = new JComboBox(); 411 groupList = new Vector<Object>(); 412 Object obj = null; 413 Iterator<?> iterator = objs.iterator(); 414 while (iterator.hasNext()) { 415 obj = iterator.next(); 416 if (obj instanceof Group) { 417 Group g = (Group) obj; 418 groupList.add(obj); 419 if (g.isRoot()) { 420 parentChoice.addItem(HObject.separator); 421 } 422 else { 423 parentChoice.addItem(g.getPath() + g.getName() + HObject.separator); 424 } 425 } 426 } 427 428 if (pGroup.isRoot()) { 429 parentChoice.setSelectedItem(HObject.separator); 430 } 431 else { 432 parentChoice.setSelectedItem(pGroup.getPath() + pGroup.getName() + HObject.separator); 433 } 434 435 JPanel contentPane = (JPanel) getContentPane(); 436 contentPane.setLayout(new BorderLayout(5, 5)); 437 contentPane.setBorder(BorderFactory.createEmptyBorder(15, 5, 5, 5)); 438 int w = 400 + (ViewProperties.getFontSize() - 12) * 15; 439 int h = 120 + (ViewProperties.getFontSize() - 12) * 10; 440 contentPane.setPreferredSize(new Dimension(w, h)); 441 442 JButton okButton = new JButton(" Ok "); 443 okButton.setActionCommand("Ok"); 444 okButton.setMnemonic(KeyEvent.VK_O); 445 okButton.addActionListener(this); 446 447 JButton cancelButton = new JButton("Cancel"); 448 cancelButton.setMnemonic(KeyEvent.VK_C); 449 cancelButton.setActionCommand("Cancel"); 450 cancelButton.addActionListener(this); 451 452 // set OK and CANCEL buttons 453 JPanel buttonPanel = new JPanel(); 454 buttonPanel.add(okButton); 455 buttonPanel.add(cancelButton); 456 contentPane.add(buttonPanel, BorderLayout.SOUTH); 457 458 // set NAME and PARENT GROUP panel 459 JPanel namePanel = new JPanel(); 460 namePanel.setLayout(new BorderLayout(5, 5)); 461 JPanel tmpP = new JPanel(); 462 tmpP.setLayout(new GridLayout(2, 1)); 463 tmpP.add(new JLabel("Dataset name: ")); 464 tmpP.add(new JLabel("Parent group: ")); 465 namePanel.add(tmpP, BorderLayout.WEST); 466 tmpP = new JPanel(); 467 tmpP.setLayout(new GridLayout(2, 1)); 468 tmpP.add(nameField = new JTextField(((HObject) observer.getDataObject()).getName() + "~copy", 40)); 469 tmpP.add(parentChoice); 470 namePanel.add(tmpP, BorderLayout.CENTER); 471 contentPane.add(namePanel, BorderLayout.CENTER); 472 473 // locate the H5Property dialog 474 Point l = owner.getLocation(); 475 l.x += 250; 476 l.y += 80; 477 setLocation(l); 478 pack(); 479 } 480 481 public void actionPerformed(ActionEvent e) { 482 String cmd = e.getActionCommand(); 483 484 if (cmd.equals("Ok")) { 485 if (dataView instanceof TableView) { 486 newObject = createFromTable(); 487 } 488 else if (dataView instanceof ImageView) { 489 newObject = createFromImage(); 490 } 491 else if (dataView == null) { 492 newObject = createFromScratch(); 493 } 494 495 if (newObject != null) { 496 dispose(); 497 } 498 } 499 if (cmd.equals("Cancel")) { 500 newObject = null; 501 dispose(); 502 ((Vector<Object>) groupList).setSize(0); 503 } 504 else if (cmd.equals("Show help")) { 505 if (helpDialog == null) { 506 createHelpDialog(); 507 } 508 helpDialog.setVisible(true); 509 } 510 else if (cmd.equals("Hide help")) { 511 if (helpDialog != null) { 512 helpDialog.setVisible(false); 513 } 514 } 515 else if (cmd.equals("Set max size")) { 516 String strMax = maxSizeField.getText(); 517 if (strMax == null || strMax.length() < 1) strMax = currentSizeField.getText(); 518 519 String msg = JOptionPane.showInputDialog(this, "Enter max dimension sizes. \n" 520 + "Use \"unlimited\" for unlimited dimension size.\n\n" + "For example,\n" + " 200 x 100\n" 521 + " 100 x unlimited\n\n", strMax); 522 523 if (msg == null || msg.length() < 1) 524 maxSizeField.setText(currentSizeField.getText()); 525 else 526 maxSizeField.setText(msg); 527 528 checkMaxSize(); 529 } 530 } 531 532 @SuppressWarnings("unchecked") 533 public void itemStateChanged(ItemEvent e) { 534 Object source = e.getSource(); 535 536 if (source.equals(classChoice)) { 537 int idx = classChoice.getSelectedIndex(); 538 sizeChoice.setSelectedIndex(0); 539 endianChoice.setSelectedIndex(0); 540 stringLengthField.setEnabled(false); 541 542 if ((idx == 0) || (idx == 6)) { // INTEGER 543 sizeChoice.setEnabled(true); 544 endianChoice.setEnabled(isH5); 545 checkUnsigned.setEnabled(true); 546 547 if (sizeChoice.getItemCount() == 3) { 548 sizeChoice.removeItem("32"); 549 sizeChoice.removeItem("64"); 550 sizeChoice.addItem("8"); 551 sizeChoice.addItem("16"); 552 sizeChoice.addItem("32"); 553 sizeChoice.addItem("64"); 554 } 555 } 556 else if ((idx == 1) || (idx == 7)) { // FLOAT 557 sizeChoice.setEnabled(true); 558 endianChoice.setEnabled(isH5); 559 checkUnsigned.setEnabled(false); 560 561 if (sizeChoice.getItemCount() == 5) { 562 sizeChoice.removeItem("16"); 563 sizeChoice.removeItem("8"); 564 } 565 } 566 else if (idx == 2) { // CHAR 567 sizeChoice.setEnabled(false); 568 endianChoice.setEnabled(isH5); 569 checkUnsigned.setEnabled(true); 570 } 571 else if (idx == 3) { // STRING 572 sizeChoice.setEnabled(false); 573 endianChoice.setEnabled(false); 574 checkUnsigned.setEnabled(false); 575 stringLengthField.setEnabled(true); 576 stringLengthField.setText("String length"); 577 } 578 else if (idx == 4) { // REFERENCE 579 sizeChoice.setEnabled(false); 580 endianChoice.setEnabled(false); 581 checkUnsigned.setEnabled(false); 582 stringLengthField.setEnabled(false); 583 } 584 else if (idx == 5) { // ENUM 585 sizeChoice.setEnabled(true); 586 checkUnsigned.setEnabled(true); 587 stringLengthField.setEnabled(true); 588 stringLengthField.setText("R=0,G=1,B=2,..."); 589 } 590 else if (idx == 8) { 591 sizeChoice.setEnabled(false); 592 endianChoice.setEnabled(false); 593 checkUnsigned.setEnabled(false); 594 stringLengthField.setEnabled(false); 595 } 596 } 597 else if (source.equals(sizeChoice)) { 598 if (classChoice.getSelectedIndex() == 0) { 599 checkUnsigned.setEnabled(true); 600 } 601 } 602 else if (source.equals(rankChoice)) { 603 int rank = rankChoice.getSelectedIndex() + 1; 604 String currentSizeStr = "1"; 605 String maxSizeStr = "0"; 606 607 for (int i = 1; i < rank; i++) { 608 currentSizeStr += " x 1"; 609 maxSizeStr += " x 0"; 610 } 611 612 currentSizeField.setText(currentSizeStr); 613 maxSizeField.setText(maxSizeStr); 614 615 String currentStr = currentSizeField.getText(); 616 int idx = currentStr.lastIndexOf("x"); 617 String chunkStr = "1"; 618 619 if (rank <= 1) { 620 chunkStr = currentStr; 621 } 622 else { 623 for (int i = 1; i < rank - 1; i++) { 624 chunkStr += " x 1"; 625 } 626 if (idx > 0) { 627 chunkStr += " x " + currentStr.substring(idx + 1); 628 } 629 } 630 631 chunkSizeField.setText(chunkStr); 632 } 633 else if (source.equals(checkContinguous)) { 634 chunkSizeField.setEnabled(false); 635 } 636 else if (source.equals(checkChunked)) { 637 chunkSizeField.setEnabled(true); 638 String chunkStr = ""; 639 StringTokenizer st = new StringTokenizer(currentSizeField.getText(), "x"); 640 int rank = rankChoice.getSelectedIndex() + 1; 641 while (st.hasMoreTokens()) { 642 long l = Math.max(1, Long.valueOf(st.nextToken().trim()) / (2 * rank)); 643 chunkStr += String.valueOf(l) + "x"; 644 } 645 chunkStr = chunkStr.substring(0, chunkStr.lastIndexOf('x')); 646 chunkSizeField.setText(chunkStr); 647 } 648 else if (source.equals(checkCompression)) { 649 boolean isCompressed = checkCompression.isSelected(); 650 651 if (isCompressed && isH5) { 652 if (!checkChunked.isSelected()) { 653 String currentStr = currentSizeField.getText(); 654 int idx = currentStr.lastIndexOf("x"); 655 String chunkStr = "1"; 656 657 int rank = rankChoice.getSelectedIndex() + 1; 658 if (rank <= 1) { 659 chunkStr = currentStr; 660 } 661 else { 662 for (int i = 1; i < rank - 1; i++) { 663 chunkStr += " x 1"; 664 } 665 if (idx > 0) { 666 chunkStr += " x " + currentStr.substring(idx + 1); 667 } 668 } 669 670 chunkSizeField.setText(chunkStr); 671 } 672 compressionLevel.setEnabled(true); 673 checkContinguous.setEnabled(false); 674 checkChunked.setSelected(true); 675 chunkSizeField.setEnabled(true); 676 } 677 else { 678 compressionLevel.setEnabled(isCompressed); 679 checkContinguous.setEnabled(true); 680 } 681 } 682 else if (source.equals(checkFillValue)) { 683 fillValueField.setEnabled(checkFillValue.isSelected()); 684 } 685 } 686 687 /** check is the max size is valid */ 688 private void checkMaxSize() { 689 boolean isChunkNeeded = false; 690 String dimStr = currentSizeField.getText(); 691 String maxStr = maxSizeField.getText(); 692 StringTokenizer stMax = new StringTokenizer(maxStr, "x"); 693 StringTokenizer stDim = new StringTokenizer(dimStr, "x"); 694 695 if (stMax.countTokens() != stDim.countTokens()) { 696 toolkit.beep(); 697 JOptionPane.showMessageDialog(this, "Wrong number of values in the max dimension size " + maxStr, 698 getTitle(), JOptionPane.ERROR_MESSAGE); 699 maxSizeField.setText(null); 700 return; 701 } 702 703 int rank = stDim.countTokens(); 704 long max = 0, dim = 0; 705 long[] maxdims = new long[rank]; 706 for (int i = 0; i < rank; i++) { 707 String token = stMax.nextToken().trim(); 708 709 token = token.toLowerCase(); 710 if (token.startsWith("u")) { 711 max = -1; 712 isChunkNeeded = true; 713 } 714 else { 715 try { 716 max = Long.parseLong(token); 717 } 718 catch (NumberFormatException ex) { 719 toolkit.beep(); 720 JOptionPane.showMessageDialog(this, "Invalid max dimension size: " + maxStr, getTitle(), 721 JOptionPane.ERROR_MESSAGE); 722 maxSizeField.setText(null); 723 return; 724 } 725 } 726 727 token = stDim.nextToken().trim(); 728 try { 729 dim = Long.parseLong(token); 730 } 731 catch (NumberFormatException ex) { 732 toolkit.beep(); 733 JOptionPane.showMessageDialog(this, "Invalid dimension size: " + dimStr, getTitle(), 734 JOptionPane.ERROR_MESSAGE); 735 return; 736 } 737 738 if (max != -1 && max < dim) { 739 toolkit.beep(); 740 JOptionPane.showMessageDialog(this, "Invalid max dimension size: " + maxStr, getTitle(), 741 JOptionPane.ERROR_MESSAGE); 742 maxSizeField.setText(null); 743 return; 744 } 745 else if (max > dim) { 746 isChunkNeeded = true; 747 } 748 749 maxdims[i] = max; 750 } // for (int i = 0; i < rank; i++) 751 752 if (isH5) { 753 if (isChunkNeeded && !checkChunked.isSelected()) { 754 toolkit.beep(); 755 JOptionPane.showMessageDialog(this, "Chunking is required for the max dimensions of " + maxStr, 756 getTitle(), JOptionPane.ERROR_MESSAGE); 757 checkChunked.setSelected(true); 758 } 759 } 760 else { 761 for (int i = 1; i < rank; i++) { 762 if (maxdims[i] <= 0) { 763 maxSizeField.setText(currentSizeField.getText()); 764 toolkit.beep(); 765 JOptionPane.showMessageDialog(this, "Only dim[0] can be unlimited." + maxStr, getTitle(), 766 JOptionPane.ERROR_MESSAGE); 767 return; 768 } 769 } 770 } 771 } 772 773 /** Creates a dialog to show the help information. */ 774 private void createHelpDialog() { 775 helpDialog = new JDialog(this, "Create New Dataset"); 776 777 JPanel contentPane = (JPanel) helpDialog.getContentPane(); 778 contentPane.setLayout(new BorderLayout(5, 5)); 779 contentPane.setBorder(BorderFactory.createEmptyBorder(15, 5, 5, 5)); 780 int w = 500 + (ViewProperties.getFontSize() - 12) * 15; 781 int h = 400 + (ViewProperties.getFontSize() - 12) * 10; 782 contentPane.setPreferredSize(new Dimension(w, h)); 783 784 JButton b = new JButton(" Ok "); 785 b.addActionListener(this); 786 b.setActionCommand("Hide help"); 787 JPanel tmpP = new JPanel(); 788 tmpP.add(b); 789 contentPane.add(tmpP, BorderLayout.SOUTH); 790 791 JEditorPane infoPane = new JEditorPane(); 792 infoPane.setEditable(false); 793 JScrollPane editorScrollPane = new JScrollPane(infoPane); 794 contentPane.add(editorScrollPane, BorderLayout.CENTER); 795 796 try { 797 URL url = null, url2 = null, url3 = null; 798 String rootPath = ViewProperties.getViewRoot(); 799 800 try { 801 url = new URL("file:" + rootPath + "/lib/jhdfview.jar"); 802 } 803 catch (java.net.MalformedURLException mfu) { 804 log.debug("help information:", mfu); 805 } 806 807 try { 808 url2 = new URL("file:" + rootPath + "/"); 809 } 810 catch (java.net.MalformedURLException mfu) { 811 log.debug("help information:", mfu); 812 } 813 814 try { 815 url3 = new URL("file:" + rootPath + "/src/"); 816 } 817 catch (java.net.MalformedURLException mfu) { 818 log.debug("help information:", mfu); 819 } 820 821 URL uu[] = { url, url2, url3 }; 822 URLClassLoader cl = new URLClassLoader(uu); 823 URL u = cl.findResource("hdf/view/NewDatasetHelp.html"); 824 825 if (u == null) { 826 u = ClassLoader.getSystemResource("hdf/view/NewDatasetHelp.html"); 827 } 828 829 cl.close(); 830 infoPane.setPage(u); 831 infoPane.addHyperlinkListener(this); 832 } 833 catch (Exception e) { 834 infoPane.setContentType("text/html"); 835 StringBuffer buff = new StringBuffer(); 836 buff.append("<html>"); 837 buff.append("<body>"); 838 buff.append("ERROR: cannot load help information."); 839 buff.append("</body>"); 840 buff.append("</html>"); 841 infoPane.setText(buff.toString()); 842 } 843 844 Point l = helpDialog.getOwner().getLocation(); 845 l.x += 50; 846 l.y += 80; 847 helpDialog.setLocation(l); 848 helpDialog.validate(); 849 helpDialog.pack(); 850 } 851 852 public void hyperlinkUpdate(HyperlinkEvent e) { 853 if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { 854 JEditorPane pane = (JEditorPane) e.getSource(); 855 856 if (e instanceof HTMLFrameHyperlinkEvent) { 857 HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent) e; 858 HTMLDocument doc = (HTMLDocument) pane.getDocument(); 859 doc.processHTMLFrameHyperlinkEvent(evt); 860 } 861 else { 862 try { 863 pane.setPage(e.getURL()); 864 } 865 catch (Throwable t) { 866 log.debug("JEditorPane hyperlink:", t); 867 } 868 } 869 } 870 } 871 872 private HObject createFromScratch() { 873 String name = null; 874 Group pgroup = null; 875 boolean isVLen = false; 876 int rank = -1, gzip = -1, tclass = -1, tsize = -1, torder = -1, tsign = -1; 877 long dims[], maxdims[] = null, chunks[] = null; 878 879 name = nameField.getText().trim(); 880 if ((name == null) || (name.length() < 1)) { 881 toolkit.beep(); 882 JOptionPane 883 .showMessageDialog(this, "Dataset name is not specified.", getTitle(), JOptionPane.ERROR_MESSAGE); 884 return null; 885 } 886 887 if (name.indexOf(HObject.separator) >= 0) { 888 toolkit.beep(); 889 JOptionPane.showMessageDialog(this, "Dataset name cannot contain path.", getTitle(), 890 JOptionPane.ERROR_MESSAGE); 891 return null; 892 } 893 894 pgroup = (Group) groupList.get(parentChoice.getSelectedIndex()); 895 896 if (pgroup == null) { 897 toolkit.beep(); 898 JOptionPane.showMessageDialog(this, "Parent group is null.", getTitle(), JOptionPane.ERROR_MESSAGE); 899 return null; 900 } 901 902 // set datatype class 903 int idx = classChoice.getSelectedIndex(); 904 if (idx == 0) { 905 tclass = Datatype.CLASS_INTEGER; 906 if (checkUnsigned.isSelected()) { 907 tsign = Datatype.SIGN_NONE; 908 } 909 } 910 else if (idx == 1) { 911 tclass = Datatype.CLASS_FLOAT; 912 } 913 else if (idx == 2) { 914 tclass = Datatype.CLASS_CHAR; 915 if (checkUnsigned.isSelected()) { 916 tsign = Datatype.SIGN_NONE; 917 } 918 } 919 else if (idx == 3) { 920 tclass = Datatype.CLASS_STRING; 921 } 922 else if (idx == 4) { 923 tclass = Datatype.CLASS_REFERENCE; 924 } 925 else if (idx == 5) { 926 tclass = Datatype.CLASS_ENUM; 927 } 928 else if (idx == 6) { 929 isVLen = true; 930 tclass = Datatype.CLASS_INTEGER; 931 if (checkUnsigned.isSelected()) { 932 tsign = Datatype.SIGN_NONE; 933 } 934 } 935 else if (idx == 7) { 936 isVLen = true; 937 tclass = Datatype.CLASS_FLOAT; 938 } 939 else if (idx == 8) { 940 isVLen = true; 941 tclass = Datatype.CLASS_STRING; 942 } 943 944 // set datatype size/order 945 idx = sizeChoice.getSelectedIndex(); 946 if (tclass == Datatype.CLASS_STRING) { 947 if (isVLen) { 948 tsize = -1; 949 } 950 else { 951 int stringLength = 0; 952 try { 953 stringLength = Integer.parseInt(stringLengthField.getText()); 954 } 955 catch (NumberFormatException ex) { 956 stringLength = -1; 957 } 958 959 if (stringLength <= 0) { 960 toolkit.beep(); 961 JOptionPane.showMessageDialog(this, "Invalid string length: " + stringLengthField.getText(), 962 getTitle(), JOptionPane.ERROR_MESSAGE); 963 return null; 964 } 965 tsize = stringLength; 966 } 967 } 968 else if (tclass == Datatype.CLASS_ENUM) { 969 String enumStr = stringLengthField.getText(); 970 if ((enumStr == null) || (enumStr.length() < 1) || enumStr.endsWith("...")) { 971 toolkit.beep(); 972 JOptionPane.showMessageDialog(this, "Invalid member values: " + stringLengthField.getText(), 973 getTitle(), JOptionPane.ERROR_MESSAGE); 974 return null; 975 } 976 } 977 else if (tclass == Datatype.CLASS_REFERENCE) { 978 tsize = 1; 979 } 980 else if (idx == 0) { 981 tsize = Datatype.NATIVE; 982 } 983 else if (tclass == Datatype.CLASS_FLOAT) { 984 tsize = idx * 4; 985 } 986 else { 987 tsize = 1 << (idx - 1); 988 } 989 990 if ((tsize == 8) && !isH5 && (tclass == Datatype.CLASS_INTEGER)) { 991 toolkit.beep(); 992 JOptionPane.showMessageDialog(this, "HDF4 does not support 64-bit integer.", getTitle(), 993 JOptionPane.ERROR_MESSAGE); 994 return null; 995 } 996 997 // set order 998 idx = endianChoice.getSelectedIndex(); 999 if (idx == 0) { 1000 torder = Datatype.NATIVE; 1001 } 1002 else if (idx == 1) { 1003 torder = Datatype.ORDER_LE; 1004 } 1005 else { 1006 torder = Datatype.ORDER_BE; 1007 } 1008 1009 rank = rankChoice.getSelectedIndex() + 1; 1010 StringTokenizer st = new StringTokenizer(currentSizeField.getText(), "x"); 1011 if (st.countTokens() < rank) { 1012 toolkit.beep(); 1013 JOptionPane.showMessageDialog(this, "Number of values in the current dimension size is less than " + rank, 1014 getTitle(), JOptionPane.ERROR_MESSAGE); 1015 return null; 1016 } 1017 1018 long l = 0; 1019 dims = new long[rank]; 1020 String token = null; 1021 for (int i = 0; i < rank; i++) { 1022 token = st.nextToken().trim(); 1023 try { 1024 l = Long.parseLong(token); 1025 } 1026 catch (NumberFormatException ex) { 1027 toolkit.beep(); 1028 JOptionPane.showMessageDialog(this, "Invalid dimension size: " + currentSizeField.getText(), 1029 getTitle(), JOptionPane.ERROR_MESSAGE); 1030 return null; 1031 } 1032 1033 if (l <= 0) { 1034 toolkit.beep(); 1035 JOptionPane.showMessageDialog(this, "Dimension size must be greater than zero.", getTitle(), 1036 JOptionPane.ERROR_MESSAGE); 1037 return null; 1038 } 1039 1040 dims[i] = l; 1041 } 1042 1043 String maxFieldStr = maxSizeField.getText(); 1044 if (maxFieldStr != null && maxFieldStr.length() > 1) { 1045 st = new StringTokenizer(maxFieldStr, "x"); 1046 if (st.countTokens() < rank) { 1047 toolkit.beep(); 1048 JOptionPane.showMessageDialog(this, "Number of values in the max dimension size is less than " + rank, 1049 getTitle(), JOptionPane.ERROR_MESSAGE); 1050 return null; 1051 } 1052 1053 l = 0; 1054 maxdims = new long[rank]; 1055 for (int i = 0; i < rank; i++) { 1056 token = st.nextToken().trim(); 1057 1058 token = token.toLowerCase(); 1059 if (token.startsWith("u")) 1060 l = -1; 1061 else { 1062 try { 1063 l = Long.parseLong(token); 1064 } 1065 catch (NumberFormatException ex) { 1066 toolkit.beep(); 1067 JOptionPane.showMessageDialog(this, "Invalid max dimension size: " + maxSizeField.getText(), 1068 getTitle(), JOptionPane.ERROR_MESSAGE); 1069 return null; 1070 } 1071 } 1072 1073 if (l < -1) { 1074 toolkit.beep(); 1075 JOptionPane.showMessageDialog(this, "Dimension size cannot be less than -1.", getTitle(), 1076 JOptionPane.ERROR_MESSAGE); 1077 return null; 1078 } 1079 else if (l == 0) { 1080 l = dims[i]; 1081 } 1082 1083 maxdims[i] = l; 1084 } 1085 } 1086 1087 chunks = null; 1088 if (checkChunked.isSelected()) { 1089 st = new StringTokenizer(chunkSizeField.getText(), "x"); 1090 if (st.countTokens() < rank) { 1091 toolkit.beep(); 1092 JOptionPane.showMessageDialog(this, "Number of values in the chunk size is less than " + rank, 1093 getTitle(), JOptionPane.ERROR_MESSAGE); 1094 return null; 1095 } 1096 1097 l = 0; 1098 chunks = new long[rank]; 1099 for (int i = 0; i < rank; i++) { 1100 token = st.nextToken().trim(); 1101 try { 1102 l = Long.parseLong(token); 1103 } 1104 catch (NumberFormatException ex) { 1105 toolkit.beep(); 1106 JOptionPane.showMessageDialog(this, "Invalid chunk dimension size: " + chunkSizeField.getText(), 1107 getTitle(), JOptionPane.ERROR_MESSAGE); 1108 return null; 1109 } 1110 1111 if (l < 1) { 1112 toolkit.beep(); 1113 JOptionPane.showMessageDialog(this, "Chunk size cannot be less than 1.", getTitle(), 1114 JOptionPane.ERROR_MESSAGE); 1115 return null; 1116 } 1117 1118 chunks[i] = l; 1119 } // for (int i=0; i<rank; i++) 1120 1121 long tchunksize = 1, tdimsize = 1; 1122 for (int i = 0; i < rank; i++) { 1123 tchunksize *= chunks[i]; 1124 tdimsize *= dims[i]; 1125 } 1126 1127 if (tchunksize >= tdimsize) { 1128 toolkit.beep(); 1129 int status = JOptionPane.showConfirmDialog(this, "Chunk size is equal/greater than the current size. " 1130 + "\nAre you sure you want to set chunk size to " + chunkSizeField.getText() + "?", getTitle(), 1131 JOptionPane.YES_NO_OPTION); 1132 if (status == JOptionPane.NO_OPTION) { 1133 return null; 1134 } 1135 } 1136 1137 if (tchunksize == 1) { 1138 toolkit.beep(); 1139 int status = JOptionPane.showConfirmDialog(this, 1140 "Chunk size is one, which may cause large memory overhead for large dataset." 1141 + "\nAre you sure you want to set chunk size to " + chunkSizeField.getText() + "?", 1142 getTitle(), JOptionPane.YES_NO_OPTION); 1143 if (status == JOptionPane.NO_OPTION) { 1144 return null; 1145 } 1146 } 1147 1148 } // if (checkChunked.isSelected()) 1149 1150 if (checkCompression.isSelected()) { 1151 gzip = compressionLevel.getSelectedIndex(); 1152 } 1153 else { 1154 gzip = 0; 1155 } 1156 1157 HObject obj = null; 1158 try { 1159 Datatype basedatatype = null; 1160 if (isVLen) { 1161 basedatatype = fileFormat.createDatatype(tclass, tsize, torder, tsign); 1162 tclass = Datatype.CLASS_VLEN; 1163 } 1164 Datatype datatype = fileFormat.createDatatype(tclass, tsize, torder, tsign, basedatatype); 1165 if (tclass == Datatype.CLASS_ENUM) { 1166 datatype.setEnumMembers(stringLengthField.getText()); 1167 } 1168 String fillValue = null; 1169 if (fillValueField.isEnabled()) fillValue = fillValueField.getText(); 1170 1171 obj = fileFormat.createScalarDS(name, pgroup, datatype, dims, maxdims, chunks, gzip, fillValue, null); 1172 } 1173 catch (Exception ex) { 1174 toolkit.beep(); 1175 JOptionPane.showMessageDialog(this, ex, getTitle(), JOptionPane.ERROR_MESSAGE); 1176 return null; 1177 } 1178 1179 return obj; 1180 } 1181 1182 private HObject createFromTable() { 1183 HObject obj = null; 1184 1185 String name = null; 1186 Group pgroup = null; 1187 1188 name = nameField.getText(); 1189 if (name == null) { 1190 toolkit.beep(); 1191 JOptionPane 1192 .showMessageDialog(this, "Dataset name is not specified.", getTitle(), JOptionPane.ERROR_MESSAGE); 1193 return null; 1194 } 1195 1196 if (name.indexOf(HObject.separator) >= 0) { 1197 toolkit.beep(); 1198 JOptionPane.showMessageDialog(this, "Dataset name cannot contain path.", getTitle(), 1199 JOptionPane.ERROR_MESSAGE); 1200 return null; 1201 } 1202 1203 pgroup = (Group) groupList.get(parentChoice.getSelectedIndex()); 1204 if (pgroup == null) { 1205 toolkit.beep(); 1206 JOptionPane.showMessageDialog(this, "Parent group is null.", getTitle(), JOptionPane.ERROR_MESSAGE); 1207 return null; 1208 } 1209 1210 TableView tableView = (TableView) dataView; 1211 Object theData = tableView.getSelectedData(); 1212 if (theData == null) { 1213 return null; 1214 } 1215 1216 int w = tableView.getTable().getSelectedColumnCount(); 1217 int h = tableView.getTable().getSelectedRowCount(); 1218 Dataset dataset = (Dataset) tableView.getDataObject(); 1219 if (dataset instanceof ScalarDS) { 1220 ScalarDS sd = (ScalarDS) dataset; 1221 if (sd.isUnsigned()) { 1222 theData = Dataset.convertToUnsignedC(theData, null); 1223 } 1224 } 1225 1226 try { 1227 long[] dims = { h, w }; 1228 obj = dataset.copy(pgroup, name, dims, theData); 1229 } 1230 catch (Exception ex) { 1231 toolkit.beep(); 1232 JOptionPane.showMessageDialog(this, ex.getMessage(), getTitle(), JOptionPane.ERROR_MESSAGE); 1233 return null; 1234 } 1235 1236 return obj; 1237 } 1238 1239 private HObject createFromImage() { 1240 HObject obj = null; 1241 String name = null; 1242 Group pgroup = null; 1243 1244 name = nameField.getText(); 1245 if (name == null) { 1246 toolkit.beep(); 1247 JOptionPane 1248 .showMessageDialog(this, "Dataset name is not specified.", getTitle(), JOptionPane.ERROR_MESSAGE); 1249 return null; 1250 } 1251 1252 if (name.indexOf(HObject.separator) >= 0) { 1253 toolkit.beep(); 1254 JOptionPane.showMessageDialog(this, "Dataset name cannot contain path.", getTitle(), 1255 JOptionPane.ERROR_MESSAGE); 1256 return null; 1257 } 1258 1259 pgroup = (Group) groupList.get(parentChoice.getSelectedIndex()); 1260 if (pgroup == null) { 1261 toolkit.beep(); 1262 JOptionPane.showMessageDialog(this, "Parent group is null.", getTitle(), JOptionPane.ERROR_MESSAGE); 1263 return null; 1264 } 1265 1266 ImageView imageView = (ImageView) dataView; 1267 ScalarDS dataset = (ScalarDS) imageView.getDataObject(); 1268 Object theData = imageView.getSelectedData(); 1269 1270 if (theData == null) { 1271 return null; 1272 } 1273 1274 // in version 2.4, unsigned image data is converted to signed data 1275 // to write data, the data needs to converted back to unsigned. 1276 if (dataset.isUnsigned()) { 1277 theData = Dataset.convertToUnsignedC(theData, null); 1278 } 1279 1280 int w = imageView.getSelectedArea().width; 1281 int h = imageView.getSelectedArea().height; 1282 1283 try { 1284 long[] dims = null; 1285 if (isH5) { 1286 if (imageView.isTrueColor()) { 1287 dims = new long[3]; 1288 if (imageView.isPlaneInterlace()) { 1289 dims[0] = 3; 1290 dims[1] = h; 1291 dims[2] = w; 1292 } 1293 else { 1294 dims[0] = h; 1295 dims[1] = w; 1296 dims[2] = 3; 1297 } 1298 } 1299 else { 1300 dims = new long[2]; 1301 dims[0] = h; 1302 dims[1] = w; 1303 } 1304 } 1305 else { 1306 dims = new long[2]; 1307 dims[0] = w; 1308 dims[1] = h; 1309 } 1310 1311 obj = dataset.copy(pgroup, name, dims, theData); 1312 } 1313 catch (Exception ex) { 1314 toolkit.beep(); 1315 JOptionPane.showMessageDialog(this, ex.getMessage(), getTitle(), JOptionPane.ERROR_MESSAGE); 1316 return null; 1317 } 1318 1319 return obj; 1320 } 1321 1322 /** 1323 * Returns the new dataset created. 1324 * 1325 * @return The new Dataset created 1326 */ 1327 public DataFormat getObject() { 1328 return newObject; 1329 } 1330 1331 /** 1332 * Returns the parent group of the new dataset. 1333 * 1334 * @return The parent group of the new Dataset 1335 */ 1336 public Group getParentGroup() { 1337 return (Group) groupList.get(parentChoice.getSelectedIndex()); 1338 } 1339}