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