001 /*
002 * Copyright (c) 1995-2010, The University of Sheffield. See the file
003 * COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
004 *
005 * This file is part of GATE (see http://gate.ac.uk/), and is free
006 * software, licenced under the GNU Library General Public License,
007 * Version 2, June 1991 (in the distribution as file licence.html,
008 * and also available at http://gate.ac.uk/gate/licence.html).
009 *
010 * Valentin Tablan 03/10/2001
011 *
012 * $Id: ResourceParametersEditor.java 12494 2010-04-15 15:30:11Z thomas_heitz $
013 *
014 */
015
016 package gate.gui;
017
018 import java.awt.*;
019 import java.awt.event.*;
020 import java.io.IOException;
021 import java.lang.reflect.Method;
022 import java.util.*;
023 import java.util.List;
024
025 import javax.swing.*;
026 import javax.swing.event.ChangeEvent;
027 import javax.swing.table.*;
028
029 import gate.*;
030 import gate.creole.*;
031 import gate.event.CreoleEvent;
032 import gate.event.CreoleListener;
033 import gate.swing.XJTable;
034 import gate.swing.XJFileChooser;
035 import gate.util.*;
036
037 /**
038 * Allows the editing of a set of parameters for a resource. It needs a
039 * pointer to the resource and a list of the parameter names for the
040 * parameters that should be displayed. The list of the parameters is
041 * actually a list of lists of strings representing parameter
042 * disjunctions.
043 */
044 public class ResourceParametersEditor extends XJTable implements CreoleListener {
045
046 public ResourceParametersEditor() {
047 initLocalData();
048 initGuiComponents();
049 initListeners();
050 setSortable(true);
051 setSortedColumn(0);
052 setComparator(0, new ParameterDisjunctionComparator());
053 setTabSkipUneditableCell(true);
054 setEditCellAsSoonAsFocus(true);
055 }
056
057 /**
058 * Initialises this GUI component.
059 *
060 * @param resource the resource for which the parameters need to be
061 * set.
062 * @param parameters a list of lists of {@link Parameter} representing
063 * parameter disjunctions.
064 */
065 public void init(Resource resource, List parameters) {
066 cleanup();
067 this.resource = resource;
068 if(parameters != null) {
069 parameterDisjunctions = new ArrayList<ParameterDisjunction>(parameters.size());
070 for(int i = 0; i < parameters.size(); i++) {
071 parameterDisjunctions.add(new ParameterDisjunction(resource,
072 (List)parameters.get(i)));
073 }
074 }
075 else {
076 parameterDisjunctions = null;
077 }
078 tableModel.fireTableDataChanged();
079 fileChooser = MainFrame.getFileChooser();
080 // must be saved now as it will be reset when the file chooser is hidden
081 fileChooserResource = (resource != null) ?
082 resource.getClass().getName() : fileChooser.getResource();
083 }
084
085 protected void initLocalData() {
086 resource = null;
087 parameterDisjunctions = null;
088 }// protected void initLocalData()
089
090 protected void initGuiComponents() {
091 setModel(tableModel = new ParametersTableModel());
092 getColumnModel().getColumn(0).setCellRenderer(
093 new ParameterDisjunctionRenderer());
094 getColumnModel().getColumn(2).setCellRenderer(new DefaultTableCellRenderer());
095 getColumnModel().getColumn(2).setCellRenderer(new BooleanRenderer());
096 getColumnModel().getColumn(3).setCellRenderer(new ParameterValueRenderer());
097 getColumnModel().getColumn(0).setCellEditor(
098 new ParameterDisjunctionEditor());
099 getColumnModel().getColumn(3).setCellEditor(new ParameterValueEditor());
100 setAutoResizeMode(AUTO_RESIZE_LAST_COLUMN);
101
102 setSurrendersFocusOnKeystroke(true);
103 }// protected void initGuiComponents()
104
105 protected void initListeners() {
106 Gate.getCreoleRegister().addCreoleListener(this);
107 }
108
109 /**
110 * Cleans the internal data and prepares this object to be collected
111 */
112 public void cleanup() {
113 Gate.getCreoleRegister().removeCreoleListener(this);
114 if(parameterDisjunctions != null && parameterDisjunctions.size() > 0) {
115 for(int i = 0; i < parameterDisjunctions.size(); i++) {
116 parameterDisjunctions.get(i).cleanup();
117 }
118 }
119 resource = null;
120 }
121
122 /**
123 * Sets the parameters for the resource to their new values as
124 * resulted from the user's edits.
125 */
126 public void setParameters() throws ResourceInstantiationException {
127 if(resource == null || parameterDisjunctions == null) return;
128 // stop current edits
129 if(getEditingColumn() != -1 && getEditingRow() != -1) {
130 editingStopped(new ChangeEvent(getCellEditor(getEditingRow(),
131 getEditingColumn())));
132 }
133 // set the parameters
134 for(int i = 0; i < parameterDisjunctions.size(); i++) {
135 ParameterDisjunction pDisj = parameterDisjunctions
136 .get(i);
137 resource.setParameterValue(pDisj.getName(), pDisj.getValue());
138 }
139 }
140
141 /**
142 * Does this GUI component allow editing?
143 */
144
145 public Resource getResource() {
146 return resource;
147 }
148
149 /**
150 * Gets the current values for the parameters.
151 *
152 * @return a {@link FeatureMap} containing the curent values for the
153 * currently selected parameters in each disjunction.
154 */
155 public FeatureMap getParameterValues() {
156 // stop current edits
157 if(getEditingColumn() != -1 && getEditingRow() != -1) {
158 editingStopped(new ChangeEvent(getCellEditor(getEditingRow(),
159 getEditingColumn())));
160 }
161 // get the parameters
162 FeatureMap values = Factory.newFeatureMap();
163 if(parameterDisjunctions != null) {
164 for(int i = 0; i < parameterDisjunctions.size(); i++) {
165 ParameterDisjunction pDisj = parameterDisjunctions.get(i);
166 values.put(pDisj.getName(), pDisj.getValue());
167 }
168 }
169 return values;
170 }
171
172 public void resourceLoaded(CreoleEvent e) {
173 repaint();
174 }
175
176 public void resourceUnloaded(CreoleEvent e) {
177 repaint();
178 }
179
180 public void resourceRenamed(Resource resource, String oldName, String newName) {
181 repaint();
182 }
183
184 public void datastoreOpened(CreoleEvent e) {
185 }
186
187 public void datastoreCreated(CreoleEvent e) {
188 }
189
190 public void datastoreClosed(CreoleEvent e) {
191 }
192
193 public void setEditable(boolean editable) {
194 this.editable = editable;
195 }
196
197 public boolean isEditable() {
198 return editable;
199 }
200
201 /**
202 * Called by other GUI classes that use this as a subcomponent that
203 * doesn't need to update with the creole register changes.
204 */
205 void removeCreoleListenerLink() {
206 // this component is only used as a viewer now; it doesn't need to
207 // update
208 // so we don't need to listen to creole events
209 Gate.getCreoleRegister().removeCreoleListener(this);
210 if(parameterDisjunctions != null && parameterDisjunctions.size() > 0) {
211 for(int i = 0; i < parameterDisjunctions.size(); i++) {
212 parameterDisjunctions.get(i).removeCreoleListenerLink();
213 }
214 }
215
216 }
217
218 ParametersTableModel tableModel;
219
220 Resource resource;
221
222 /**
223 * A pointer to the filechooser from MainFrame.
224 */
225 static XJFileChooser fileChooser;
226
227 String fileChooserResource;
228
229 /**
230 * A list of {@link ParameterDisjunction}
231 */
232 protected List<ParameterDisjunction> parameterDisjunctions;
233
234 protected boolean editable = true;
235
236 // inner classes
237 protected class ParametersTableModel extends AbstractTableModel {
238
239 public int getColumnCount() {
240 return 4;
241 }
242
243 public Class getColumnClass(int columnIndex) {
244 switch(columnIndex) {
245 case 0:
246 return ParameterDisjunction.class;
247 case 1:
248 return String.class;
249 case 2:
250 return Boolean.class;
251 case 3:
252 return Object.class;
253 default:
254 return Object.class;
255 }
256 }// public Class getColumnClass(int columnIndex)
257
258 public String getColumnName(int columnIndex) {
259 switch(columnIndex) {
260 case 0:
261 return "Name";
262 case 1:
263 return "Type";
264 case 2:
265 return "Required";
266 case 3:
267 return "Value";
268 default:
269 return "?";
270 }
271 }// public String getColumnName(int columnIndex)
272
273 public boolean isCellEditable(int rowIndex, int columnIndex) {
274 switch(columnIndex) {
275 case 0:
276 return parameterDisjunctions.get(rowIndex).size() > 1;
277 case 1:
278 return false;
279 case 2:
280 return false;
281 case 3:
282 return editable;
283 default:
284 return false;
285 }
286 }// public boolean isCellEditable
287
288 public int getRowCount() {
289 return (parameterDisjunctions == null) ? 0 : parameterDisjunctions.size();
290 }
291
292 public Object getValueAt(int rowIndex, int columnIndex) {
293 ParameterDisjunction pDisj = parameterDisjunctions.get(rowIndex);
294 switch(columnIndex) {
295 case 0:
296 return pDisj;
297 case 1:
298 String paramType = pDisj.getType();
299 return paramType.substring(paramType.lastIndexOf('.') + 1);
300 case 2:
301 return pDisj.isRequired();
302 case 3:
303 return pDisj.getValue();
304 default:
305 return "?";
306 }
307 }// public Object getValueAt
308
309 public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
310 ParameterDisjunction pDisj = parameterDisjunctions.get(rowIndex);
311 switch(columnIndex) {
312 case 0: {
313 if(aValue instanceof ParameterDisjunction){
314 //do nothing
315 } else if (aValue instanceof Integer){
316 pDisj.setSelectedIndex((Integer) aValue);
317 }
318 break;
319 }
320 case 1: {
321 break;
322 }
323 case 2: {
324 break;
325 }
326 case 3: {
327 pDisj.setValue(aValue);
328 break;
329 }
330 default: {
331 }
332 }
333 tableModel.fireTableCellUpdated(rowIndex, columnIndex);
334 }// public void setValueAt
335 }// /class FeaturesTableModel extends DefaultTableModel
336
337 class ParameterDisjunctionRenderer extends DefaultTableCellRenderer {
338 public ParameterDisjunctionRenderer() {
339 combo = new JComboBox();
340 class CustomRenderer extends JLabel implements ListCellRenderer {
341 public Component getListCellRendererComponent(JList list, Object value,
342 int index, boolean isSelected, boolean cellHasFocus) {
343
344 setText(text);
345 setIcon(MainFrame.getIcon(iconName));
346 return this;
347 }
348 }
349 combo.setRenderer(new CustomRenderer());
350 }
351
352 public Component getTableCellRendererComponent(JTable table, Object value,
353 boolean isSelected, boolean hasFocus, int row, int column) {
354 ParameterDisjunction pDisj = (ParameterDisjunction)value;
355 text = pDisj.getName();
356 String type = pDisj.getType();
357 iconName = "param";
358 if(Gate.isGateType(type)) {
359 ResourceData rData = Gate.getCreoleRegister().get(type);
360 if(rData != null) iconName = rData.getIcon();
361 }
362 if(pDisj.size() > 1) {
363 combo.setModel(new DefaultComboBoxModel(new Object[] {text}));
364 return combo;
365 }
366 // prepare the renderer
367 super.getTableCellRendererComponent(table, text, isSelected,
368 hasFocus, row, column);
369 setIcon(MainFrame.getIcon(iconName));
370 return this;
371 }// public Component getTableCellRendererComponent
372
373 // combobox used for OR parameters
374 JComboBox combo;
375
376 String iconName;
377
378 String text;
379 }// class ParameterDisjunctionRenderer
380
381 /**
382 * A renderer that displays a File Open button next to a text field.
383 * Used for setting URLs from files.
384 */
385 class ParameterValueRenderer extends DefaultTableCellRenderer {
386 public ParameterValueRenderer() {
387 fileButton = new JButton(MainFrame.getIcon("open-file"));
388 fileButton.setToolTipText("Browse the file system");
389 listButton = new JButton(MainFrame.getIcon("edit-list"));
390 listButton.setToolTipText("Edit the list");
391 fmButton = new JButton(MainFrame.getIcon("edit-list"));
392 fmButton.setToolTipText("Edit the feature map");
393 textField = new JTextField(25){
394 @Override
395 public Dimension getMinimumSize() {
396 //we don't want to be squashed!
397 return getPreferredSize();
398 }
399
400 };
401 textButtonBox = new JPanel();
402 textButtonBox.setLayout(new BoxLayout(textButtonBox, BoxLayout.X_AXIS));
403 textButtonBox.setOpaque(false);
404 combo = new JComboBox();
405 combo.setRenderer(new ResourceRenderer());
406 }// CustomObjectRenderer()
407
408 public Component getTableCellRendererComponent(JTable table, Object value,
409 boolean isSelected, boolean hasFocus, int row, int column) {
410
411 ParameterDisjunction pDisj = (ParameterDisjunction)table
412 .getValueAt(row, convertColumnIndexToView(0));
413 String type = pDisj.getType();
414 // set the tooltip
415 combo.setToolTipText(pDisj.getComment());
416 textField.setToolTipText(pDisj.getComment());
417 textButtonBox.setToolTipText(pDisj.getComment());
418
419 if(Gate.isGateType(type)) {
420 // Gate type
421 if(ResourceParametersEditor.this.isEditable()) {
422 combo.setModel(new DefaultComboBoxModel(new Object[] {value == null
423 ? "<none>"
424 : value}));
425 return combo;
426 }
427 else {
428 // not editable; we'll just use the text field
429 // prepare the renderer
430 String text = value == null ? "<none>" : value.toString();
431 // super.getTableCellRendererComponent(table, text,
432 // isSelected,
433 // hasFocus, row, column);
434 textField.setText(text);
435 return textField;
436 }
437 }
438 else {
439 Class typeClass = null;
440 try {
441 // load type class through GATE classloader
442 typeClass = Class.forName(type, true, Gate.getClassLoader());
443 }
444 catch(ClassNotFoundException cnfe) {
445 cnfe.printStackTrace();
446 }
447 // non Gate type -> we'll use the text field
448 String text = (value == null)
449 ? ""
450 : value.toString();
451 // prepare the renderer
452 textField.setText(text);
453 // super.getTableCellRendererComponent(table, text, isSelected,
454 // hasFocus, row, column);
455
456 if(type.equals("java.net.URL")) {
457 if(ResourceParametersEditor.this.isEditable()) {
458 textButtonBox.removeAll();
459 textField.setText(text);
460 // textButtonBox.add(this);
461 textButtonBox.add(textField);
462 // this.setMaximumSize(new Dimension(Integer.MAX_VALUE,
463 // getPreferredSize().height));
464 textButtonBox.add(Box.createHorizontalStrut(5));
465 textButtonBox.add(fileButton);
466 return textButtonBox;
467 }
468 else {
469 // return this;
470 return textField;
471 }
472 }
473 else if(typeClass != null
474 && Collection.class.isAssignableFrom(typeClass)) {
475 // List value
476 // setText(textForList((List)value));
477 textField.setText(textForList((Collection)value));
478 if(ResourceParametersEditor.this.isEditable()) {
479 textButtonBox.removeAll();
480 // textButtonBox.add(this);
481 textButtonBox.add(textField);
482 // this.setMaximumSize(new Dimension(Integer.MAX_VALUE,
483 // getPreferredSize().height));
484 textButtonBox.add(Box.createHorizontalStrut(5));
485 textButtonBox.add(listButton);
486 return textButtonBox;
487 }
488 }
489 else if(typeClass != null
490 && FeatureMap.class.isAssignableFrom(typeClass)) {
491 textField.setText(textForFeatureMap((FeatureMap)value));
492 if(ResourceParametersEditor.this.isEditable()) {
493 textButtonBox.removeAll();
494 textButtonBox.add(textField);
495 textButtonBox.add(Box.createHorizontalStrut(5));
496 textButtonBox.add(fmButton);
497 return textButtonBox;
498 }
499 }
500 else if(typeClass != null && typeClass.isEnum()) {
501 if(ResourceParametersEditor.this.isEditable()) {
502 combo.setModel(new DefaultComboBoxModel(new Object[] {value == null
503 ? "<none>"
504 : value}));
505 return combo;
506 }
507 else {
508 return textField;
509 }
510 }
511 else {
512 // return this;
513 return textField;
514 }
515
516 // not actually reachable, but keeps the compiler happy
517 return textField;
518 }
519 }// public Component getTableCellRendererComponent
520
521
522 JButton fileButton;
523
524 JButton listButton;
525
526 JButton fmButton;
527
528 JComboBox combo;
529
530 JPanel textButtonBox;
531
532 JTextField textField;
533 }// class ObjectRenderer extends DefaultTableCellRenderer
534
535 class ParameterDisjunctionComparator implements Comparator {
536 public int compare(Object o1, Object o2) {
537 ParameterDisjunction pDisj1 = (ParameterDisjunction)o1;
538 ParameterDisjunction pDisj2 = (ParameterDisjunction)o2;
539 return pDisj1.getName().compareTo(pDisj2.getName());
540 }
541 }
542
543 class ParameterDisjunctionEditor extends DefaultCellEditor {
544 public ParameterDisjunctionEditor() {
545 super(new JComboBox());
546 combo = (JComboBox)super.getComponent();
547 class CustomRenderer extends JLabel implements ListCellRenderer {
548 public CustomRenderer() {
549 setOpaque(true);
550 }
551
552 public Component getListCellRendererComponent(JList list, Object value,
553 int index, boolean isSelected, boolean cellHasFocus) {
554 if(isSelected) {
555 setBackground(list.getSelectionBackground());
556 setForeground(list.getSelectionForeground());
557 }
558 else {
559 setBackground(list.getBackground());
560 setForeground(list.getForeground());
561 }
562
563 setFont(list.getFont());
564
565 setText((String)value);
566
567 String iconName = "param";
568 Parameter[] params = pDisj.getParameters();
569 for(int i = 0; i < params.length; i++) {
570 Parameter param = params[i];
571 if(param.getName().equals(value)) {
572 String type = param.getTypeName();
573 if(Gate.getCreoleRegister().containsKey(type)) {
574 ResourceData rData = Gate.getCreoleRegister()
575 .get(type);
576 if(rData != null) iconName = rData.getIcon();
577 }
578 break;
579 }// if(params[i].getName().equals(value))
580 }// for(int i = 0; params.length; i++)
581
582 setIcon(MainFrame.getIcon(iconName));
583 return this;
584 }
585 } // class CustomRenderer extends JLabel implements
586 // ListCellRenderer
587 combo.setRenderer(new CustomRenderer());
588 combo.addActionListener(new ActionListener() {
589 public void actionPerformed(ActionEvent e) {
590 pDisj.setSelectedIndex(combo.getSelectedIndex());
591 stopCellEditing();
592 }
593 });
594 }// public ParameterDisjunctionEditor()
595
596 public Component getTableCellEditorComponent(JTable table, Object value,
597 boolean isSelected, int row, int column) {
598 pDisj = (ParameterDisjunction)value;
599 DefaultComboBoxModel comboModel = new DefaultComboBoxModel(pDisj.getNames());
600 combo.setModel(comboModel);
601 combo.setSelectedIndex(pDisj.getSelectedIndex());
602 return combo;
603 }// public Component getTableCellEditorComponent
604
605 public Object getCellEditorValue() {
606 pDisj.setSelectedIndex(combo.getSelectedIndex());
607 // return combo.getSelectedIndex();
608 return pDisj;
609 }
610
611 public boolean stopCellEditing() {
612 combo.hidePopup();
613 return super.stopCellEditing();
614 }
615
616 JComboBox combo;
617
618 ParameterDisjunction pDisj;
619 }// class ParameterDisjunctionEditor extends DefaultCellEditor
620
621 class ParameterValueEditor extends AbstractCellEditor implements
622 TableCellEditor {
623 ParameterValueEditor() {
624 combo = new JComboBox();
625 combo.setRenderer(new ResourceRenderer());
626 combo.setEditable(false);
627
628 textField = new JTextField(20);
629
630 fileButton = new JButton(MainFrame.getIcon("open-file"));
631 fileButton.setToolTipText("Browse the file system");
632 fileButton.addActionListener(new ActionListener() {
633 public void actionPerformed(ActionEvent e) {
634 fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
635 fileChooser.setDialogTitle("Select a file");
636 fileChooser.setResource(fileChooserResource);
637 int res = fileChooser.showOpenDialog(ResourceParametersEditor.this);
638 if(res == JFileChooser.APPROVE_OPTION) {
639 try {
640 textField.setText(fileChooser.getSelectedFile().toURI().toURL()
641 .toExternalForm());
642 }
643 catch(IOException ioe) {
644 ioe.printStackTrace();
645 }
646 fireEditingStopped();
647 }
648 else {
649 fireEditingCanceled();
650 }
651 }
652 });
653
654 listButton = new JButton(MainFrame.getIcon("edit-list"));
655 listButton.setToolTipText("Edit the list");
656 listButton.addActionListener(new ActionListener() {
657 public void actionPerformed(ActionEvent e) {
658 List returnedList = listEditor.showDialog();
659 if(returnedList != null) {
660 listValue = returnedList;
661 fireEditingStopped();
662 }
663 else {
664 fireEditingCanceled();
665 }
666 }
667 });
668
669 fmButton = new JButton(MainFrame.getIcon("edit-list"));
670 fmButton.setToolTipText("Edit the feature map");
671 fmButton.addActionListener(new ActionListener() {
672 public void actionPerformed(ActionEvent e) {
673 FeatureMap returnedFM = fmEditor.showDialog();
674 if(returnedFM != null) {
675 fmValue = returnedFM;
676 fireEditingStopped();
677 }
678 else {
679 fireEditingCanceled();
680 }
681 }
682 });
683
684 textButtonBox = new JPanel();
685 textButtonBox.setLayout(new BoxLayout(textButtonBox, BoxLayout.X_AXIS));
686 textButtonBox.setOpaque(false);
687 textFieldBoolean = new JTextField();
688 textFieldBoolean.setEditable(false);
689 textFieldBoolean.addMouseListener(new MouseAdapter() {
690 public void mouseClicked(MouseEvent e) {
691 Boolean value = Boolean.valueOf(textFieldBoolean.getText());
692 value = !value;
693 textFieldBoolean.setText(value.toString());
694 }
695 });
696 textFieldBoolean.addKeyListener(new KeyAdapter() {
697 public void keyTyped(KeyEvent e) {
698 Boolean value = Boolean.valueOf(textFieldBoolean.getText());
699 value = !value;
700 textFieldBoolean.setText(value.toString());
701 }
702 });
703
704 textButtonBox.addFocusListener(new FocusAdapter() {
705 public void focusGained(FocusEvent e) {
706 if(!comboUsed) {
707 // needed because the focus would otherwise stay
708 // on the textButtonBox panel
709 textField.requestFocusInWindow();
710 }
711 }
712 });
713 // select the opposite element when tab key is pressed
714 textField.addKeyListener(new KeyAdapter() {
715 public void keyPressed(KeyEvent e) {
716 JTextField textField = (JTextField) e.getSource();
717 if((e.getKeyCode() == KeyEvent.VK_TAB)
718 && textField.getParent().getComponentCount() == 3) {
719 textField.getParent().getComponent(2).requestFocusInWindow();
720 e.consume();
721 }
722 }
723 });
724
725 }// ParameterValueEditor()
726
727 public Component getTableCellEditorComponent(JTable table, Object value,
728 boolean isSelected, int row, int column) {
729 comboUsed = false;
730 listUsed = false;
731 fmUsed = false;
732 ParameterDisjunction pDisj = (ParameterDisjunction)table
733 .getValueAt(row, convertColumnIndexToView(0));
734 type = pDisj.getType();
735 // set the tooltip
736 combo.setToolTipText(pDisj.getComment());
737 textField.setToolTipText(pDisj.getComment());
738 textFieldBoolean.setToolTipText(pDisj.getComment());
739
740 if(Gate.isGateType(type)) {
741 // Gate type
742 comboUsed = true;
743 ArrayList<Object> values = new ArrayList<Object>();
744 try {
745 values.addAll(Gate.getCreoleRegister().getAllInstances(type));
746 }
747 catch(GateException ge) {
748 ge.printStackTrace(Err.getPrintWriter());
749 }
750 values.add(0, "<none>");
751 combo.setModel(new DefaultComboBoxModel(values.toArray()));
752 combo.setSelectedItem(value == null ? "<none>" : value);
753 return combo;
754 }
755 else {
756 // non Gate type
757 Class typeClass = null;
758 try {
759 // load type class through GATE classloader
760 typeClass = Class.forName(type, true, Gate.getClassLoader());
761 }
762 catch(ClassNotFoundException cnfe) {
763 cnfe.printStackTrace();
764 }
765
766 textField.setText((value == null) ? "" : value.toString());
767 if(type.equals("java.net.URL")) {
768 // clean up all filters
769 fileChooser.resetChoosableFileFilters();
770 fileChooser.setAcceptAllFileFilterUsed(true);
771 fileChooser.setFileFilter(fileChooser.getAcceptAllFileFilter());
772 Parameter param = pDisj.getParameter();
773 Set sufixes = param.getSuffixes();
774 if(sufixes != null) {
775 ExtensionFileFilter fileFilter = new ExtensionFileFilter();
776 Iterator sufIter = sufixes.iterator();
777 while(sufIter.hasNext()) {
778 fileFilter.addExtension((String)sufIter.next());
779 }
780 fileFilter.setDescription("Known file types " + sufixes.toString());
781 fileChooser.addChoosableFileFilter(fileFilter);
782 fileChooser.setFileFilter(fileFilter);
783 }
784
785 textField.setEditable(true);
786 textButtonBox.removeAll();
787 textButtonBox.add(textField);
788 textButtonBox.add(Box.createHorizontalStrut(5));
789 textButtonBox.add(fileButton);
790 return textButtonBox;
791 }
792 else if(type.equals("java.lang.Boolean")) {
793 textFieldBoolean.setText(value == null ? "false" : value.toString());
794 return textFieldBoolean;
795 }
796 else if(typeClass != null
797 && Collection.class.isAssignableFrom(typeClass)) {
798 // List value
799 listUsed = true;
800 Parameter param = pDisj.getParameter();
801
802 listValue = (Collection)value;
803 listEditor = new ListEditorDialog(SwingUtilities.getAncestorOfClass(
804 Window.class, ResourceParametersEditor.this),
805 (Collection)value, typeClass, param.getItemClassName());
806
807 textField.setEditable(false);
808 textField.setText(textForList((Collection)value));
809 textButtonBox.removeAll();
810 textButtonBox.add(textField);
811 textButtonBox.add(Box.createHorizontalStrut(5));
812 textButtonBox.add(listButton);
813 return textButtonBox;
814 }
815 else if(typeClass != null
816 && FeatureMap.class.isAssignableFrom(typeClass)) {
817 // List value
818 fmUsed = true;
819
820 fmValue = (FeatureMap)value;
821 fmEditor = new FeatureMapEditorDialog(SwingUtilities
822 .getAncestorOfClass(Window.class,
823 ResourceParametersEditor.this), (FeatureMap)value);
824
825 textField.setEditable(false);
826 textField.setText(textForFeatureMap((FeatureMap)value));
827 textButtonBox.removeAll();
828 textButtonBox.add(textField);
829 textButtonBox.add(Box.createHorizontalStrut(5));
830 textButtonBox.add(fmButton);
831 return textButtonBox;
832 }
833 else if(typeClass != null && typeClass.isEnum()) {
834 comboUsed = true;
835 try {
836 // extract list of allowable values by reflection - every
837 // enum type has a values method returning an array of values
838 Method getValuesMethod = typeClass.getMethod("values");
839 Object[] enumValues = (Object[])getValuesMethod.invoke(null);
840 Object[] comboValues = null;
841 Parameter param = pDisj.getParameter();
842 // only allow selection of "<none>" for optional parameters
843 if(param.isOptional()) {
844 comboValues = new Object[enumValues.length + 1];
845 comboValues[0] = "<none>";
846 System.arraycopy(enumValues, 0, comboValues, 1,enumValues.length);
847 }
848 else {
849 comboValues = enumValues;
850 }
851 combo.setModel(new DefaultComboBoxModel(comboValues));
852 combo.setSelectedItem(value == null ? "<none>" : value);
853 return combo;
854 }
855 catch(Exception ex) {
856 throw new LuckyException("Error calling \"values\" method of an "
857 + "enum type");
858 }
859 }
860 else {
861 textField.setEditable(true);
862 return textField;
863 }
864 }
865 }// getTableCellEditorComponent
866
867 public Object getCellEditorValue() {
868 if(comboUsed) {
869 Object value = combo.getSelectedItem();
870 return value == "<none>" ? null : value;
871 }
872 else if(listUsed) {
873 return listValue;
874 }
875 else if(fmUsed) {
876 return fmValue;
877 }
878 else {
879 if(type.equals("java.lang.Boolean")) {
880 // get the value from the label
881 return Boolean.valueOf(textFieldBoolean.getText());
882 }
883 else {
884 // get the value from the text field
885 return textField.getText();
886 // return ((textField.getText().equals("")) ? null :
887 // textField.getText());
888 }
889 }
890 }// public Object getCellEditorValue()
891
892 /**
893 * The type of the value currently being edited
894 */
895 String type;
896
897 /**
898 * Combobox use as editor for Gate objects (chooses between
899 * instances)
900 */
901 JComboBox combo;
902
903 /**
904 * Generic editor for all types that are not treated special
905 */
906 JTextField textField;
907
908 /**
909 * Editor used for boolean values.
910 */
911 JTextField textFieldBoolean;
912
913 ListEditorDialog listEditor = null;
914
915 Collection listValue;
916
917 FeatureMapEditorDialog fmEditor = null;
918
919 FeatureMap fmValue;
920
921 boolean comboUsed;
922
923 boolean listUsed;
924
925 boolean fmUsed;
926
927 JButton fileButton;
928
929 JButton listButton;
930
931 JButton fmButton;
932
933 /** Contains a textfield and a button */
934 JPanel textButtonBox;
935 }// /class ParameterValueEditor
936
937 /**
938 * Gets a string representation for a list value
939 */
940 protected String textForList(Collection list) {
941 if(list == null || list.isEmpty()) return "[]";
942 StringBuilder res = new StringBuilder("[");
943 Iterator elemIter = list.iterator();
944 while(elemIter.hasNext()) {
945 Object elem = elemIter.next();
946 if(elem != null)
947 res.append((elem instanceof NameBearer) ?
948 ((NameBearer) elem).getName() : elem.toString())
949 .append(", ");
950 else res.append("<null>, ");
951 }
952 res.delete(res.length() - 2, res.length() - 1);
953 res.append("]");
954 return res.toString();
955 }
956
957 /**
958 * Get a string representation for a FeatureMap value.
959 */
960 protected String textForFeatureMap(FeatureMap fm) {
961 return (fm == null) ? "" : fm.toString();
962 }
963
964 }// class NewResourceDialog
|