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.Iterator; 029import java.util.List; 030import java.util.Vector; 031 032import javax.swing.BorderFactory; 033import javax.swing.JButton; 034import javax.swing.JCheckBox; 035import javax.swing.JComboBox; 036import javax.swing.JDialog; 037import javax.swing.JFrame; 038import javax.swing.JLabel; 039import javax.swing.JOptionPane; 040import javax.swing.JPanel; 041import javax.swing.JTextField; 042import javax.swing.border.TitledBorder; 043 044import hdf.object.DataFormat; 045import hdf.object.Datatype; 046import hdf.object.FileFormat; 047import hdf.object.Group; 048import hdf.object.HObject; 049 050/** 051 * NewDatasetDialog shows a message dialog requesting user input for creating a 052 * new HDF4/5 dataset. 053 * 054 * @author Peter X. Cao 055 * @version 2.4 9/6/2007 056 */ 057public class NewDatatypeDialog extends JDialog 058implements ActionListener, ItemListener { 059 private static final long serialVersionUID = -1930736056916611522L; 060 061 private JTextField nameField, stringLengthField; 062 063 @SuppressWarnings("rawtypes") 064 private JComboBox parentChoice, classChoice, sizeChoice, endianChoice; 065 066 private JCheckBox checkUnsigned; 067 068 private boolean isH5; 069 070 /** a list of current groups */ 071 private List<Object> groupList; 072 073 private HObject newObject; 074 075 private FileFormat fileFormat; 076 077 private final Toolkit toolkit; 078 079 /** 080 * Constructs NewDatatypeDialog with specified list of possible parent 081 * groups. 082 * 083 * @param owner 084 * the owner of the input 085 * @param pGroup 086 * the parent group which the new group is added to. 087 * @param objs 088 * the list of all objects. 089 */ 090 @SuppressWarnings({ "rawtypes", "unchecked" }) 091 public NewDatatypeDialog(JFrame owner, Group pGroup, List<?> objs) { 092 super(owner, "New Datatype...", true); 093 094 newObject = null; 095 096 fileFormat = pGroup.getFileFormat(); 097 toolkit = Toolkit.getDefaultToolkit(); 098 isH5 = pGroup.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5)); 099 100 parentChoice = new JComboBox(); 101 groupList = new Vector<Object>(objs.size()); 102 Object obj = null; 103 Iterator<?> iterator = objs.iterator(); 104 while (iterator.hasNext()) { 105 obj = iterator.next(); 106 if (obj instanceof Group) { 107 Group g = (Group) obj; 108 groupList.add(obj); 109 if (g.isRoot()) { 110 parentChoice.addItem(HObject.separator); 111 } 112 else { 113 parentChoice.addItem(g.getPath() + g.getName() + HObject.separator); 114 } 115 } 116 } 117 118 if (pGroup.isRoot()) { 119 parentChoice.setSelectedItem(HObject.separator); 120 } 121 else { 122 parentChoice.setSelectedItem(pGroup.getPath() + pGroup.getName() + HObject.separator); 123 } 124 125 JPanel contentPane = (JPanel) getContentPane(); 126 contentPane.setLayout(new BorderLayout(5, 5)); 127 contentPane.setBorder(BorderFactory.createEmptyBorder(15, 5, 5, 5)); 128 int w = 600 + (ViewProperties.getFontSize() - 12) * 15; 129 int h = 200 + (ViewProperties.getFontSize() - 12) * 10; 130 contentPane.setPreferredSize(new Dimension(w, h)); 131 132 JButton okButton = new JButton(" Ok "); 133 okButton.setName("OK"); 134 okButton.setActionCommand("Ok"); 135 okButton.setMnemonic(KeyEvent.VK_O); 136 okButton.addActionListener(this); 137 138 JButton cancelButton = new JButton("Cancel"); 139 cancelButton.setName("Cancel"); 140 cancelButton.setMnemonic(KeyEvent.VK_C); 141 cancelButton.setActionCommand("Cancel"); 142 cancelButton.addActionListener(this); 143 144 // set OK and CANCEL buttons 145 JPanel buttonPanel = new JPanel(); 146 buttonPanel.add(okButton); 147 buttonPanel.add(cancelButton); 148 contentPane.add(buttonPanel, BorderLayout.SOUTH); 149 150 // set NAME and PARENT GROUP panel 151 JPanel namePanel = new JPanel(); 152 namePanel.setLayout(new BorderLayout(5, 5)); 153 JPanel tmpP = new JPanel(); 154 tmpP.setLayout(new GridLayout(2, 1)); 155 tmpP.add(new JLabel("Datatype name: ")); 156 tmpP.add(new JLabel("Parent group: ")); 157 namePanel.add(tmpP, BorderLayout.WEST); 158 tmpP = new JPanel(); 159 tmpP.setLayout(new GridLayout(2, 1)); 160 nameField = new JTextField(); 161 nameField.setName("dtname"); 162 tmpP.add(nameField); 163 tmpP.add(parentChoice); 164 namePanel.add(tmpP, BorderLayout.CENTER); 165 contentPane.add(namePanel, BorderLayout.NORTH); 166 167 // set DATATYPE 168 JPanel typePanel = new JPanel(); 169 typePanel.setLayout(new GridLayout(2, 4, 15, 3)); 170 TitledBorder border = new TitledBorder("Datatype"); 171 border.setTitleColor(Color.blue); 172 typePanel.setBorder(border); 173 174 stringLengthField = new JTextField("String length"); 175 stringLengthField.setName("dtstringlen"); 176 stringLengthField.setEnabled(false); 177 178 endianChoice = new JComboBox(); 179 endianChoice.setName("dtendian"); 180 classChoice = new JComboBox(); 181 classChoice.setName("dtclass"); 182 sizeChoice = new JComboBox(); 183 sizeChoice.setName("dtsize"); 184 endianChoice.setEnabled(isH5); 185 186 classChoice.addItem("INTEGER"); 187 classChoice.addItem("FLOAT"); 188 classChoice.addItem("CHAR"); 189 190 if (isH5) { 191 classChoice.addItem("STRING"); 192 classChoice.addItem("REFERENCE"); 193 classChoice.addItem("VLEN_INTEGER"); 194 classChoice.addItem("VLEN_FLOAT"); 195 classChoice.addItem("VLEN_STRING"); 196 sizeChoice.addItem("NATIVE"); 197 endianChoice.addItem("NATIVE"); 198 endianChoice.addItem("LITTLE ENDIAN"); 199 endianChoice.addItem("BIG ENDIAN"); 200 } 201 else { 202 sizeChoice.addItem("DEFAULT"); 203 endianChoice.addItem("DEFAULT"); 204 typePanel.add(new JLabel()); 205 } 206 sizeChoice.addItem("8"); 207 sizeChoice.addItem("16"); 208 sizeChoice.addItem("32"); 209 sizeChoice.addItem("64"); 210 211 typePanel.add(new JLabel("Datatype class")); 212 typePanel.add(new JLabel("Size (bits)")); 213 typePanel.add(new JLabel("Byte ordering")); 214 checkUnsigned = new JCheckBox("Unsigned"); 215 checkUnsigned.setName("dtchkunsigned"); 216 typePanel.add(checkUnsigned); 217 218 typePanel.add(classChoice); 219 typePanel.add(sizeChoice); 220 typePanel.add(endianChoice); 221 typePanel.add(stringLengthField); 222 223 contentPane.add(typePanel, BorderLayout.CENTER); 224 225 classChoice.addItemListener(this); 226 sizeChoice.addItemListener(this); 227 228 // locate the H5Property dialog 229 Point l = owner.getLocation(); 230 l.x += 250; 231 l.y += 100; 232 setLocation(l); 233 validate(); 234 pack(); 235 } 236 237 public void actionPerformed(ActionEvent e) { 238 Object source = e.getSource(); 239 String cmd = e.getActionCommand(); 240 241 if (cmd.equals("Ok")) { 242 newObject = createDatatype(); 243 244 if (newObject != null) { 245 dispose(); 246 } 247 } 248 if (cmd.equals("Cancel")) { 249 newObject = null; 250 dispose(); 251 } 252 } 253 254 @SuppressWarnings("unchecked") 255 public void itemStateChanged(ItemEvent e) { 256 Object source = e.getSource(); 257 258 if (source.equals(classChoice)) { 259 int idx = classChoice.getSelectedIndex(); 260 sizeChoice.setSelectedIndex(0); 261 endianChoice.setSelectedIndex(0); 262 stringLengthField.setEnabled(false); 263 264 if ((idx == 0) || (idx == 5)) { 265 sizeChoice.setEnabled(true); 266 endianChoice.setEnabled(isH5); 267 checkUnsigned.setEnabled(true); 268 269 if (sizeChoice.getItemCount() == 3) { 270 sizeChoice.removeItem("32"); 271 sizeChoice.removeItem("64"); 272 sizeChoice.addItem("8"); 273 sizeChoice.addItem("16"); 274 sizeChoice.addItem("32"); 275 sizeChoice.addItem("64"); 276 } 277 } 278 else if ((idx == 1) || (idx == 6)) { 279 sizeChoice.setEnabled(true); 280 endianChoice.setEnabled(isH5); 281 checkUnsigned.setEnabled(false); 282 283 if (sizeChoice.getItemCount() == 5) { 284 sizeChoice.removeItem("16"); 285 sizeChoice.removeItem("8"); 286 } 287 } 288 else if (idx == 2) { 289 sizeChoice.setEnabled(false); 290 endianChoice.setEnabled(isH5); 291 checkUnsigned.setEnabled(true); 292 } 293 else if (idx == 3) { 294 sizeChoice.setEnabled(false); 295 endianChoice.setEnabled(false); 296 checkUnsigned.setEnabled(false); 297 stringLengthField.setEnabled(true); 298 stringLengthField.setText("String length"); 299 } 300 else if (idx == 4) { 301 sizeChoice.setEnabled(false); 302 endianChoice.setEnabled(false); 303 checkUnsigned.setEnabled(false); 304 stringLengthField.setEnabled(false); 305 } 306 else if (idx == 7) { 307 sizeChoice.setEnabled(false); 308 endianChoice.setEnabled(false); 309 checkUnsigned.setEnabled(false); 310 stringLengthField.setEnabled(false); 311 } 312 } 313 else if (source.equals(sizeChoice)) { 314 if (classChoice.getSelectedIndex() == 0) { 315 checkUnsigned.setEnabled(true); 316 } 317 } 318 } 319 320 private HObject createDatatype() { 321 String name = null; 322 Group pgroup = null; 323 boolean isVLen = false; 324 int tclass = -1, tsize = -1, torder = -1, tsign = -1; 325 name = nameField.getText().trim(); 326 if ((name == null) || (name.length() < 1)) { 327 toolkit.beep(); 328 JOptionPane.showMessageDialog(this, 329 "Datatype name is not specified.", 330 getTitle(), 331 JOptionPane.ERROR_MESSAGE); 332 return null; 333 } 334 335 if (name.indexOf(HObject.separator) >= 0) { 336 toolkit.beep(); 337 JOptionPane.showMessageDialog(this, 338 "Datatype name cannot contain path.", 339 getTitle(), 340 JOptionPane.ERROR_MESSAGE); 341 return null; 342 } 343 344 pgroup = (Group) groupList.get(parentChoice.getSelectedIndex()); 345 346 if (pgroup == null) { 347 toolkit.beep(); 348 JOptionPane.showMessageDialog(this, 349 "Parent group is null.", 350 getTitle(), 351 JOptionPane.ERROR_MESSAGE); 352 return null; 353 } 354 355 // set datatype class 356 int idx = classChoice.getSelectedIndex(); 357 if (idx == 0) { 358 tclass = Datatype.CLASS_INTEGER; 359 if (checkUnsigned.isSelected()) { 360 tsign = Datatype.SIGN_NONE; 361 } 362 } 363 else if (idx == 1) { 364 tclass = Datatype.CLASS_FLOAT; 365 } 366 else if (idx == 2) { 367 tclass = Datatype.CLASS_CHAR; 368 if (checkUnsigned.isSelected()) { 369 tsign = Datatype.SIGN_NONE; 370 } 371 } 372 else if (idx == 3) { 373 tclass = Datatype.CLASS_STRING; 374 } 375 else if (idx == 4) { 376 tclass = Datatype.CLASS_REFERENCE; 377 } 378 else if (idx == 5) {; 379 isVLen = true; 380 tclass = Datatype.CLASS_INTEGER; 381 if (checkUnsigned.isSelected()) { 382 tsign = Datatype.SIGN_NONE; 383 } 384 } 385 else if (idx == 6) {; 386 isVLen = true; 387 tclass = Datatype.CLASS_FLOAT; 388 } 389 else if (idx == 7) { 390 isVLen = true; 391 tclass = Datatype.CLASS_STRING; 392 } 393 394 // set datatype size/order 395 idx = sizeChoice.getSelectedIndex(); 396 if (tclass == Datatype.CLASS_STRING) { 397 if (isVLen) { 398 tsize = -1; 399 } 400 else { 401 int stringLength = 0; 402 try { 403 stringLength = Integer.parseInt(stringLengthField.getText()); 404 } 405 catch (NumberFormatException ex) { 406 stringLength = -1; 407 } 408 409 if (stringLength <= 0) { 410 toolkit.beep(); 411 JOptionPane.showMessageDialog(this, 412 "Invalid string length: " + stringLengthField.getText(), 413 getTitle(), 414 JOptionPane.ERROR_MESSAGE); 415 return null; 416 } 417 418 tsize = stringLength; 419 } 420 } 421 else if (tclass == Datatype.CLASS_REFERENCE) { 422 tsize = 1; 423 } 424 else if (idx == 0) { 425 tsize = Datatype.NATIVE; 426 } 427 else if (tclass == Datatype.CLASS_FLOAT) { 428 tsize = idx * 4; 429 } 430 else { 431 tsize = 1 << (idx - 1); 432 } 433 434 if ((tsize == 8) && !isH5 && (tclass == Datatype.CLASS_INTEGER)) { 435 toolkit.beep(); 436 JOptionPane.showMessageDialog(this, 437 "HDF4 does not support 64-bit integer.", 438 getTitle(), 439 JOptionPane.ERROR_MESSAGE); 440 return null; 441 } 442 443 // set order 444 idx = endianChoice.getSelectedIndex(); 445 if (idx == 0) { 446 torder = Datatype.NATIVE; 447 } 448 else if (idx == 1) { 449 torder = Datatype.ORDER_LE; 450 } 451 else { 452 torder = Datatype.ORDER_BE; 453 } 454 455 HObject obj = null; 456 try { 457 String fullPath = HObject.separator; 458 if (pgroup.isRoot()) { 459 fullPath += name; 460 } 461 else { 462 fullPath = pgroup.getPath() + HObject.separator + pgroup.getName() + HObject.separator + name; 463 } 464 Datatype basedatatype = null; 465 if (isVLen) { 466 basedatatype = fileFormat.createDatatype(tclass, tsize, torder, tsign); 467 tclass = Datatype.CLASS_VLEN; 468 } 469 Datatype datatype = fileFormat.createDatatype(tclass, tsize, torder, tsign, basedatatype, fullPath); 470 obj = datatype; 471 } 472 catch (Exception ex) { 473 toolkit.beep(); 474 JOptionPane.showMessageDialog(this, 475 ex, 476 getTitle(), 477 JOptionPane.ERROR_MESSAGE); 478 return null; 479 } 480 481 return obj; 482 } 483 484 /** 485 * Returns the new dataset created. 486 * 487 * @return The new Dataset created 488 */ 489 public DataFormat getObject() { 490 return newObject; 491 } 492 493 /** 494 * Returns the parent group of the new dataset. 495 * 496 * @return The parent group of the new Dataset 497 */ 498 public Group getParentGroup() { 499 return (Group) groupList.get(parentChoice.getSelectedIndex()); 500 } 501}