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.util.Hashtable; 028import java.util.Iterator; 029import java.util.List; 030import java.util.StringTokenizer; 031import java.util.Vector; 032 033import javax.swing.BorderFactory; 034import javax.swing.ButtonGroup; 035import javax.swing.DefaultCellEditor; 036import javax.swing.JButton; 037import javax.swing.JCheckBox; 038import javax.swing.JComboBox; 039import javax.swing.JDialog; 040import javax.swing.JFrame; 041import javax.swing.JLabel; 042import javax.swing.JOptionPane; 043import javax.swing.JPanel; 044import javax.swing.JRadioButton; 045import javax.swing.JScrollPane; 046import javax.swing.JTable; 047import javax.swing.JTextField; 048import javax.swing.border.TitledBorder; 049import javax.swing.table.DefaultTableModel; 050import javax.swing.table.TableCellEditor; 051 052import hdf.object.CompoundDS; 053import hdf.object.DataFormat; 054import hdf.object.Dataset; 055import hdf.object.Datatype; 056import hdf.object.FileFormat; 057import hdf.object.Group; 058import hdf.object.HObject; 059 060/** 061 * NewTableDataDialog shows a message dialog requesting user input for creating 062 * a new HDF4/5 dataset. 063 * 064 * @author Peter X. Cao 065 * @version 2.4 9/6/2007 066 */ 067public class NewTableDataDialog extends JDialog implements ActionListener, ItemListener { 068 private static final long serialVersionUID = -6786877503226330821L; 069 070 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NewTableDataDialog.class); 071 072 private static final String[] DATATYPE_NAMES = { 073 "byte (8-bit)", // 0 074 "short (16-bit)", // 1 075 "int (32-bit)", // 2 076 "unsigned byte (8-bit)", // 3 077 "unsigned short (16-bit)", // 4 078 "unsigned int (32-bit)", // 5 079 "long (64-bit)", // 6 080 "float", // 7 081 "double", // 8 082 "string", // 9 083 "enum", // 10 084 "unsigned long (64-bit)" // 11 085 }; 086 087 private FileFormat fileformat; 088 089 @SuppressWarnings("rawtypes") 090 private JComboBox parentChoice, nFieldBox, templateChoice; 091 092 /** a list of current groups */ 093 private Vector<Object> groupList, compoundDSList; 094 095 private HObject newObject; 096 097 private final Toolkit toolkit; 098 099 private int numberOfMembers; 100 101 private JTable table; 102 103 private DefaultTableModel tableModel; 104 105 private RowEditorModel rowEditorModel; 106 107 private DefaultCellEditor cellEditor; 108 109 private JTextField nameField, currentSizeField, maxSizeField, chunkSizeField; 110 @SuppressWarnings("rawtypes") 111 private JComboBox compressionLevel, rankChoice, memberTypeChoice; 112 private JCheckBox checkCompression; 113 private JRadioButton checkContinguous, checkChunked; 114 115 /** 116 * Constructs NewTableDataDialog with specified list of possible parent 117 * groups. 118 * 119 * @param owner 120 * the owner of the input 121 * @param pGroup 122 * the parent group which the new group is added to. 123 * @param objs 124 * the list of all objects. 125 */ 126 @SuppressWarnings({ "unchecked", "rawtypes" }) 127 public NewTableDataDialog(JFrame owner, Group pGroup, List<?> objs) { 128 super(owner, "New Compound Dataset...", true); 129 130 newObject = null; 131 numberOfMembers = 2; 132 fileformat = pGroup.getFileFormat(); 133 134 memberTypeChoice = new JComboBox(DATATYPE_NAMES); 135 cellEditor = new DefaultCellEditor(memberTypeChoice); 136 rowEditorModel = new RowEditorModel(numberOfMembers, cellEditor); 137 String[] colNames = { "Name", "Datatype", "Array size / String length / Enum names" }; 138 tableModel = new DefaultTableModel(colNames, numberOfMembers); 139 table = new JTable(tableModel) { 140 private static final long serialVersionUID = 7141605060652738476L; 141 RowEditorModel rm = rowEditorModel; 142 143 @Override 144 public TableCellEditor getCellEditor(int row, int col) { 145 TableCellEditor cellEditor = rm.getEditor(row); 146 147 if ((cellEditor == null) || !(col == 1)) { 148 cellEditor = super.getCellEditor(row, col); 149 } 150 151 return cellEditor; 152 } 153 }; 154 table.setName("CompoundDataset"); 155 table.setRowSelectionAllowed(false); 156 table.setColumnSelectionAllowed(false); 157 158 // set cell height for large fonts 159 int cellRowHeight = Math.max(16, table.getFontMetrics(table.getFont()).getHeight()); 160 table.setRowHeight(cellRowHeight); 161 162 toolkit = Toolkit.getDefaultToolkit(); 163 164 parentChoice = new JComboBox(); 165 String[] memberSizes = new String[100]; 166 for (int i = 0; i < 100; i++) { 167 memberSizes[i] = String.valueOf(i + 1); 168 } 169 170 nFieldBox = new JComboBox(memberSizes); 171 nFieldBox.setName("numbermembers"); 172 nFieldBox.setEditable(true); 173 nFieldBox.addActionListener(this); 174 nFieldBox.setActionCommand("Change number of members"); 175 nFieldBox.setSelectedItem(String.valueOf(numberOfMembers)); 176 177 groupList = new Vector<Object>(objs.size()); 178 Object obj = null; 179 Iterator<?> iterator = objs.iterator(); 180 181 compoundDSList = new Vector<Object>(objs.size()); 182 183 while (iterator.hasNext()) { 184 obj = iterator.next(); 185 if (obj instanceof Group) { 186 Group g = (Group) obj; 187 groupList.add(obj); 188 if (g.isRoot()) { 189 parentChoice.addItem(HObject.separator); 190 } 191 else { 192 parentChoice.addItem(g.getPath() + g.getName() + HObject.separator); 193 } 194 } 195 else if (obj instanceof CompoundDS) { 196 compoundDSList.add(obj); 197 } 198 } 199 200 templateChoice = new JComboBox(compoundDSList); 201 templateChoice.setName("templateChoice"); 202 templateChoice.setSelectedIndex(-1); 203 templateChoice.addItemListener(this); 204 205 if (pGroup.isRoot()) { 206 parentChoice.setSelectedItem(HObject.separator); 207 } 208 else { 209 parentChoice.setSelectedItem(pGroup.getPath() + pGroup.getName() + HObject.separator); 210 } 211 212 JPanel contentPane = (JPanel) getContentPane(); 213 contentPane.setLayout(new BorderLayout(5, 5)); 214 contentPane.setBorder(BorderFactory.createEmptyBorder(15, 5, 5, 5)); 215 int w = 700 + (ViewProperties.getFontSize() - 12) * 15; 216 int h = 500 + (ViewProperties.getFontSize() - 12) * 10; 217 contentPane.setPreferredSize(new Dimension(w, h)); 218 219 JButton okButton = new JButton(" Ok "); 220 okButton.setName("OK"); 221 okButton.setActionCommand("Ok"); 222 okButton.setMnemonic(KeyEvent.VK_O); 223 okButton.addActionListener(this); 224 225 JButton cancelButton = new JButton("Cancel"); 226 cancelButton.setName("Cancel"); 227 cancelButton.setMnemonic(KeyEvent.VK_C); 228 cancelButton.setActionCommand("Cancel"); 229 cancelButton.addActionListener(this); 230 231 // set NAME and PARENT GROUP panel 232 JPanel namePanel = new JPanel(); 233 namePanel.setLayout(new BorderLayout(5, 5)); 234 JPanel tmpP = new JPanel(); 235 tmpP.setLayout(new GridLayout(3, 1)); 236 tmpP.add(new JLabel(" Dataset name: ")); 237 tmpP.add(new JLabel(" Parent group: ")); 238 tmpP.add(new JLabel("Import template: ")); 239 namePanel.add(tmpP, BorderLayout.WEST); 240 tmpP = new JPanel(); 241 tmpP.setLayout(new GridLayout(3, 1)); 242 tmpP.add(nameField = new JTextField()); 243 nameField.setName("datasetname"); 244 tmpP.add(parentChoice); 245 tmpP.add(templateChoice); 246 namePanel.add(tmpP, BorderLayout.CENTER); 247 248 // set DATATSPACE 249 JPanel spacePanel = new JPanel(); 250 spacePanel.setLayout(new GridLayout(2, 3, 15, 3)); 251 TitledBorder border = new TitledBorder("Dataspace"); 252 border.setTitleColor(Color.blue); 253 spacePanel.setBorder(border); 254 255 rankChoice = new JComboBox(); 256 for (int i = 1; i < 33; i++) { 257 rankChoice.addItem(String.valueOf(i)); 258 } 259 rankChoice.setSelectedIndex(0); 260 261 currentSizeField = new JTextField("1"); 262 maxSizeField = new JTextField("0"); 263 spacePanel.add(new JLabel("No. of dimensions")); 264 spacePanel.add(new JLabel("Current size")); 265 spacePanel.add(new JLabel("Max size (-1 for unlimited)")); 266 spacePanel.add(rankChoice); 267 spacePanel.add(currentSizeField); 268 spacePanel.add(maxSizeField); 269 270 // set storage layout and data compression 271 JPanel layoutPanel = new JPanel(); 272 layoutPanel.setLayout(new BorderLayout()); 273 border = new TitledBorder("Data Layout and Compression"); 274 border.setTitleColor(Color.BLUE); 275 layoutPanel.setBorder(border); 276 277 checkContinguous = new JRadioButton("Contiguous"); 278 checkContinguous.setSelected(true); 279 checkChunked = new JRadioButton("Chunked"); 280 ButtonGroup bgroup = new ButtonGroup(); 281 bgroup.add(checkChunked); 282 bgroup.add(checkContinguous); 283 chunkSizeField = new JTextField("1"); 284 chunkSizeField.setEnabled(false); 285 checkCompression = new JCheckBox("gzip"); 286 287 compressionLevel = new JComboBox(); 288 for (int i = 0; i < 10; i++) { 289 compressionLevel.addItem(String.valueOf(i)); 290 } 291 compressionLevel.setSelectedIndex(6); 292 compressionLevel.setEnabled(false); 293 294 tmpP = new JPanel(); 295 tmpP.setLayout(new GridLayout(2, 1)); 296 tmpP.add(new JLabel("Storage layout: ")); 297 tmpP.add(new JLabel("Compression: ")); 298 layoutPanel.add(tmpP, BorderLayout.WEST); 299 300 tmpP = new JPanel(); 301 tmpP.setLayout(new GridLayout(2, 1)); 302 303 JPanel tmpP0 = new JPanel(); 304 tmpP0.setLayout(new GridLayout(1, 2)); 305 tmpP0.add(checkContinguous); 306 307 JPanel tmpP00 = new JPanel(); 308 tmpP00.setLayout(new GridLayout(1, 3)); 309 tmpP00.add(checkChunked); 310 tmpP00.add(new JLabel(" Size: ")); 311 tmpP00.add(chunkSizeField); 312 tmpP0.add(tmpP00); 313 314 tmpP.add(tmpP0); 315 316 tmpP0 = new JPanel(); 317 tmpP0.setLayout(new GridLayout(1, 7)); 318 tmpP0.add(checkCompression); 319 tmpP0.add(new JLabel(" Level: ")); 320 tmpP0.add(compressionLevel); 321 tmpP0.add(new JLabel("")); 322 tmpP0.add(new JLabel("")); 323 tmpP0.add(new JLabel("")); 324 tmpP0.add(new JLabel("")); 325 tmpP.add(tmpP0); 326 327 layoutPanel.add(tmpP, BorderLayout.CENTER); 328 329 // add name, space and layout panels 330 tmpP = new JPanel(); 331 tmpP.setLayout(new BorderLayout(5, 5)); 332 tmpP.add(namePanel, BorderLayout.NORTH); 333 tmpP.add(spacePanel, BorderLayout.CENTER); 334 tmpP.add(layoutPanel, BorderLayout.SOUTH); 335 336 contentPane.add(tmpP, BorderLayout.NORTH); 337 338 // add field table 339 tmpP = new JPanel(); 340 tmpP.setLayout(new BorderLayout(5, 5)); 341 tmpP0 = new JPanel(); 342 tmpP0.setLayout(new BorderLayout(5, 5)); 343 tmpP0.add(new JLabel(" Number of Members:"), BorderLayout.WEST); 344 tmpP0.add(nFieldBox, BorderLayout.CENTER); 345 tmpP.add(tmpP0, BorderLayout.NORTH); 346 JScrollPane scroller = new JScrollPane(table); 347 border = new TitledBorder("Compound Datatype Properties"); 348 border.setTitleColor(Color.BLUE); 349 tmpP.setBorder(border); 350 tmpP.add(scroller, BorderLayout.CENTER); 351 contentPane.add(tmpP, BorderLayout.CENTER); 352 353 // set OK and CANCEL buttons 354 JPanel buttonPanel = new JPanel(); 355 buttonPanel.add(okButton); 356 buttonPanel.add(cancelButton); 357 contentPane.add(buttonPanel, BorderLayout.SOUTH); 358 359 rankChoice.addItemListener(this); 360 checkCompression.addItemListener(this); 361 checkContinguous.addItemListener(this); 362 checkChunked.addItemListener(this); 363 memberTypeChoice.addItemListener(this); 364 365 // locate the H5Property dialog 366 Point l = owner.getLocation(); 367 l.x += 250; 368 l.y += 120; 369 setLocation(l); 370 validate(); 371 pack(); 372 } 373 374 public void actionPerformed(ActionEvent e) { 375 String cmd = e.getActionCommand(); 376 377 if (cmd.equals("Ok")) { 378 try { 379 newObject = createCompoundDS(); 380 } 381 catch (Exception ex) { 382 JOptionPane.showMessageDialog(this, ex, getTitle(), JOptionPane.ERROR_MESSAGE); 383 } 384 385 if (newObject != null) { 386 dispose(); 387 } 388 } 389 else if (cmd.equals("Cancel")) { 390 newObject = null; 391 dispose(); 392 (groupList).setSize(0); 393 } 394 else if (cmd.equals("Change number of members")) { 395 int n = 0; 396 397 try { 398 n = Integer.valueOf((String) nFieldBox.getSelectedItem()).intValue(); 399 } 400 catch (Exception ex) { 401 log.debug("Change number of members:", ex); 402 } 403 404 if (n == numberOfMembers) { 405 return; 406 } 407 408 tableModel.setRowCount(n); 409 for (int i = numberOfMembers; i < n; i++) { 410 rowEditorModel.addEditorForRow(i, cellEditor); 411 } 412 numberOfMembers = n; 413 } 414 } 415 416 public void itemStateChanged(ItemEvent e) { 417 Object source = e.getSource(); 418 419 if (source.equals(rankChoice)) { 420 int rank = (int)rankChoice.getSelectedIndex() + 1; 421 String currentSizeStr = "1"; 422 String maxSizeStr = "0"; 423 424 for (int i = 1; i < rank; i++) { 425 currentSizeStr += " x 1"; 426 maxSizeStr += " x 0"; 427 } 428 429 currentSizeField.setText(currentSizeStr); 430 maxSizeField.setText(maxSizeStr); 431 432 String currentStr = currentSizeField.getText(); 433 int idx = currentStr.lastIndexOf("x"); 434 String chunkStr = "1"; 435 436 if (rank <= 1) { 437 chunkStr = currentStr; 438 } 439 else { 440 for (int i = 1; i < rank - 1; i++) { 441 chunkStr += " x 1"; 442 } 443 if (idx > 0) { 444 chunkStr += " x " + currentStr.substring(idx + 1); 445 } 446 } 447 448 chunkSizeField.setText(chunkStr); 449 } 450 else if (source.equals(checkContinguous)) { 451 chunkSizeField.setEnabled(false); 452 } 453 else if (source.equals(checkChunked)) { 454 chunkSizeField.setEnabled(true); 455 String currentStr = currentSizeField.getText(); 456 int idx = currentStr.lastIndexOf("x"); 457 String chunkStr = "1"; 458 459 int rank = (int)rankChoice.getSelectedIndex() + 1; 460 if (rank <= 1) { 461 chunkStr = currentStr; 462 } 463 else { 464 for (int i = 1; i < rank - 1; i++) { 465 chunkStr += " x 1"; 466 } 467 if (idx > 0) { 468 chunkStr += " x " + currentStr.substring(idx + 1); 469 } 470 } 471 472 chunkSizeField.setText(chunkStr); 473 } 474 else if (source.equals(checkCompression)) { 475 boolean isCompressed = checkCompression.isSelected(); 476 477 if (isCompressed) { 478 if (!checkChunked.isSelected()) { 479 String currentStr = currentSizeField.getText(); 480 int idx = currentStr.lastIndexOf("x"); 481 String chunkStr = "1"; 482 483 int rank = (int)rankChoice.getSelectedIndex() + 1; 484 if (rank <= 1) { 485 chunkStr = currentStr; 486 } 487 else { 488 for (int i = 1; i < rank - 1; i++) { 489 chunkStr += " x 1"; 490 } 491 if (idx > 0) { 492 chunkStr += " x " + currentStr.substring(idx + 1); 493 } 494 } 495 496 chunkSizeField.setText(chunkStr); 497 } 498 compressionLevel.setEnabled(true); 499 checkContinguous.setEnabled(false); 500 checkChunked.setSelected(true); 501 chunkSizeField.setEnabled(true); 502 } 503 else { 504 compressionLevel.setEnabled(false); 505 checkContinguous.setEnabled(true); 506 } 507 } 508 else if (source.equals(memberTypeChoice)) { 509 String item = (String) memberTypeChoice.getSelectedItem(); 510 if ((item == null) || !item.equals("enum")) { 511 return; 512 } 513 514 int row = table.getSelectedRow(); 515 table.setValueAt("mb1=0,mb=1,...", row, 2); 516 } 517 else if (source.equals(templateChoice)) { 518 Object obj = templateChoice.getSelectedItem(); 519 if (!(obj instanceof CompoundDS)) { 520 return; 521 } 522 523 CompoundDS dset = (CompoundDS) obj; 524 int rank = dset.getRank(); 525 if (rank < 1) { 526 dset.init(); 527 } 528 529 rank = dset.getRank(); 530 rankChoice.setSelectedIndex(rank - 1); 531 long[] dims = dset.getDims(); 532 String[] mNames = dset.getMemberNames(); 533 int[] mOrders = dset.getMemberOrders(); 534 Datatype[] mTypes = dset.getMemberTypes(); 535 536 String sizeStr = String.valueOf(dims[0]); 537 for (int i = 1; i < rank; i++) { 538 sizeStr += "x" + dims[i]; 539 } 540 currentSizeField.setText(sizeStr); 541 542 try { 543 dset.getMetadata(); 544 } // get chunking and compression info 545 catch (Exception ex) { 546 log.debug("get chunking and compression info:", ex); 547 } 548 long[] chunks = dset.getChunkSize(); 549 if (chunks != null) { 550 checkChunked.setSelected(true); 551 sizeStr = String.valueOf(chunks[0]); 552 for (int i = 1; i < rank; i++) { 553 sizeStr += "x" + chunks[i]; 554 } 555 chunkSizeField.setText(sizeStr); 556 } 557 558 String compression = dset.getCompression(); 559 if (compression != null) { 560 int clevel = -1; 561 int comp_pos = Dataset.compression_gzip_txt.length(); 562 int idx = compression.indexOf(Dataset.compression_gzip_txt); 563 if (idx >= 0) { 564 try { 565 clevel = Integer.parseInt(compression.substring(idx + comp_pos, idx + comp_pos +1)); 566 } 567 catch (NumberFormatException ex) { 568 clevel = -1; 569 } 570 } 571 if (clevel > 0) { 572 checkCompression.setSelected(true); 573 compressionLevel.setSelectedIndex(clevel); 574 } 575 } 576 577 numberOfMembers = dset.getMemberCount(); 578 nFieldBox.setSelectedIndex(numberOfMembers - 1); 579 tableModel.setRowCount(numberOfMembers); 580 for (int i = 0; i < numberOfMembers; i++) { 581 rowEditorModel.addEditorForRow(i, cellEditor); 582 583 tableModel.setValueAt(mNames[i], i, 0); 584 585 int typeIdx = -1; 586 int tclass = mTypes[i].getDatatypeClass(); 587 int tsize = mTypes[i].getDatatypeSize(); 588 int tsigned = mTypes[i].getDatatypeSign(); 589 if (tclass == Datatype.CLASS_ARRAY) { 590 tclass = mTypes[i].getBasetype().getDatatypeClass(); 591 tsize = mTypes[i].getBasetype().getDatatypeSize(); 592 tsigned = mTypes[i].getBasetype().getDatatypeSign(); 593 } 594 if (tclass == Datatype.CLASS_CHAR) { 595 if (tsigned == Datatype.SIGN_NONE) { 596 if (tsize == 1) { 597 typeIdx = 3; 598 } 599 } 600 else { 601 if (tsize == 1) { 602 typeIdx = 0; 603 } 604 } 605 } 606 if (tclass == Datatype.CLASS_INTEGER) { 607 if (tsigned == Datatype.SIGN_NONE) { 608 if (tsize == 1) { 609 typeIdx = 3; 610 } 611 else if (tsize == 2) { 612 typeIdx = 4; 613 } 614 else if (tsize == 4) { 615 typeIdx = 5; 616 } 617 else { 618 typeIdx = 11; 619 } 620 } 621 else { 622 if (tsize == 1) { 623 typeIdx = 0; 624 } 625 else if (tsize == 2) { 626 typeIdx = 1; 627 } 628 else if (tsize == 4) { 629 typeIdx = 2; 630 } 631 else { 632 typeIdx = 6; 633 } 634 } 635 } 636 else if (tclass == Datatype.CLASS_FLOAT) { 637 if (tsize == 4) { 638 typeIdx = 7; 639 } 640 else { 641 typeIdx = 8; 642 } 643 } 644 else if (tclass == Datatype.CLASS_STRING) { 645 typeIdx = 9; 646 } 647 else if (tclass == Datatype.CLASS_ENUM) { 648 typeIdx = 10; 649 } 650 if (typeIdx < 0) { 651 continue; 652 } 653 654 memberTypeChoice.setSelectedIndex(typeIdx); 655 tableModel.setValueAt(memberTypeChoice.getSelectedItem(), i, 1); 656 657 if (tclass == Datatype.CLASS_STRING) { 658 tableModel.setValueAt(String.valueOf(tsize), i, 2); 659 } 660 else if (tclass == Datatype.CLASS_ENUM) { 661 tableModel.setValueAt(mTypes[i].getEnumMembers(), i, 2); 662 } 663 else { 664 tableModel.setValueAt(String.valueOf(mOrders[i]), i, 2); 665 } 666 667 } // for (int i=0; i<numberOfMembers; i++) 668 } // else if (source.equals(templateChoice)) 669 } 670 671 private HObject createCompoundDS() throws Exception { 672 HObject obj = null; 673 long dims[], maxdims[], chunks[]; 674 int rank; 675 676 // stop editing the last selected cell 677 int row = table.getSelectedRow(); 678 int col = table.getSelectedColumn(); 679 if ((row >= 0) && (col > -0)) { 680 TableCellEditor ed = table.getCellEditor(row, col); 681 if (ed != null) { 682 ed.stopCellEditing(); 683 } 684 } 685 686 maxdims = chunks = null; 687 String dname = nameField.getText(); 688 if ((dname == null) || (dname.length() <= 0)) { 689 throw new IllegalArgumentException("Dataset name is empty"); 690 } 691 692 Group pgroup = (Group) groupList.get(parentChoice.getSelectedIndex()); 693 if (pgroup == null) { 694 throw new IllegalArgumentException("Invalid parent group"); 695 } 696 697 int n = table.getRowCount(); 698 if (n <= 0) { 699 return null; 700 } 701 702 String[] mNames = new String[n]; 703 Datatype[] mDatatypes = new Datatype[n]; 704 int[] mOrders = new int[n]; 705 706 for (int i = 0; i < n; i++) { 707 String name = (String) table.getValueAt(i, 0); 708 if ((name == null) || (name.length() <= 0)) { 709 throw new IllegalArgumentException("Member name is empty"); 710 } 711 mNames[i] = name; 712 713 int order = 1; 714 String orderStr = (String) table.getValueAt(i, 2); 715 if (orderStr != null) { 716 try { 717 order = Integer.parseInt(orderStr); 718 } 719 catch (Exception ex) { 720 log.debug("compound order:", ex); 721 } 722 } 723 mOrders[i] = order; 724 725 String typeName = (String) table.getValueAt(i, 1); 726 Datatype type = null; 727 if (DATATYPE_NAMES[0].equals(typeName)) { 728 type = fileformat.createDatatype(Datatype.CLASS_INTEGER, 1, Datatype.NATIVE, Datatype.NATIVE); 729 } 730 else if (DATATYPE_NAMES[1].equals(typeName)) { 731 type = fileformat.createDatatype(Datatype.CLASS_INTEGER, 2, Datatype.NATIVE, Datatype.NATIVE); 732 } 733 else if (DATATYPE_NAMES[2].equals(typeName)) { 734 type = fileformat.createDatatype(Datatype.CLASS_INTEGER, 4, Datatype.NATIVE, Datatype.NATIVE); 735 } 736 else if (DATATYPE_NAMES[3].equals(typeName)) { 737 type = fileformat.createDatatype(Datatype.CLASS_INTEGER, 1, Datatype.NATIVE, Datatype.SIGN_NONE); 738 } 739 else if (DATATYPE_NAMES[4].equals(typeName)) { 740 type = fileformat.createDatatype(Datatype.CLASS_INTEGER, 2, Datatype.NATIVE, Datatype.SIGN_NONE); 741 } 742 else if (DATATYPE_NAMES[5].equals(typeName)) { 743 type = fileformat.createDatatype(Datatype.CLASS_INTEGER, 4, Datatype.NATIVE, Datatype.SIGN_NONE); 744 } 745 else if (DATATYPE_NAMES[6].equals(typeName)) { 746 type = fileformat.createDatatype(Datatype.CLASS_INTEGER, 8, Datatype.NATIVE, Datatype.NATIVE); 747 } 748 else if (DATATYPE_NAMES[7].equals(typeName)) { 749 type = fileformat.createDatatype(Datatype.CLASS_FLOAT, 4, Datatype.NATIVE, Datatype.NATIVE); 750 } 751 else if (DATATYPE_NAMES[8].equals(typeName)) { 752 type = fileformat.createDatatype(Datatype.CLASS_FLOAT, 8, Datatype.NATIVE, Datatype.NATIVE); 753 } 754 else if (DATATYPE_NAMES[9].equals(typeName)) { 755 type = fileformat.createDatatype(Datatype.CLASS_STRING, order, Datatype.NATIVE, Datatype.NATIVE); 756 } 757 else if (DATATYPE_NAMES[10].equals(typeName)) { // enum 758 type = fileformat.createDatatype(Datatype.CLASS_ENUM, 4, Datatype.NATIVE, Datatype.NATIVE); 759 if ((orderStr == null) || (orderStr.length() < 1) || orderStr.endsWith("...")) { 760 toolkit.beep(); 761 JOptionPane.showMessageDialog(this, "Invalid member values: " + orderStr, getTitle(), 762 JOptionPane.ERROR_MESSAGE); 763 return null; 764 } 765 else { 766 type.setEnumMembers(orderStr); 767 } 768 } 769 else if (DATATYPE_NAMES[11].equals(typeName)) { 770 type = fileformat.createDatatype(Datatype.CLASS_INTEGER, 8, Datatype.NATIVE, Datatype.SIGN_NONE); 771 } 772 else { 773 throw new IllegalArgumentException("Invalid data type."); 774 } 775 mDatatypes[i] = type; 776 } // for (int i=0; i<n; i++) 777 778 rank = (int)rankChoice.getSelectedIndex() + 1; 779 StringTokenizer st = new StringTokenizer(currentSizeField.getText(), "x"); 780 if (st.countTokens() < rank) { 781 toolkit.beep(); 782 JOptionPane.showMessageDialog(this, "Number of values in the current dimension size is less than " + rank, 783 getTitle(), JOptionPane.ERROR_MESSAGE); 784 return null; 785 } 786 787 long l = 0; 788 dims = new long[rank]; 789 String token = null; 790 for (int i = 0; i < rank; i++) { 791 token = st.nextToken().trim(); 792 try { 793 l = Long.parseLong(token); 794 } 795 catch (NumberFormatException ex) { 796 toolkit.beep(); 797 JOptionPane.showMessageDialog(this, "Invalid dimension size: " + currentSizeField.getText(), 798 getTitle(), JOptionPane.ERROR_MESSAGE); 799 return null; 800 } 801 802 if (l <= 0) { 803 toolkit.beep(); 804 JOptionPane.showMessageDialog(this, "Dimension size must be greater than zero.", getTitle(), 805 JOptionPane.ERROR_MESSAGE); 806 return null; 807 } 808 809 dims[i] = l; 810 } 811 812 st = new StringTokenizer(maxSizeField.getText(), "x"); 813 if (st.countTokens() < rank) { 814 toolkit.beep(); 815 JOptionPane.showMessageDialog(this, "Number of values in the max dimension size is less than " + rank, 816 getTitle(), JOptionPane.ERROR_MESSAGE); 817 return null; 818 } 819 820 l = 0; 821 maxdims = new long[rank]; 822 for (int i = 0; i < rank; i++) { 823 token = st.nextToken().trim(); 824 try { 825 l = Long.parseLong(token); 826 } 827 catch (NumberFormatException ex) { 828 toolkit.beep(); 829 JOptionPane.showMessageDialog(this, "Invalid max dimension size: " + maxSizeField.getText(), 830 getTitle(), JOptionPane.ERROR_MESSAGE); 831 return null; 832 } 833 834 if (l < -1) { 835 toolkit.beep(); 836 JOptionPane.showMessageDialog(this, "Dimension size cannot be less than -1.", getTitle(), 837 JOptionPane.ERROR_MESSAGE); 838 return null; 839 } 840 else if (l == 0) { 841 l = dims[i]; 842 } 843 844 maxdims[i] = l; 845 } 846 847 chunks = null; 848 if (checkChunked.isSelected()) { 849 st = new StringTokenizer(chunkSizeField.getText(), "x"); 850 if (st.countTokens() < rank) { 851 toolkit.beep(); 852 JOptionPane.showMessageDialog(this, "Number of values in the chunk size is less than " + rank, 853 getTitle(), JOptionPane.ERROR_MESSAGE); 854 return null; 855 } 856 857 l = 0; 858 chunks = new long[rank]; 859 token = null; 860 for (int i = 0; i < rank; i++) { 861 token = st.nextToken().trim(); 862 try { 863 l = Long.parseLong(token); 864 } 865 catch (NumberFormatException ex) { 866 toolkit.beep(); 867 JOptionPane.showMessageDialog(this, "Invalid chunk dimension size: " + chunkSizeField.getText(), 868 getTitle(), JOptionPane.ERROR_MESSAGE); 869 return null; 870 } 871 872 if (l < 1) { 873 toolkit.beep(); 874 JOptionPane.showMessageDialog(this, "Chunk size cannot be less than 1.", getTitle(), 875 JOptionPane.ERROR_MESSAGE); 876 return null; 877 } 878 879 chunks[i] = l; 880 } // for (int i=0; i<rank; i++) 881 882 long tchunksize = 1, tdimsize = 1; 883 for (int i = 0; i < rank; i++) { 884 tchunksize *= chunks[i]; 885 tdimsize *= dims[i]; 886 } 887 888 if (tchunksize >= tdimsize) { 889 toolkit.beep(); 890 int status = JOptionPane.showConfirmDialog(this, "Chunk size is equal/greater than the current size. " 891 + "\nAre you sure you want to set chunk size to " + chunkSizeField.getText() + "?", getTitle(), 892 JOptionPane.YES_NO_OPTION); 893 if (status == JOptionPane.NO_OPTION) { 894 return null; 895 } 896 } 897 898 if (tchunksize == 1) { 899 toolkit.beep(); 900 int status = JOptionPane.showConfirmDialog(this, 901 "Chunk size is one, which may cause large memory overhead for large dataset." 902 + "\nAre you sure you want to set chunk size to " + chunkSizeField.getText() + "?", 903 getTitle(), JOptionPane.YES_NO_OPTION); 904 if (status == JOptionPane.NO_OPTION) { 905 return null; 906 } 907 } 908 909 } // if (checkChunked.isSelected()) 910 911 int gzip = 0; 912 if (checkCompression.isSelected()) { 913 gzip = compressionLevel.getSelectedIndex(); 914 } 915 916 if (checkChunked.isSelected()) { 917 obj = fileformat.createCompoundDS(dname, pgroup, dims, maxdims, chunks, gzip, mNames, mDatatypes, mOrders, 918 null); 919 } 920 else { 921 obj = fileformat 922 .createCompoundDS(dname, pgroup, dims, maxdims, null, -1, mNames, mDatatypes, mOrders, null); 923 } 924 925 return obj; 926 } 927 928 /** 929 * Returns the new dataset created. 930 * 931 * @return The new Dataset created 932 */ 933 public DataFormat getObject() { 934 return newObject; 935 } 936 937 /** 938 * Returns the parent group of the new dataset. 939 * 940 * @return The parent group of the new Dataset 941 */ 942 public Group getParentGroup() { 943 return (Group) groupList.get(parentChoice.getSelectedIndex()); 944 } 945 946 private class RowEditorModel { 947 private Hashtable<Integer, TableCellEditor> data; 948 949 public RowEditorModel() { 950 data = new Hashtable<Integer, TableCellEditor>(); 951 } 952 953 // all rows has the same cell editor 954 public RowEditorModel(int rows, TableCellEditor ed) { 955 data = new Hashtable<Integer, TableCellEditor>(); 956 for (int i = 0; i < rows; i++) { 957 data.put(new Integer(i), ed); 958 } 959 } 960 961 public void addEditorForRow(int row, TableCellEditor e) { 962 data.put(new Integer(row), e); 963 } 964 965 public void removeEditorForRow(int row) { 966 data.remove(new Integer(row)); 967 } 968 969 public TableCellEditor getEditor(int row) { 970 return (TableCellEditor) data.get(new Integer(row)); 971 } 972 } 973}