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.Dimension; 019import java.awt.Frame; 020import java.awt.GridLayout; 021import java.awt.Insets; 022import java.awt.Point; 023import java.awt.Toolkit; 024import java.awt.event.ActionEvent; 025import java.awt.event.ActionListener; 026import java.awt.event.ItemEvent; 027import java.awt.event.ItemListener; 028import java.awt.event.KeyEvent; 029import java.awt.event.KeyListener; 030import java.util.Iterator; 031import java.util.List; 032import java.util.Vector; 033 034import javax.swing.BorderFactory; 035import javax.swing.JButton; 036import javax.swing.JCheckBox; 037import javax.swing.JComboBox; 038import javax.swing.JDialog; 039import javax.swing.JLabel; 040import javax.swing.JOptionPane; 041import javax.swing.JPanel; 042import javax.swing.JTextField; 043import javax.swing.border.TitledBorder; 044import javax.swing.text.AttributeSet; 045import javax.swing.text.BadLocationException; 046import javax.swing.text.PlainDocument; 047 048import hdf.object.DataFormat; 049import hdf.object.FileFormat; 050import hdf.object.Group; 051import hdf.object.HObject; 052 053/** 054 * NewGroupDialog shows a message dialog requesting user input for creating a new HDF4/5 group. 055 * 056 * @author Peter X. Cao 057 * @version 2.4 9/6/2007 058 */ 059public class NewGroupDialog extends JDialog implements ActionListener, ItemListener, KeyListener { 060 private static final long serialVersionUID = 7340860373483987075L; 061 062 private JTextField nameField; 063 064 private JTextField compactField; 065 066 private JTextField indexedField; 067 068 @SuppressWarnings("rawtypes") 069 private JComboBox parentChoice; 070 071 private JCheckBox useCreationOrder; 072 073 private JCheckBox setLinkStorage; 074 075 @SuppressWarnings("rawtypes") 076 private JComboBox orderFlags; 077 078 /** a list of current groups */ 079 private List<Group> groupList; 080 081 private HObject newObject; 082 083 private FileFormat fileFormat; 084 085 private final Toolkit toolkit; 086 087 private int creationOrder; 088 089 private JPanel useCreationOrderJPanel; 090 091 private JPanel setLinkStorageJPanel; 092 093 private JButton moreButton; 094 095 private JPanel labelPanel; 096 097 private JPanel textPanel; 098 099 private JPanel contentPane; 100 101 private JButton creationOrderHelpButton; 102 103 private JButton storageTypeHelpButton; 104 105 private boolean isH5; 106 107 /** 108 * Constructs NewGroupDialog with specified list of possible parent groups. 109 * 110 * @param owner 111 * the owner of the input 112 * @param pGroup 113 * the parent group which the new group is added to. 114 * @param objs 115 * the list of all objects. 116 */ 117 @SuppressWarnings({ "rawtypes", "unchecked" }) 118 public NewGroupDialog(Frame owner, Group pGroup, List<?> objs) { 119 super(owner, "New Group...", true); 120 121 newObject = null; 122 123 fileFormat = pGroup.getFileFormat(); 124 isH5 = pGroup.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5)); 125 toolkit = Toolkit.getDefaultToolkit(); 126 127 parentChoice = new JComboBox(); 128 groupList = new Vector<Group>(); 129 Object obj = null; 130 Iterator<?> iterator = objs.iterator(); 131 while (iterator.hasNext()) { 132 obj = iterator.next(); 133 if (obj instanceof Group) { 134 groupList.add((Group) obj); 135 Group g = (Group) obj; 136 if (g.isRoot()) { 137 parentChoice.addItem(HObject.separator); 138 } 139 else { 140 parentChoice.addItem(g.getPath() + g.getName() + HObject.separator); 141 } 142 } 143 } 144 145 if (pGroup.isRoot()) { 146 parentChoice.setSelectedItem(HObject.separator); 147 } 148 else { 149 parentChoice.setSelectedItem(pGroup.getPath() + pGroup.getName() + HObject.separator); 150 } 151 152 orderFlags = new JComboBox(); 153 orderFlags.addItem("Tracked"); 154 orderFlags.addItem("Tracked+Indexed"); 155 156 contentPane = (JPanel) getContentPane(); 157 contentPane.setLayout(new BorderLayout(5, 5)); 158 contentPane.setBorder(BorderFactory.createEmptyBorder(15, 5, 5, 5)); 159 int w = 400 + (ViewProperties.getFontSize() - 12) * 15; 160 int h = 150 + (ViewProperties.getFontSize() - 12) * 10; 161 contentPane.setPreferredSize(new Dimension(w, h)); 162 163 JButton okButton = new JButton(" Ok "); 164 okButton.setName("OK"); 165 okButton.setActionCommand("Ok"); 166 okButton.setMnemonic(KeyEvent.VK_O); 167 okButton.addActionListener(this); 168 169 JButton cancelButton = new JButton("Cancel"); 170 cancelButton.setName("Cancel"); 171 cancelButton.setMnemonic(KeyEvent.VK_C); 172 cancelButton.setActionCommand("Cancel"); 173 cancelButton.addActionListener(this); 174 175 moreButton = new JButton("More"); 176 moreButton.setName("More"); 177 moreButton.addActionListener(this); 178 179 // set OK and CANCEL buttons 180 JPanel buttonPanel = new JPanel(); 181 buttonPanel.add(okButton); 182 buttonPanel.add(cancelButton); 183 contentPane.add(buttonPanel, BorderLayout.SOUTH); 184 185 // set NAME and PARENT GROUP panel 186 JPanel namePanel = new JPanel(); 187 namePanel.setLayout(new BorderLayout(5, 5)); 188 189 labelPanel = new JPanel(); 190 textPanel = new JPanel(); 191 192 if (!isH5) { 193 labelPanel.setLayout(new GridLayout(2, 1)); 194 labelPanel.add(new JLabel("Group name: ")); 195 labelPanel.add(new JLabel("Parent group: ")); 196 textPanel.setLayout(new GridLayout(2, 1)); 197 textPanel.add(nameField = new JTextField()); 198 textPanel.add(parentChoice); 199 } 200 else { 201 labelPanel.setLayout(new GridLayout(3, 1)); 202 labelPanel.add(new JLabel("Group name: ")); 203 labelPanel.add(new JLabel("Parent group: ")); 204 labelPanel.add(moreButton); // if h5 format then add more button 205 textPanel.setLayout(new GridLayout(3, 1)); 206 textPanel.add(nameField = new JTextField()); 207 textPanel.add(parentChoice); 208 textPanel.add(new JLabel("")); // for more button 209 } 210 nameField.setName("groupname"); 211 parentChoice.setName("groupparent"); 212 213 creationOrderHelpButton = new JButton(ViewProperties.getHelpIcon()); 214 creationOrderHelpButton.setToolTipText("Help on Creation Order"); 215 creationOrderHelpButton.setMargin(new Insets(0, 0, 0, 0)); 216 creationOrderHelpButton.addActionListener(this); 217 creationOrderHelpButton.setActionCommand("Help on Creation Order"); 218 219 storageTypeHelpButton = new JButton(ViewProperties.getHelpIcon()); 220 storageTypeHelpButton.setToolTipText("Help on set Link Storage"); 221 storageTypeHelpButton.setMargin(new Insets(0, 0, 0, 0)); 222 storageTypeHelpButton.addActionListener(this); 223 storageTypeHelpButton.setActionCommand("Help on set Link Storage"); 224 225 namePanel.add(labelPanel, BorderLayout.WEST); 226 227 useCreationOrderJPanel = new JPanel(); 228 useCreationOrderJPanel.setLayout(new GridLayout(1, 2)); 229 useCreationOrderJPanel.setBorder(new TitledBorder("")); 230 useCreationOrderJPanel.add(useCreationOrder = new JCheckBox("Use Creation Order")); 231 useCreationOrder.addItemListener(this); 232 JPanel orderFlagsJPanel = new JPanel(); 233 orderFlagsJPanel.setLayout(new GridLayout(1, 2)); 234 orderFlagsJPanel.add(new JLabel("Order Flags: ")); 235 orderFlagsJPanel.add(orderFlags); 236 orderFlags.setEnabled(false); 237 useCreationOrderJPanel.add(orderFlagsJPanel); 238 239 setLinkStorageJPanel = new JPanel(); 240 setLinkStorageJPanel.setLayout(new GridLayout(1, 2)); 241 setLinkStorageJPanel.setBorder(new TitledBorder("")); 242 setLinkStorageJPanel.add(setLinkStorage = new JCheckBox("Set Link Storage")); 243 setLinkStorage.addItemListener(this); 244 JPanel storageTypeJPanel = new JPanel(); 245 storageTypeJPanel.setLayout(new GridLayout(2, 2)); 246 storageTypeJPanel.add(new JLabel("Min Indexed: ")); 247 storageTypeJPanel.add(new JLabel("Max Compact: ")); 248 indexedField = new JTextField(); 249 indexedField.addKeyListener(this); 250 storageTypeJPanel.add(indexedField); 251 indexedField.setDocument(new JTextFieldLimit(5)); 252 indexedField.setText("6"); 253 indexedField.setEnabled(false); 254 compactField = new JTextField(); 255 storageTypeJPanel.add(compactField); 256 compactField.addKeyListener(this); 257 compactField.setDocument(new JTextFieldLimit(5)); 258 compactField.setText("8"); 259 compactField.setEnabled(false); 260 setLinkStorageJPanel.add(storageTypeJPanel); 261 262 namePanel.add(textPanel, BorderLayout.CENTER); 263 contentPane.add(namePanel, BorderLayout.CENTER); 264 265 // locate the H5Property dialog 266 Point l = owner.getLocation(); 267 l.x += 250; 268 l.y += 80; 269 setLocation(l); 270 validate(); 271 pack(); 272 } 273 274 public void actionPerformed(ActionEvent e) { 275 String cmd = e.getActionCommand(); 276 277 if (cmd.equals("More")) { 278 moreButton.setText("Less"); 279 int w = 500 + (ViewProperties.getFontSize() - 12) * 15; 280 int h = 280 + (ViewProperties.getFontSize() - 12) * 10; 281 contentPane.setPreferredSize(new Dimension(w, h)); 282 labelPanel.setLayout(new GridLayout(5, 1)); 283 labelPanel.add(creationOrderHelpButton); 284 labelPanel.add(storageTypeHelpButton); 285 textPanel.setLayout(new GridLayout(5, 1)); 286 textPanel.add(useCreationOrderJPanel); 287 textPanel.add(setLinkStorageJPanel); 288 validate(); 289 pack(); 290 } 291 292 if (cmd.equals("Less")) { 293 moreButton.setText("More"); 294 int w = 400 + (ViewProperties.getFontSize() - 12) * 15; 295 int h = 150 + (ViewProperties.getFontSize() - 12) * 10; 296 contentPane.setPreferredSize(new Dimension(w, h)); 297 labelPanel.setLayout(new GridLayout(3, 1)); 298 labelPanel.remove(creationOrderHelpButton); 299 labelPanel.remove(storageTypeHelpButton); 300 textPanel.setLayout(new GridLayout(3, 1)); 301 textPanel.remove(useCreationOrderJPanel); 302 textPanel.remove(setLinkStorageJPanel); 303 useCreationOrder.setSelected(false); 304 setLinkStorage.setSelected(false); 305 validate(); 306 pack(); 307 } 308 309 if (cmd.equals("Help on Creation Order")) { 310 final String msg = "Use Creation Order allows the user to set the creation order \n" 311 + "of links in a group, so that tracking, indexing, and iterating over links\n" 312 + "in groups can be possible. \n\n" 313 + "If the order flag Tracked is selected, links in a group can now \n" 314 + "be explicitly tracked by the order that they were created. \n\n" 315 + "If the order flag Tracked+Indexed is selected, links in a group can \n" 316 + "now be explicitly tracked and indexed in the order that they were created. \n\n" 317 + "The default order in which links in a group are listed is alphanumeric-by-name. \n\n\n"; 318 JOptionPane.showMessageDialog(this, msg); 319 } 320 321 if (cmd.equals("Help on set Link Storage")) { 322 final String msg = "Set Link Storage allows the users to explicitly set the storage \n" 323 + "type of a group to be Compact or Indexed. \n\n" 324 + "Compact Storage: For groups with only a few links, compact link storage\n" 325 + "allows groups containing only a few links to take up much less space \n" + "in the file. \n\n" 326 + "Indexed Storage: For groups with large number of links, indexed link storage \n" 327 + "provides a faster and more scalable method for storing and working with \n" 328 + "large groups containing many links. \n\n" 329 + "The threshold for switching between the compact and indexed storage \n" 330 + "formats is either set to default values or can be set by the user. \n\n" 331 + "<html><b>Max Compact</b></html> \n" 332 + "Max Compact is the maximum number of links to store in the group in a \n" 333 + "compact format, before converting the group to the Indexed format. Groups \n" 334 + "that are in compact format and in which the number of links rises above \n" 335 + " this threshold are automatically converted to indexed format. \n\n" 336 + "<html><b>Min Indexed</b></html> \n" 337 + "Min Indexed is the minimum number of links to store in the Indexed format. \n" 338 + "Groups which are in indexed format and in which the number of links falls \n" 339 + "below this threshold are automatically converted to compact format. \n\n\n"; 340 JOptionPane.showMessageDialog(this, msg); 341 } 342 343 if (cmd.equals("Ok")) { 344 newObject = create(); 345 if (newObject != null) { 346 dispose(); 347 } 348 } 349 if (cmd.equals("Cancel")) { 350 newObject = null; 351 dispose(); 352 } 353 } 354 355 private HObject create() { 356 String name = null; 357 Group pgroup = null; 358 int gcpl = 0; 359 360 name = nameField.getText(); 361 if (name == null) { 362 toolkit.beep(); 363 JOptionPane.showMessageDialog(this, "Group name is not specified.", getTitle(), JOptionPane.ERROR_MESSAGE); 364 return null; 365 } 366 367 if (name.indexOf(HObject.separator) >= 0) { 368 toolkit.beep(); 369 JOptionPane.showMessageDialog(this, "Group name cannot contain path.", getTitle(), 370 JOptionPane.ERROR_MESSAGE); 371 return null; 372 } 373 374 pgroup = groupList.get(parentChoice.getSelectedIndex()); 375 376 if (pgroup == null) { 377 toolkit.beep(); 378 JOptionPane.showMessageDialog(this, "Parent group is null.", getTitle(), JOptionPane.ERROR_MESSAGE); 379 return null; 380 } 381 382 Group obj = null; 383 384 if (orderFlags.isEnabled()) { 385 String order = (String) orderFlags.getSelectedItem(); 386 if (order.equals("Tracked")) 387 creationOrder = Group.CRT_ORDER_TRACKED; 388 else if (order.equals("Tracked+Indexed")) 389 creationOrder = Group.CRT_ORDER_INDEXED; 390 } 391 else 392 creationOrder = 0; 393 394 if ((orderFlags.isEnabled()) || (setLinkStorage.isSelected())) { 395 int maxCompact = Integer.parseInt(compactField.getText()); 396 int minDense = Integer.parseInt(indexedField.getText()); 397 398 if ((maxCompact <= 0) || (maxCompact > 65536) || (minDense > 65536)) { 399 toolkit.beep(); 400 JOptionPane.showMessageDialog(this, "Max Compact and Min Indexed should be > 0 and < 65536.", 401 getTitle(), JOptionPane.ERROR_MESSAGE); 402 return null; 403 } 404 405 if (maxCompact < minDense) { 406 toolkit.beep(); 407 JOptionPane.showMessageDialog(this, "Min Indexed should be <= Max Compact", getTitle(), 408 JOptionPane.ERROR_MESSAGE); 409 return null; 410 } 411 412 try { 413 gcpl = fileFormat.createGcpl(creationOrder, maxCompact, minDense); 414 } 415 catch (Exception ex) { 416 ex.printStackTrace(); 417 } 418 } 419 420 try { 421 if (isH5) 422 obj = fileFormat.createGroup(name, pgroup, 0, gcpl); 423 else 424 obj = fileFormat.createGroup(name, pgroup); 425 } 426 catch (Exception ex) { 427 toolkit.beep(); 428 JOptionPane.showMessageDialog(this, ex.getMessage(), getTitle(), JOptionPane.ERROR_MESSAGE); 429 return null; 430 } 431 432 return obj; 433 } 434 435 /** 436 * Returns the new group created. 437 * 438 * @return The new group created 439 */ 440 public DataFormat getObject() { 441 return newObject; 442 } 443 444 /** 445 * Returns the parent group of the new group. 446 * 447 * @return The parent group of the new group 448 */ 449 public Group getParentGroup() { 450 return groupList.get(parentChoice.getSelectedIndex()); 451 } 452 453 public void itemStateChanged(ItemEvent e) { 454 Object source = e.getSource(); 455 456 if (source.equals(useCreationOrder)) { 457 boolean isOrder = useCreationOrder.isSelected(); 458 459 if (isOrder) 460 orderFlags.setEnabled(true); 461 else 462 orderFlags.setEnabled(false); 463 } 464 465 if (source.equals(setLinkStorage)) { 466 boolean setStorage = setLinkStorage.isSelected(); 467 468 if (setStorage) { 469 compactField.setEnabled(true); 470 indexedField.setEnabled(true); 471 } 472 else { 473 compactField.setText("8"); 474 compactField.setEnabled(false); 475 indexedField.setText("6"); 476 indexedField.setEnabled(false); 477 } 478 } 479 } 480 481 // Setting the length of the text fields. 482 class JTextFieldLimit extends PlainDocument { 483 private static final long serialVersionUID = -5131438789797052658L; 484 private int limit; 485 486 JTextFieldLimit(int limit) { 487 super(); 488 this.limit = limit; 489 } 490 491 JTextFieldLimit(int limit, boolean upper) { 492 super(); 493 this.limit = limit; 494 } 495 496 public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException { 497 if (str == null) 498 return; 499 500 if ((getLength() + str.length()) <= limit) { 501 super.insertString(offset, str, attr); 502 } 503 } 504 } 505 506 public void keyPressed(java.awt.event.KeyEvent arg0) { 507 } 508 509 public void keyReleased(java.awt.event.KeyEvent arg0) { 510 } 511 512 public void keyTyped(java.awt.event.KeyEvent arg0) { 513 char c = arg0.getKeyChar(); 514 if (!Character.isDigit(c)) 515 arg0.consume(); // prevent event propagation 516 } 517 518}