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