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 COPYING file, which can be found * 009 * at the root of the source code distribution tree, * 010 * or in https://www.hdfgroup.org/licenses. * 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.dialog; 016 017import java.util.Iterator; 018import java.util.List; 019import java.util.StringTokenizer; 020import java.util.Vector; 021 022import hdf.object.Attribute; 023import hdf.object.Datatype; 024import hdf.object.Group; 025import hdf.object.HObject; 026import hdf.object.h5.H5CompoundAttr; 027import hdf.object.h5.H5Datatype; 028import hdf.view.Tools; 029import hdf.view.ViewProperties; 030 031import org.slf4j.Logger; 032import org.slf4j.LoggerFactory; 033 034import org.eclipse.swt.SWT; 035import org.eclipse.swt.custom.CCombo; 036import org.eclipse.swt.custom.TableEditor; 037import org.eclipse.swt.events.DisposeEvent; 038import org.eclipse.swt.events.DisposeListener; 039import org.eclipse.swt.events.ModifyEvent; 040import org.eclipse.swt.events.ModifyListener; 041import org.eclipse.swt.events.SelectionAdapter; 042import org.eclipse.swt.events.SelectionEvent; 043import org.eclipse.swt.events.TraverseEvent; 044import org.eclipse.swt.events.TraverseListener; 045import org.eclipse.swt.graphics.Point; 046import org.eclipse.swt.graphics.Rectangle; 047import org.eclipse.swt.layout.GridData; 048import org.eclipse.swt.layout.GridLayout; 049import org.eclipse.swt.widgets.Button; 050import org.eclipse.swt.widgets.Combo; 051import org.eclipse.swt.widgets.Composite; 052import org.eclipse.swt.widgets.Display; 053import org.eclipse.swt.widgets.Event; 054import org.eclipse.swt.widgets.Label; 055import org.eclipse.swt.widgets.Listener; 056import org.eclipse.swt.widgets.Shell; 057import org.eclipse.swt.widgets.Table; 058import org.eclipse.swt.widgets.TableColumn; 059import org.eclipse.swt.widgets.TableItem; 060import org.eclipse.swt.widgets.Text; 061 062/** 063 * NewCompoundAttributeDialog shows a message dialog requesting user input for creating 064 * a new HDF5 compound attribute. 065 * 066 * @author Allen Byrne 067 * @version 1.0 7/20/2021 068 */ 069public class NewCompoundAttributeDialog extends NewDataObjectDialog { 070 071 private static final Logger log = LoggerFactory.getLogger(NewCompoundAttributeDialog.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 (32-bit)", // 7 082 "double (64-bit)", // 8 083 "string", // 9 084 "enum", // 10 085 "unsigned long (64-bit)", // 11 086 "float16 (16-bit)", // 12 087 "long double (128-bit)" // 13 088 }; 089 090 private Combo nFieldBox, templateChoice; 091 092 private Vector<H5CompoundAttr> compoundAttrList; 093 094 private int numberOfMembers; 095 096 private Table table; 097 098 private TableEditor[][] editors; 099 100 private Text nameField, currentSizeField; 101 102 private Combo rankChoice; 103 104 /** 105 * Constructs a NewCompoundAttributeDialog with specified list of possible parent 106 * objects. 107 * 108 * @param parent 109 * the parent shell of the dialog 110 * @param pObject 111 * the parent object which the new attribute is attached to. 112 * @param objs 113 * the list of all objects. 114 */ 115 public NewCompoundAttributeDialog(Shell parent, HObject pObject, List<HObject> objs) 116 { 117 super(parent, pObject, objs); 118 119 numberOfMembers = 2; 120 121 compoundAttrList = new Vector<>(objs.size()); 122 } 123 124 /** 125 * Open the NewCompoundAttributeDialog for adding a new compound attribute. 126 */ 127 public void open() 128 { 129 Shell parent = getParent(); 130 shell = new Shell(parent, SWT.SHELL_TRIM | SWT.APPLICATION_MODAL); 131 shell.setFont(curFont); 132 shell.setText("New Compound Attribute..."); 133 shell.setImages(ViewProperties.getHdfIcons()); 134 shell.setLayout(new GridLayout(1, false)); 135 136 // Create Name/Parent Object/Import field region 137 Composite fieldComposite = new Composite(shell, SWT.NONE); 138 GridLayout layout = new GridLayout(2, false); 139 layout.verticalSpacing = 0; 140 fieldComposite.setLayout(layout); 141 fieldComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 142 143 Label attributeNameLabel = new Label(fieldComposite, SWT.LEFT); 144 attributeNameLabel.setFont(curFont); 145 attributeNameLabel.setText("Attribute name: "); 146 147 nameField = new Text(fieldComposite, SWT.SINGLE | SWT.BORDER); 148 nameField.setFont(curFont); 149 nameField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 150 151 // Create Dataspace region 152 org.eclipse.swt.widgets.Group dataspaceGroup = new org.eclipse.swt.widgets.Group(shell, SWT.NONE); 153 dataspaceGroup.setFont(curFont); 154 dataspaceGroup.setText("Dataspace"); 155 dataspaceGroup.setLayout(new GridLayout(3, true)); 156 dataspaceGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 157 158 Label label = new Label(dataspaceGroup, SWT.LEFT); 159 label.setFont(curFont); 160 label.setText("No. of dimensions"); 161 162 label = new Label(dataspaceGroup, SWT.LEFT); 163 label.setFont(curFont); 164 label.setText("Current size"); 165 166 // Dummy label 167 label = new Label(dataspaceGroup, SWT.LEFT); 168 label.setFont(curFont); 169 label.setText(""); 170 171 rankChoice = new Combo(dataspaceGroup, SWT.DROP_DOWN | SWT.READ_ONLY); 172 rankChoice.setFont(curFont); 173 rankChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 174 rankChoice.addSelectionListener(new SelectionAdapter() { 175 @Override 176 public void widgetSelected(SelectionEvent e) 177 { 178 int rank = rankChoice.getSelectionIndex() + 1; 179 StringBuilder currentSizeStr = new StringBuilder("1"); 180 181 for (int i = 1; i < rank; i++) { 182 currentSizeStr.append(" x 1"); 183 } 184 185 currentSizeField.setText(currentSizeStr.toString()); 186 187 String currentStr = currentSizeField.getText(); 188 int idx = currentStr.lastIndexOf('x'); 189 } 190 }); 191 192 for (int i = 1; i < 33; i++) { 193 rankChoice.add(String.valueOf(i)); 194 } 195 rankChoice.select(1); 196 197 currentSizeField = new Text(dataspaceGroup, SWT.SINGLE | SWT.BORDER); 198 currentSizeField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 199 currentSizeField.setFont(curFont); 200 currentSizeField.setText("1 x 1"); 201 202 // Create Properties region 203 org.eclipse.swt.widgets.Group propertiesGroup = new org.eclipse.swt.widgets.Group(shell, SWT.NONE); 204 propertiesGroup.setLayout(new GridLayout(2, false)); 205 propertiesGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 206 propertiesGroup.setFont(curFont); 207 propertiesGroup.setText("Compound Datatype Properties"); 208 209 label = new Label(propertiesGroup, SWT.LEFT); 210 label.setFont(curFont); 211 label.setText("Number of Members:"); 212 213 nFieldBox = new Combo(propertiesGroup, SWT.DROP_DOWN); 214 nFieldBox.setFont(curFont); 215 nFieldBox.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 216 nFieldBox.addSelectionListener(new SelectionAdapter() { 217 @Override 218 public void widgetSelected(SelectionEvent e) 219 { 220 updateMemberTableItems(); 221 } 222 }); 223 nFieldBox.addTraverseListener(new TraverseListener() { 224 @Override 225 public void keyTraversed(TraverseEvent e) 226 { 227 if (e.detail == SWT.TRAVERSE_RETURN) 228 updateMemberTableItems(); 229 } 230 }); 231 232 for (int i = 1; i <= 100; i++) { 233 nFieldBox.add(String.valueOf(i)); 234 } 235 236 table = new Table(propertiesGroup, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); 237 table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); 238 table.setLinesVisible(false); 239 table.setHeaderVisible(true); 240 table.setFont(curFont); 241 242 editors = new TableEditor[nFieldBox.getItemCount()][3]; 243 244 String[] colNames = {"Name", "Datatype", "Array size / String length / Enum names"}; 245 246 TableColumn column = new TableColumn(table, SWT.NONE); 247 column.setText(colNames[0]); 248 249 column = new TableColumn(table, SWT.NONE); 250 column.setText(colNames[1]); 251 252 column = new TableColumn(table, SWT.NONE); 253 column.setText(colNames[2]); 254 255 for (int i = 0; i < 2; i++) { 256 TableEditor[] editor = addMemberTableItem(table); 257 editors[i][0] = editor[0]; 258 editors[i][1] = editor[1]; 259 editors[i][2] = editor[2]; 260 } 261 262 for (int i = 0; i < table.getColumnCount(); i++) { 263 table.getColumn(i).pack(); 264 } 265 266 // Last table column always expands to fill remaining table size 267 table.addListener(SWT.Resize, new Listener() { 268 @Override 269 public void handleEvent(Event e) 270 { 271 Table table = (Table)e.widget; 272 Rectangle area = table.getClientArea(); 273 int columnCount = table.getColumnCount(); 274 int totalGridLineWidth = (columnCount - 1) * table.getGridLineWidth(); 275 276 int totalColumnWidth = 0; 277 for (TableColumn column : table.getColumns()) { 278 totalColumnWidth += column.getWidth(); 279 } 280 281 int diff = area.width - (totalColumnWidth + totalGridLineWidth); 282 283 TableColumn col = table.getColumns()[columnCount - 1]; 284 col.setWidth(diff + col.getWidth()); 285 } 286 }); 287 288 // Disable table selection highlighting 289 table.addListener(SWT.EraseItem, new Listener() { 290 @Override 291 public void handleEvent(Event e) 292 { 293 if ((e.detail & SWT.SELECTED) != 0) { 294 e.detail &= ~SWT.SELECTED; 295 } 296 } 297 }); 298 299 // Create Ok/Cancel button region 300 Composite buttonComposite = new Composite(shell, SWT.NONE); 301 buttonComposite.setLayout(new GridLayout(2, true)); 302 buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); 303 304 Button okButton = new Button(buttonComposite, SWT.PUSH); 305 okButton.setFont(curFont); 306 okButton.setText(" &OK "); 307 okButton.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false)); 308 okButton.addSelectionListener(new SelectionAdapter() { 309 @Override 310 public void widgetSelected(SelectionEvent e) 311 { 312 if (createAttribute()) { 313 shell.dispose(); 314 } 315 } 316 }); 317 318 Button cancelButton = new Button(buttonComposite, SWT.PUSH); 319 cancelButton.setFont(curFont); 320 cancelButton.setText(" &Cancel "); 321 cancelButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, true, false)); 322 cancelButton.addSelectionListener(new SelectionAdapter() { 323 @Override 324 public void widgetSelected(SelectionEvent e) 325 { 326 newObject = null; 327 shell.dispose(); 328 } 329 }); 330 331 rankChoice.select(0); 332 nFieldBox.select(nFieldBox.indexOf(String.valueOf(numberOfMembers))); 333 334 shell.pack(); 335 336 table.getColumn(0).setWidth(table.getClientArea().width / 3); 337 table.getColumn(1).setWidth(table.getClientArea().width / 3); 338 339 shell.addDisposeListener(new DisposeListener() { 340 @Override 341 public void widgetDisposed(DisposeEvent e) 342 { 343 if (curFont != null) 344 curFont.dispose(); 345 } 346 }); 347 348 shell.setMinimumSize(shell.computeSize(SWT.DEFAULT, SWT.DEFAULT)); 349 350 Rectangle parentBounds = parent.getBounds(); 351 Point shellSize = shell.getSize(); 352 shell.setLocation((parentBounds.x + (parentBounds.width / 2)) - (shellSize.x / 2), 353 (parentBounds.y + (parentBounds.height / 2)) - (shellSize.y / 2)); 354 355 shell.open(); 356 357 Display display = shell.getDisplay(); 358 while (!shell.isDisposed()) 359 if (!display.readAndDispatch()) 360 display.sleep(); 361 } 362 363 @SuppressWarnings("unchecked") 364 private boolean createAttribute() 365 { 366 String attrName = null; 367 int rank = -1; 368 long[] dims; 369 370 attrName = nameField.getText(); 371 if (attrName != null) { 372 attrName = attrName.trim(); 373 } 374 375 if ((attrName == null) || (attrName.length() < 1)) { 376 shell.getDisplay().beep(); 377 Tools.showError(shell, "Create", "Attribute name is not specified."); 378 return false; 379 } 380 381 int n = table.getItemCount(); 382 if (n <= 0) { 383 return false; 384 } 385 386 String[] mNames = new String[n]; 387 Datatype[] mDatatypes = new Datatype[n]; 388 int[] mOrders = new int[n]; 389 390 for (int i = 0; i < n; i++) { 391 String name = (String)table.getItem(i).getData("MemberName"); 392 if ((name == null) || (name.length() <= 0)) { 393 throw new IllegalArgumentException("Member name is empty"); 394 } 395 mNames[i] = name; 396 log.trace("createCompoundAttribute member[{}] name = {}", i, mNames[i]); 397 398 int order = 1; 399 String orderStr = (String)table.getItem(i).getData("MemberSize"); 400 if (orderStr != null) { 401 try { 402 order = Integer.parseInt(orderStr); 403 } 404 catch (Exception ex) { 405 log.debug("compound order:", ex); 406 } 407 } 408 mOrders[i] = order; 409 410 String typeName = (String)table.getItem(i).getData("MemberType"); 411 log.trace("createCompoundAttribute type[{}] name = {}", i, typeName); 412 Datatype type = null; 413 try { 414 if (DATATYPE_NAMES[0].equals(typeName)) { 415 type = fileFormat.createDatatype(Datatype.CLASS_INTEGER, 1, Datatype.NATIVE, 416 Datatype.NATIVE); 417 } 418 else if (DATATYPE_NAMES[1].equals(typeName)) { 419 type = fileFormat.createDatatype(Datatype.CLASS_INTEGER, 2, Datatype.NATIVE, 420 Datatype.NATIVE); 421 } 422 else if (DATATYPE_NAMES[2].equals(typeName)) { 423 type = fileFormat.createDatatype(Datatype.CLASS_INTEGER, 4, Datatype.NATIVE, 424 Datatype.NATIVE); 425 } 426 else if (DATATYPE_NAMES[3].equals(typeName)) { 427 type = fileFormat.createDatatype(Datatype.CLASS_INTEGER, 1, Datatype.NATIVE, 428 Datatype.SIGN_NONE); 429 } 430 else if (DATATYPE_NAMES[4].equals(typeName)) { 431 type = fileFormat.createDatatype(Datatype.CLASS_INTEGER, 2, Datatype.NATIVE, 432 Datatype.SIGN_NONE); 433 } 434 else if (DATATYPE_NAMES[5].equals(typeName)) { 435 type = fileFormat.createDatatype(Datatype.CLASS_INTEGER, 4, Datatype.NATIVE, 436 Datatype.SIGN_NONE); 437 } 438 else if (DATATYPE_NAMES[6].equals(typeName)) { 439 type = fileFormat.createDatatype(Datatype.CLASS_INTEGER, 8, Datatype.NATIVE, 440 Datatype.NATIVE); 441 } 442 else if (DATATYPE_NAMES[7].equals(typeName)) { 443 type = 444 fileFormat.createDatatype(Datatype.CLASS_FLOAT, 4, Datatype.NATIVE, Datatype.NATIVE); 445 } 446 else if (DATATYPE_NAMES[8].equals(typeName)) { 447 type = 448 fileFormat.createDatatype(Datatype.CLASS_FLOAT, 8, Datatype.NATIVE, Datatype.NATIVE); 449 } 450 else if (DATATYPE_NAMES[9].equals(typeName)) { 451 type = fileFormat.createDatatype(Datatype.CLASS_STRING, order, Datatype.NATIVE, 452 Datatype.NATIVE); 453 } 454 else if (DATATYPE_NAMES[10].equals(typeName)) { // enum 455 type = 456 fileFormat.createDatatype(Datatype.CLASS_ENUM, 4, Datatype.NATIVE, Datatype.NATIVE); 457 if ((orderStr == null) || (orderStr.length() < 1) || orderStr.endsWith("...")) { 458 shell.getDisplay().beep(); 459 Tools.showError(shell, "Create", "Invalid member values: " + orderStr); 460 return false; 461 } 462 else { 463 type.setEnumMembers(orderStr); 464 } 465 } 466 else if (DATATYPE_NAMES[11].equals(typeName)) { 467 type = fileFormat.createDatatype(Datatype.CLASS_INTEGER, 8, Datatype.NATIVE, 468 Datatype.SIGN_NONE); 469 } 470 else if (DATATYPE_NAMES[12].equals(typeName)) { 471 type = 472 fileFormat.createDatatype(Datatype.CLASS_FLOAT, 2, Datatype.NATIVE, Datatype.NATIVE); 473 } 474 else if (DATATYPE_NAMES[13].equals(typeName)) { 475 type = 476 fileFormat.createDatatype(Datatype.CLASS_FLOAT, 16, Datatype.NATIVE, Datatype.NATIVE); 477 } 478 else { 479 throw new IllegalArgumentException("Invalid data type."); 480 } 481 mDatatypes[i] = type; 482 } 483 catch (Exception ex) { 484 Tools.showError(shell, "Create", ex.getMessage()); 485 log.debug("createAttribute(): ", ex); 486 return false; 487 } 488 } // (int i=0; i<n; i++) 489 490 rank = rankChoice.getSelectionIndex() + 1; 491 log.trace("createCompoundAttribute rank={}", rank); 492 StringTokenizer st = new StringTokenizer(currentSizeField.getText(), "x"); 493 if (st.countTokens() < rank) { 494 shell.getDisplay().beep(); 495 Tools.showError(shell, "Create", 496 "Number of values in the current dimension size is less than " + rank); 497 return false; 498 } 499 500 long lsize = 1; // The total size 501 long l = 0; 502 dims = new long[rank]; 503 String token = null; 504 for (int i = 0; i < rank; i++) { 505 token = st.nextToken().trim(); 506 try { 507 l = Long.parseLong(token); 508 } 509 catch (NumberFormatException ex) { 510 shell.getDisplay().beep(); 511 Tools.showError(shell, "Create", "Invalid dimension size: " + currentSizeField.getText()); 512 return false; 513 } 514 515 if (l <= 0) { 516 shell.getDisplay().beep(); 517 Tools.showError(shell, "Create", "Dimension size must be greater than zero."); 518 return false; 519 } 520 521 dims[i] = l; 522 lsize *= l; 523 } 524 log.trace("Create: lsize={}", lsize); 525 526 Attribute attr = null; 527 try { 528 H5Datatype datatype = (H5Datatype)createNewDatatype(null); 529 530 attr = (Attribute) new H5CompoundAttr(parentObj, attrName, datatype, dims); 531 Object value = H5Datatype.allocateArray(datatype, (int)lsize); 532 attr.setAttributeData(value); 533 534 log.trace("writeMetadata() via write()"); 535 attr.writeAttribute(); 536 } 537 catch (Exception ex) { 538 Tools.showError(shell, "Create", ex.getMessage()); 539 log.debug("createAttribute(): ", ex); 540 return false; 541 } 542 543 newObject = (HObject)attr; 544 545 return true; 546 } 547 548 private void updateMemberTableItems() 549 { 550 int n = 0; 551 552 try { 553 n = Integer.valueOf(nFieldBox.getItem(nFieldBox.getSelectionIndex())).intValue(); 554 } 555 catch (Exception ex) { 556 log.debug("Change number of members:", ex); 557 return; 558 } 559 560 if (n == numberOfMembers) { 561 return; 562 } 563 564 if (n > numberOfMembers) { 565 try { 566 for (int i = numberOfMembers; i < n; i++) { 567 TableEditor[] editor = addMemberTableItem(table); 568 editors[i][0] = editor[0]; 569 editors[i][1] = editor[1]; 570 editors[i][2] = editor[2]; 571 } 572 } 573 catch (Exception ex) { 574 log.debug("Error adding member table items: ", ex); 575 return; 576 } 577 } 578 else { 579 try { 580 for (int i = numberOfMembers - 1; i >= n; i--) { 581 table.remove(i); 582 } 583 } 584 catch (Exception ex) { 585 log.debug("Error removing member table items: ", ex); 586 return; 587 } 588 } 589 590 table.setItemCount(n); 591 numberOfMembers = n; 592 } 593 594 private TableEditor[] addMemberTableItem(Table table) 595 { 596 final TableItem item = new TableItem(table, SWT.NONE); 597 final TableEditor[] editor = new TableEditor[3]; 598 599 for (int i = 0; i < editor.length; i++) 600 editor[i] = new TableEditor(table); 601 602 final Text nameText = new Text(table, SWT.SINGLE | SWT.BORDER); 603 nameText.setFont(curFont); 604 605 editor[0].grabHorizontal = true; 606 editor[0].grabVertical = true; 607 editor[0].horizontalAlignment = SWT.LEFT; 608 editor[0].verticalAlignment = SWT.TOP; 609 editor[0].setEditor(nameText, item, 0); 610 611 nameText.addModifyListener(new ModifyListener() { 612 @Override 613 public void modifyText(ModifyEvent e) 614 { 615 Text text = (Text)e.widget; 616 item.setData("MemberName", text.getText()); 617 } 618 }); 619 620 final CCombo typeCombo = new CCombo(table, SWT.DROP_DOWN | SWT.READ_ONLY); 621 typeCombo.setFont(curFont); 622 typeCombo.setItems(DATATYPE_NAMES); 623 624 editor[1].grabHorizontal = true; 625 editor[1].grabVertical = true; 626 editor[1].horizontalAlignment = SWT.LEFT; 627 editor[1].verticalAlignment = SWT.TOP; 628 editor[1].setEditor(typeCombo, item, 1); 629 630 typeCombo.addSelectionListener(new SelectionAdapter() { 631 @Override 632 public void widgetSelected(SelectionEvent e) 633 { 634 CCombo combo = (CCombo)e.widget; 635 item.setData("MemberType", combo.getItem(combo.getSelectionIndex())); 636 } 637 }); 638 639 final Text sizeText = new Text(table, SWT.SINGLE | SWT.BORDER); 640 sizeText.setFont(curFont); 641 642 editor[2].grabHorizontal = true; 643 editor[2].grabVertical = true; 644 editor[2].horizontalAlignment = SWT.LEFT; 645 editor[2].verticalAlignment = SWT.TOP; 646 editor[2].setEditor(sizeText, item, 2); 647 648 sizeText.addModifyListener(new ModifyListener() { 649 @Override 650 public void modifyText(ModifyEvent e) 651 { 652 Text text = (Text)e.widget; 653 item.setData("MemberSize", text.getText()); 654 } 655 }); 656 657 item.setData("MemberName", ""); 658 item.setData("MemberType", ""); 659 item.setData("MemberSize", ""); 660 661 item.addDisposeListener(new DisposeListener() { 662 @Override 663 public void widgetDisposed(DisposeEvent e) 664 { 665 editor[0].dispose(); 666 editor[1].dispose(); 667 editor[2].dispose(); 668 nameText.dispose(); 669 typeCombo.dispose(); 670 sizeText.dispose(); 671 } 672 }); 673 674 return editor; 675 } 676}