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.Dialog; 019import java.awt.Dimension; 020import java.awt.GridLayout; 021import java.awt.Point; 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.math.BigInteger; 028import java.net.URL; 029import java.net.URLClassLoader; 030import java.util.Enumeration; 031import java.util.StringTokenizer; 032 033import javax.swing.BorderFactory; 034import javax.swing.ButtonGroup; 035import javax.swing.JButton; 036import javax.swing.JCheckBox; 037import javax.swing.JComboBox; 038import javax.swing.JDialog; 039import javax.swing.JEditorPane; 040import javax.swing.JLabel; 041import javax.swing.JOptionPane; 042import javax.swing.JPanel; 043import javax.swing.JRadioButton; 044import javax.swing.JScrollPane; 045import javax.swing.JTextField; 046import javax.swing.event.HyperlinkEvent; 047import javax.swing.event.HyperlinkListener; 048import javax.swing.text.html.HTMLDocument; 049import javax.swing.text.html.HTMLFrameHyperlinkEvent; 050import javax.swing.tree.DefaultMutableTreeNode; 051 052import hdf.object.Attribute; 053import hdf.object.Datatype; 054import hdf.object.FileFormat; 055import hdf.object.Group; 056import hdf.object.HObject; 057 058/** 059 * NewAttributeDialog displays components for adding new attribute. 060 * 061 * @author Peter X. Cao 062 * @version 2.4 9/6/2007 063 */ 064public class NewAttributeDialog extends JDialog implements ActionListener, ItemListener, HyperlinkListener { 065 private static final long serialVersionUID = 4883237570834215275L; 066 067 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NewAttributeDialog.class); 068 069 /** the default length of a string attribute */ 070 public static final int DEFAULT_STRING_ATTRIBUTE_LENGTH = 256; 071 072 /** the object which the attribute to be attached to */ 073 private HObject hObject; 074 075 private Attribute newAttribute; 076 077 /** TextField for entering the name of the dataset */ 078 private JTextField nameField; 079 080 /** The Choice of the datatypes */ 081 @SuppressWarnings("rawtypes") 082 private JComboBox classChoice, sizeChoice; 083 084 private JCheckBox checkUnsigned; 085 086 /** TextField for entering the attribute value. */ 087 private JTextField valueField; 088 089 /** The Choice of the object list */ 090 @SuppressWarnings("rawtypes") 091 private JComboBox objChoice; 092 093 private FileFormat fileFormat; 094 095 /** TextField for entering the length of the data array or string. */ 096 private JTextField lengthField; 097 098 private JLabel arrayLengthLabel; 099 100 private final boolean isH5; 101 102 private JDialog helpDialog; 103 104 private JRadioButton h4GrAttrRadioButton; 105 106 /** 107 * Constructs NewAttributeDialog with specified object (dataset, group, or 108 * image) which the new attribute to be attached to. 109 * 110 * @param owner 111 * the owner of the input 112 * @param obj 113 * the object which the attribute to be attached to. 114 * @param objList 115 * the list of objects in the file 116 */ 117 @SuppressWarnings({ "rawtypes", "unchecked" }) 118 public NewAttributeDialog(Dialog owner, HObject obj, Enumeration<?> objList) { 119 super(owner, "New Attribute...", true); 120 121 hObject = obj; 122 newAttribute = null; 123 isH5 = obj.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5)); 124 helpDialog = null; 125 fileFormat = obj.getFileFormat(); 126 127 JPanel typeLabelPanel = new JPanel(); 128 typeLabelPanel.setLayout(new GridLayout(1, 4, 15, 3)); 129 JPanel typePanel = new JPanel(); 130 typePanel.setLayout(new GridLayout(1, 4, 15, 3)); 131 132 classChoice = new JComboBox(); 133 classChoice.setName("attrclass"); 134 sizeChoice = new JComboBox(); 135 sizeChoice.setName("attrsize"); 136 137 classChoice.addItem("INTEGER"); 138 classChoice.addItem("FLOAT"); 139 classChoice.addItem("CHAR"); 140 141 if (isH5) { 142 classChoice.addItem("STRING"); 143 classChoice.addItem("REFERENCE"); 144 classChoice.addItem("VLEN_INTEGER"); 145 classChoice.addItem("VLEN_FLOAT"); 146 classChoice.addItem("VLEN_STRING"); 147 } 148 sizeChoice.addItem("8"); 149 sizeChoice.addItem("16"); 150 sizeChoice.addItem("32"); 151 sizeChoice.addItem("64"); 152 153 typeLabelPanel.add(new JLabel("Datatype class")); 154 typeLabelPanel.add(new JLabel("Size (bits)")); 155 typeLabelPanel.add(new JLabel(" ")); 156 157 typePanel.add(classChoice); 158 typePanel.add(sizeChoice); 159 checkUnsigned = new JCheckBox("Unsigned"); 160 checkUnsigned.setName("attrchkunsigned"); 161 typePanel.add(checkUnsigned); 162 163 JPanel contentPane = (JPanel) getContentPane(); 164 contentPane.setLayout(new BorderLayout(5, 5)); 165 contentPane.setBorder(BorderFactory.createEmptyBorder(20, 10, 0, 10)); 166 int w = 500 + (ViewProperties.getFontSize() - 12) * 15; 167 int h = 220 + (ViewProperties.getFontSize() - 12) * 12; 168 contentPane.setPreferredSize(new Dimension(w, h)); 169 170 JButton okButton = new JButton(" Ok "); 171 okButton.setName("OK"); 172 okButton.setActionCommand("Ok"); 173 okButton.setMnemonic(KeyEvent.VK_O); 174 175 JButton cancelButton = new JButton("Cancel"); 176 cancelButton.setName("Cancel"); 177 cancelButton.setActionCommand("Cancel"); 178 cancelButton.setMnemonic(KeyEvent.VK_C); 179 180 JButton helpButton = new JButton(" Help "); 181 helpButton.setName("Help"); 182 helpButton.setActionCommand("Show help"); 183 helpButton.setMnemonic(KeyEvent.VK_H); 184 185 JPanel p = new JPanel(); 186 p.setLayout(new BorderLayout(5, 5)); 187 JPanel p2 = new JPanel(); 188 p2.setLayout(new GridLayout(6, 1, 3, 3)); 189 p2.add(new JLabel("Name: ")); 190 p2.add(new JLabel(" ")); 191 p2.add(new JLabel("Type: ")); 192 p2.add(arrayLengthLabel = new JLabel("Array Size: ")); 193 p2.add(new JLabel("Value: ")); 194 p2.add(new JLabel("Object List: ")); 195 p.add("West", p2); 196 197 JPanel typePane = new JPanel(); 198 typePane.setLayout(new BorderLayout()); 199 JPanel h4GattrPane = new JPanel(); 200 h4GattrPane.setLayout(new GridLayout(1, 2, 3, 3)); 201 ButtonGroup bg = new ButtonGroup(); 202 JRadioButton grAttr = new JRadioButton("GR"); 203 JRadioButton sdAttr = new JRadioButton("SD"); 204 bg.add(sdAttr); 205 bg.add(grAttr); 206 sdAttr.setSelected(true); 207 h4GattrPane.add(sdAttr); 208 h4GattrPane.add(grAttr); 209 typePane.add(typePanel, BorderLayout.CENTER); 210 typePane.add(h4GattrPane, BorderLayout.EAST); 211 h4GrAttrRadioButton = grAttr; 212 213 p2 = new JPanel(); 214 p2.setLayout(new GridLayout(6, 1, 3, 3)); 215 nameField = new JTextField("", 30); 216 nameField.setName("attrname"); 217 p2.add(nameField); 218 if (!isH5 && (obj instanceof Group) && ((Group) obj).isRoot()) { 219 p2.add(typePane); 220 } 221 else { 222 p2.add(typeLabelPanel); 223 p2.add(typePanel); 224 } 225 lengthField = new JTextField("1"); 226 lengthField.setName("attrlength"); 227 p2.add(lengthField); 228 valueField = new JTextField("0"); 229 valueField.setName("attrvalue"); 230 p2.add(valueField); 231 objChoice = new JComboBox(); 232 objChoice.setName("attrobjn"); 233 p2.add(objChoice); 234 p.add("Center", p2); 235 236 contentPane.add("Center", p); 237 238 p = new JPanel(); 239 p.add(okButton); 240 p.add(cancelButton); 241 p.add(helpButton); 242 contentPane.add("South", p); 243 244 classChoice.addItemListener(this); 245 sizeChoice.addItemListener(this); 246 247 okButton.addActionListener(this); 248 cancelButton.addActionListener(this); 249 helpButton.addActionListener(this); 250 objChoice.addItemListener(this); 251 objChoice.setEnabled(false); 252 253 String str; 254 HObject hobj; 255 DefaultMutableTreeNode theNode; 256 while (objList.hasMoreElements()) { 257 theNode = (DefaultMutableTreeNode) objList.nextElement(); 258 hobj = (HObject) theNode.getUserObject(); 259 if (hobj instanceof Group) { 260 if (((Group) hobj).isRoot()) continue; 261 } 262 str = hobj.getFullName(); 263 objChoice.addItem(str); 264 } 265 266 Point l = owner.getLocation(); 267 l.x += 50; 268 l.y += 80; 269 setLocation(l); 270 pack(); 271 } 272 273 public void actionPerformed(ActionEvent e) { 274 String cmd = e.getActionCommand(); 275 276 if (cmd.equals("Ok")) { 277 if (createAttribute()) { 278 dispose(); 279 } 280 } 281 else if (cmd.equals("Cancel")) { 282 newAttribute = null; 283 dispose(); 284 } 285 else if (cmd.equals("Show help")) { 286 if (helpDialog == null) { 287 createHelpDialog(); 288 } 289 helpDialog.setVisible(true); 290 } 291 else if (cmd.equals("Hide help")) { 292 if (helpDialog != null) { 293 helpDialog.setVisible(false); 294 } 295 } 296 } 297 298 @SuppressWarnings("unchecked") 299 public void itemStateChanged(ItemEvent e) { 300 Object source = e.getSource(); 301 302 if (source.equals(classChoice)) { 303 int idx = classChoice.getSelectedIndex(); 304 sizeChoice.setSelectedIndex(0); 305 objChoice.setEnabled(false); 306 lengthField.setEnabled(true); 307 308 if ((idx == 0) || (idx == 5)) { 309 sizeChoice.setEnabled(true); 310 checkUnsigned.setEnabled(true); 311 arrayLengthLabel.setText("Array Size: "); 312 313 if (sizeChoice.getItemCount() == 2) { 314 sizeChoice.removeItem("32"); 315 sizeChoice.removeItem("64"); 316 sizeChoice.addItem("8"); 317 sizeChoice.addItem("16"); 318 sizeChoice.addItem("32"); 319 sizeChoice.addItem("64"); 320 } 321 } 322 else if ((idx == 1) || (idx == 6)) { 323 sizeChoice.setEnabled(true); 324 checkUnsigned.setEnabled(false); 325 arrayLengthLabel.setText("Array Size: "); 326 327 if (sizeChoice.getItemCount() == 4) { 328 sizeChoice.removeItem("16"); 329 sizeChoice.removeItem("8"); 330 } 331 } 332 else if (idx == 2) { 333 sizeChoice.setEnabled(false); 334 checkUnsigned.setEnabled(true); 335 arrayLengthLabel.setText("Array Size: "); 336 } 337 else if (idx == 3) { 338 sizeChoice.setEnabled(false); 339 checkUnsigned.setEnabled(false); 340 arrayLengthLabel.setText("String Length: "); 341 } 342 else if (idx == 4) { 343 sizeChoice.setEnabled(false); 344 checkUnsigned.setEnabled(false); 345 lengthField.setText("1"); 346 lengthField.setEnabled(false); 347 arrayLengthLabel.setText("Array Size: "); 348 objChoice.setEnabled(true); 349 valueField.setText(""); 350 } 351 else if (idx == 7) { 352 sizeChoice.setEnabled(false); 353 checkUnsigned.setEnabled(false); 354 lengthField.setEnabled(false); 355 } 356 } 357 else if (source.equals(sizeChoice)) { 358 if (classChoice.getSelectedIndex() == 0) { 359 checkUnsigned.setEnabled(true); 360 } 361 } 362 else if (source.equals(objChoice)) { 363 String objName = (String) objChoice.getSelectedItem(); 364 365 if (e.getStateChange() != ItemEvent.SELECTED) return; 366 367 long ref = -1; 368 try { 369 HObject obj = fileFormat.get(objName); 370 ref = obj.getOID()[0]; 371 } 372 catch (Exception ex) { 373 log.debug("object id:", ex); 374 } 375 376 if (ref > 0) { 377 if (valueField.getText().length() > 1) { 378 valueField.setText(valueField.getText() + "," + ref); 379 StringTokenizer st = new StringTokenizer(valueField.getText(), ","); 380 lengthField.setText(String.valueOf(st.countTokens())); 381 } 382 else { 383 valueField.setText(String.valueOf(ref)); 384 lengthField.setText("1"); 385 } 386 } 387 } 388 } 389 390 @SuppressWarnings("unchecked") 391 private boolean createAttribute() { 392 int string_length = 0; 393 int tclass = -1, tsize = -1, torder = -1, tsign = -1; 394 boolean isVLen = false; 395 log.trace("createAttribute start"); 396 397 Object value = null; 398 String strValue = valueField.getText(); 399 400 String attrName = nameField.getText(); 401 if (attrName != null) { 402 attrName = attrName.trim(); 403 } 404 405 if ((attrName == null) || (attrName.length() < 1)) { 406 JOptionPane.showMessageDialog(this, "No attribute name.", getTitle(), JOptionPane.ERROR_MESSAGE); 407 return false; 408 } 409 410 String lengthStr = lengthField.getText(); 411 log.trace("Name is {} : Length={} and Value={}", attrName, lengthStr, strValue); 412 413 int arraySize = 0; 414 if ((lengthStr == null) || (lengthStr.length() <= 0)) { 415 arraySize = 1; 416 } 417 else { 418 try { 419 arraySize = Integer.parseInt(lengthStr); 420 } 421 catch (Exception e) { 422 arraySize = -1; 423 } 424 } 425 426 if (arraySize <= 0) { 427 JOptionPane.showMessageDialog(this, "Invalid attribute length.", getTitle(), JOptionPane.ERROR_MESSAGE); 428 return false; 429 } 430 431 StringTokenizer st = new StringTokenizer(strValue, ","); 432 int count = Math.min(arraySize, st.countTokens()); 433 String theToken; 434 log.trace("Count of Values is {}", count); 435 436 // set datatype class 437 int idx = classChoice.getSelectedIndex(); 438 if (idx == 0) { 439 tclass = Datatype.CLASS_INTEGER; 440 if (checkUnsigned.isSelected()) { 441 tsign = Datatype.SIGN_NONE; 442 } 443 torder = Datatype.NATIVE; 444 } 445 else if (idx == 1) { 446 tclass = Datatype.CLASS_FLOAT; 447 torder = Datatype.NATIVE; 448 } 449 else if (idx == 2) { 450 tclass = Datatype.CLASS_CHAR; 451 if (checkUnsigned.isSelected()) { 452 tsign = Datatype.SIGN_NONE; 453 } 454 torder = Datatype.NATIVE; 455 } 456 else if (idx == 3) { 457 tclass = Datatype.CLASS_STRING; 458 } 459 else if (idx == 4) { 460 tclass = Datatype.CLASS_REFERENCE; 461 } 462 else if (idx == 5) {; 463 isVLen = true; 464 tclass = Datatype.CLASS_INTEGER; 465 if (checkUnsigned.isSelected()) { 466 tsign = Datatype.SIGN_NONE; 467 } 468 torder = Datatype.NATIVE; 469 JOptionPane.showMessageDialog(this, "Multi-dimensional Variable Length Integer Attributes will be created without data", getTitle(), JOptionPane.WARNING_MESSAGE); 470 } 471 else if (idx == 6) {; 472 isVLen = true; 473 tclass = Datatype.CLASS_FLOAT; 474 torder = Datatype.NATIVE; 475 JOptionPane.showMessageDialog(this, "Multi-dimensional Variable Length Float Attributes will be created without data", getTitle(), JOptionPane.WARNING_MESSAGE); 476 } 477 else if (idx == 7) { 478 isVLen = true; 479 tclass = Datatype.CLASS_STRING; 480 } 481 log.trace("Attribute: isVLen={} and tclass={} and torder={} and tsign={}", isVLen, tclass, torder, tsign); 482 483 // set datatype size/order 484 idx = sizeChoice.getSelectedIndex(); 485 if (isVLen) { 486 tsize = -1; 487 log.trace("Attribute isVLen={} and tsize={}", isVLen, tsize); 488 String[] strArray = { strValue }; 489 value = strArray; 490 if (tclass == Datatype.CLASS_INTEGER) { 491 switch(idx) { 492 case 0: 493 tsize = 1; 494 break; 495 case 1: 496 tsize = 2; 497 break; 498 case 2: 499 tsize = 4; 500 break; 501 case 3: 502 tsize = 8; 503 break; 504 } 505 log.trace("Attribute VL-CLASS_INTEGER: tsize={}", tsize); 506 } 507 else if (tclass == Datatype.CLASS_FLOAT) { 508 tsize = (idx + 1) * 4; 509 log.trace("Attribute VL-CLASS_FLOAT: tsize={}", tsize); 510 } 511 } 512 else { 513 if (tclass == Datatype.CLASS_STRING) { 514 int stringLength = 0; 515 try { 516 stringLength = Integer.parseInt(lengthField.getText()); 517 } 518 catch (NumberFormatException ex) { 519 stringLength = -1; 520 } 521 522 if (stringLength <= 0) { 523 stringLength = DEFAULT_STRING_ATTRIBUTE_LENGTH; 524 } 525 if (strValue.length() > stringLength) { 526 strValue = strValue.substring(0, stringLength); 527 } 528 529 tsize = stringLength; 530 531 String[] strArray = { strValue }; 532 value = strArray; 533 534 if (isH5) { 535 arraySize = 1; // support string type 536 } 537 else { 538 arraySize = stringLength; // array of characters 539 } 540 log.trace("Attribute CLASS_STRING: isVLen={} and tsize={} and arraySize={}", isVLen, tsize, arraySize); 541 } 542 else if (tclass == Datatype.CLASS_REFERENCE) { 543 tsize = 1; 544 arraySize = st.countTokens(); 545 long[] ref = new long[arraySize]; 546 for (int j = 0; j < arraySize; j++) { 547 theToken = st.nextToken().trim(); 548 try { 549 ref[j] = Long.parseLong(theToken); 550 } 551 catch (NumberFormatException ex) { 552 JOptionPane.showMessageDialog(this, ex.getMessage(), getTitle(), JOptionPane.ERROR_MESSAGE); 553 return false; 554 } 555 } 556 557 value = ref; 558 torder = Datatype.NATIVE; 559 log.trace("Attribute CLASS_REFERENCE: tsize={} and arraySize={}", tsize, arraySize); 560 } 561 else if (tclass == Datatype.CLASS_INTEGER) { 562 switch(idx) { 563 case 0: 564 tsize = 1; 565 break; 566 case 1: 567 tsize = 2; 568 break; 569 case 2: 570 tsize = 4; 571 break; 572 case 3: 573 tsize = 8; 574 break; 575 } 576 log.trace("Attribute CLASS_INTEGER: tsize={}", tsize); 577 } 578 else if (tclass == Datatype.CLASS_FLOAT) { 579 tsize = (idx + 1) * 4; 580 log.trace("Attribute CLASS_FLOAT: tsize={}", tsize); 581 } 582 else { 583 tsize = 1 << (idx); 584 log.trace("Attribute other: tsize={}", tsize); 585 } 586 587 if ((tsize == 8) && !isH5 && (tclass == Datatype.CLASS_INTEGER)) { 588 JOptionPane.showMessageDialog(this, 589 "HDF4 does not support 64-bit integer.", 590 getTitle(), 591 JOptionPane.ERROR_MESSAGE); 592 return false; 593 } 594 595 if (tclass == Datatype.CLASS_INTEGER) { 596 if (tsign == Datatype.SIGN_NONE) { 597 if (tsize == 1) { 598 byte[] b = new byte[arraySize]; 599 short sv = 0; 600 for (int j = 0; j < count; j++) { 601 theToken = st.nextToken().trim(); 602 try { 603 sv = Short.parseShort(theToken); 604 } 605 catch (NumberFormatException ex) { 606 JOptionPane.showMessageDialog(this, ex.getMessage(), getTitle(), JOptionPane.ERROR_MESSAGE); 607 return false; 608 } 609 if (sv < 0) { 610 sv = 0; 611 } 612 else if (sv > 255) { 613 sv = 255; 614 } 615 b[j] = (byte) sv; 616 } 617 value = b; 618 } 619 else if (tsize == 2) { 620 short[] s = new short[arraySize]; 621 int iv = 0; 622 for (int j = 0; j < count; j++) { 623 theToken = st.nextToken().trim(); 624 try { 625 iv = Integer.parseInt(theToken); 626 } 627 catch (NumberFormatException ex) { 628 JOptionPane.showMessageDialog(this, ex.getMessage(), getTitle(), JOptionPane.ERROR_MESSAGE); 629 return false; 630 } 631 if (iv < 0) { 632 iv = 0; 633 } 634 else if (iv > 65535) { 635 iv = 65535; 636 } 637 s[j] = (short) iv; 638 } 639 value = s; 640 } 641 else if (tsize == 4) { 642 int[] i = new int[arraySize]; 643 long lv = 0; 644 for (int j = 0; j < count; j++) { 645 theToken = st.nextToken().trim(); 646 try { 647 lv = Long.parseLong(theToken); 648 } 649 catch (NumberFormatException ex) { 650 JOptionPane.showMessageDialog(this, ex.getMessage(), getTitle(), JOptionPane.ERROR_MESSAGE); 651 return false; 652 } 653 if (lv < 0) { 654 lv = 0; 655 } 656 if (lv > 4294967295L) { 657 lv = 4294967295L; 658 } 659 i[j] = (int) lv; 660 } 661 value = i; 662 } 663 else if (tsize == 8) { 664 long[] i = new long[arraySize]; 665 BigInteger lv = BigInteger.valueOf(0); 666 for (int j = 0; j < count; j++) { 667 theToken = st.nextToken().trim(); 668 try { 669 lv = new BigInteger(theToken); 670 } 671 catch (NumberFormatException ex) { 672 JOptionPane.showMessageDialog(this, ex.getMessage(), getTitle(), JOptionPane.ERROR_MESSAGE); 673 return false; 674 } 675 i[j] = (long) lv.longValue(); 676 } 677 value = i; 678 } 679 } 680 else { 681 if (tsize == 1) { 682 byte[] b = new byte[arraySize]; 683 for (int j = 0; j < count; j++) { 684 theToken = st.nextToken().trim(); 685 try { 686 b[j] = Byte.parseByte(theToken); 687 } 688 catch (NumberFormatException ex) { 689 JOptionPane.showMessageDialog(this, ex.getMessage(), getTitle(), JOptionPane.ERROR_MESSAGE); 690 return false; 691 } 692 } 693 value = b; 694 } 695 else if (tsize == 2) { 696 short[] s = new short[arraySize]; 697 698 for (int j = 0; j < count; j++) { 699 theToken = st.nextToken().trim(); 700 try { 701 s[j] = Short.parseShort(theToken); 702 } 703 catch (NumberFormatException ex) { 704 JOptionPane.showMessageDialog(this, ex.getMessage(), getTitle(), JOptionPane.ERROR_MESSAGE); 705 return false; 706 } 707 } 708 value = s; 709 } 710 else if (tsize == 4) { 711 int[] i = new int[arraySize]; 712 713 for (int j = 0; j < count; j++) { 714 theToken = st.nextToken().trim(); 715 try { 716 i[j] = Integer.parseInt(theToken); 717 } 718 catch (NumberFormatException ex) { 719 JOptionPane.showMessageDialog(this, ex.getMessage(), getTitle(), JOptionPane.ERROR_MESSAGE); 720 return false; 721 } 722 } 723 value = i; 724 } 725 else if (tsize == 8) { 726 long[] l = new long[arraySize]; 727 for (int j = 0; j < count; j++) { 728 theToken = st.nextToken().trim(); 729 try { 730 l[j] = Long.parseLong(theToken); 731 } 732 catch (NumberFormatException ex) { 733 JOptionPane.showMessageDialog(this, ex.getMessage(), getTitle(), JOptionPane.ERROR_MESSAGE); 734 return false; 735 } 736 } 737 value = l; 738 } 739 } 740 } 741 742 if (tclass == Datatype.CLASS_FLOAT) { 743 if (tsize == 4) { 744 float[] f = new float[arraySize]; 745 for (int j = 0; j < count; j++) { 746 theToken = st.nextToken().trim(); 747 try { 748 f[j] = Float.parseFloat(theToken); 749 } 750 catch (NumberFormatException ex) { 751 JOptionPane.showMessageDialog(this, ex.getMessage(), getTitle(), JOptionPane.ERROR_MESSAGE); 752 return false; 753 } 754 if (Float.isInfinite(f[j]) || Float.isNaN(f[j])) { 755 f[j] = 0; 756 } 757 } 758 value = f; 759 } 760 else if (tsize == 8) { 761 double[] d = new double[arraySize]; 762 for (int j = 0; j < count; j++) { 763 theToken = st.nextToken().trim(); 764 try { 765 d[j] = Double.parseDouble(theToken); 766 } 767 catch (NumberFormatException ex) { 768 JOptionPane.showMessageDialog(this, ex.getMessage(), getTitle(), JOptionPane.ERROR_MESSAGE); 769 return false; 770 } 771 if (Double.isInfinite(d[j]) || Double.isNaN(d[j])) { 772 d[j] = 0; 773 } 774 } 775 value = d; 776 } 777 } 778 } 779 780 Datatype datatype = null; 781 try { 782 Datatype basedatatype = null; 783 if (isVLen) { 784 basedatatype = fileFormat.createDatatype(tclass, tsize, torder, tsign); 785 tclass = Datatype.CLASS_VLEN; 786 log.trace("Attribute CLASS_VLEN"); 787 } 788 datatype = fileFormat.createDatatype(tclass, tsize, torder, tsign, basedatatype); 789 } 790 catch (Exception ex) { 791 JOptionPane.showMessageDialog(this, ex.getMessage(), getTitle(), JOptionPane.ERROR_MESSAGE); 792 return false; 793 } 794 795 long[] dims = { arraySize }; 796 Attribute attr = new Attribute(attrName, datatype, dims); 797 attr.setValue(value); 798 799 try { 800 if (!isH5 && (hObject instanceof Group) && ((Group) hObject).isRoot() && h4GrAttrRadioButton.isSelected()) { 801 // don't find a good way to write HDF4 global 802 // attribute. Use the isExisted to separate the 803 // global attribute is GR or SD 804 hObject.getFileFormat().writeAttribute(hObject, attr, false); 805 if (hObject.getMetadata() == null) { 806 hObject.getMetadata().add(attr); 807 } 808 } 809 else { 810 log.trace("writeMetadata()"); 811 hObject.writeMetadata(attr); 812 } 813 } 814 catch (Exception ex) { 815 JOptionPane.showMessageDialog(this, ex.getMessage(), getTitle(), JOptionPane.ERROR_MESSAGE); 816 return false; 817 } 818 819 newAttribute = attr; 820 821 log.trace("createAttribute finish"); 822 return true; 823 } 824 825 /** Creates a dialog to show the help information. */ 826 private void createHelpDialog() { 827 helpDialog = new JDialog(this, "Creation New Attribute"); 828 829 JPanel contentPane = (JPanel) helpDialog.getContentPane(); 830 contentPane.setLayout(new BorderLayout(5, 5)); 831 contentPane.setBorder(BorderFactory.createEmptyBorder(15, 5, 5, 5)); 832 int w = 500 + (ViewProperties.getFontSize() - 12) * 15; 833 int h = 400 + (ViewProperties.getFontSize() - 12) * 10; 834 contentPane.setPreferredSize(new Dimension(w, h)); 835 836 JButton b = new JButton(" Ok "); 837 b.addActionListener(this); 838 b.setActionCommand("Hide help"); 839 JPanel tmpP = new JPanel(); 840 tmpP.add(b); 841 contentPane.add(tmpP, BorderLayout.SOUTH); 842 843 JEditorPane infoPane = new JEditorPane(); 844 infoPane.setEditable(false); 845 JScrollPane editorScrollPane = new JScrollPane(infoPane); 846 contentPane.add(editorScrollPane, BorderLayout.CENTER); 847 848 try { 849 URL url = null, url2 = null, url3 = null; 850 String rootPath = ViewProperties.getViewRoot(); 851 852 try { 853 url = new URL("file:" + rootPath + "/lib/jhdfview.jar"); 854 } 855 catch (java.net.MalformedURLException mfu) { 856 log.debug("help information:", mfu); 857 } 858 859 try { 860 url2 = new URL("file:" + rootPath + "/"); 861 } 862 catch (java.net.MalformedURLException mfu) { 863 log.debug("help information:", mfu); 864 } 865 866 try { 867 url3 = new URL("file:" + rootPath + "/src/"); 868 } 869 catch (java.net.MalformedURLException mfu) { 870 log.debug("help information:", mfu); 871 } 872 873 URL uu[] = { url, url2, url3 }; 874 URLClassLoader cl = new URLClassLoader(uu); 875 URL u = cl.findResource("hdf/view/NewAttrHelp.html"); 876 877 if (u == null) { 878 u = ClassLoader.getSystemResource("hdf/view/NewAttrHelp.html"); 879 } 880 881 cl.close(); 882 infoPane.setPage(u); 883 infoPane.addHyperlinkListener(this); 884 } 885 catch (Exception e) { 886 infoPane.setContentType("text/html"); 887 StringBuffer buff = new StringBuffer(); 888 buff.append("<html>"); 889 buff.append("<body>"); 890 buff.append("ERROR: cannot load help information."); 891 buff.append("</body>"); 892 buff.append("</html>"); 893 infoPane.setText(buff.toString()); 894 } 895 896 Point l = helpDialog.getOwner().getLocation(); 897 l.x += 50; 898 l.y += 80; 899 helpDialog.setLocation(l); 900 helpDialog.validate(); 901 helpDialog.pack(); 902 } 903 904 public void hyperlinkUpdate(HyperlinkEvent e) { 905 if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { 906 JEditorPane pane = (JEditorPane) e.getSource(); 907 908 if (e instanceof HTMLFrameHyperlinkEvent) { 909 HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent) e; 910 HTMLDocument doc = (HTMLDocument) pane.getDocument(); 911 doc.processHTMLFrameHyperlinkEvent(evt); 912 } 913 else { 914 try { 915 pane.setPage(e.getURL()); 916 } 917 catch (Throwable t) { 918 log.debug("JEditorPane hyper link:", t); 919 } 920 } 921 } 922 } 923 924 /** 925 * Returns the new attribute created. 926 * 927 * @return The new Attribute created 928 */ 929 public Attribute getAttribute() { 930 return newAttribute; 931 } 932}