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