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