1
14
15 package gate.gui;
16
17 import java.awt.*;
18 import java.awt.event.*;
19 import java.io.IOException;
20 import java.util.*;
21 import java.util.List;
22
23 import javax.swing.*;
24 import javax.swing.border.BevelBorder;
25 import javax.swing.event.ChangeEvent;
26 import javax.swing.table.*;
27
28 import gate.*;
29 import gate.creole.*;
30 import gate.event.CreoleEvent;
31 import gate.event.CreoleListener;
32 import gate.swing.XJTable;
33 import gate.util.*;
34
35
41 public class ResourceParametersEditor extends XJTable implements CreoleListener{
42
43 public ResourceParametersEditor(){
44 initLocalData();
45 initGuiComponents();
46 initListeners();
47 setSortable(true);
48 setSortedColumn(0);
49 setComparator(0, new ParameterDisjunctionComparator());
50 }
51
52
58 public void init(Resource resource, List parameters){
59 cleanup();
60 this.resource = resource;
61 if(parameters != null){
62 parameterDisjunctions = new ArrayList(parameters.size());
63 for(int i = 0; i < parameters.size(); i++){
64 parameterDisjunctions.add(
65 new ParameterDisjunction(resource,
66 (List)parameters.get(i)));
67 }
68 }else{
69 parameterDisjunctions = null;
70 }
71 tableModel.fireTableDataChanged();
72 }
74
75 protected void initLocalData(){
76 resource = null;
77 parameterDisjunctions = null;
78 }
80 protected void initGuiComponents(){
81 setModel(tableModel = new ParametersTableModel());
82 getColumnModel().getColumn(0).
83 setCellRenderer(new ParameterDisjunctionRenderer());
84 getColumnModel().getColumn(1).
85 setCellRenderer(new DefaultTableCellRenderer());
86 getColumnModel().getColumn(2).
87 setCellRenderer(new BooleanRenderer());
88 getColumnModel().getColumn(3).
89 setCellRenderer(new ParameterValueRenderer());
90 getColumnModel().getColumn(0).
91 setCellEditor(new ParameterDisjunctionEditor());
92 getColumnModel().getColumn(3).
93 setCellEditor(new ParameterValueEditor());
94 setIntercellSpacing(new Dimension(5, 5));
95 setAutoResizeMode(AUTO_RESIZE_LAST_COLUMN);
96
97 setSurrendersFocusOnKeystroke(true);
98 }
100
101 protected void initListeners(){
102 Gate.getCreoleRegister().addCreoleListener(this);
103 addKeyListener(new KeyAdapter() {
104 public void keyTyped(KeyEvent e) {
105 if(e.getKeyCode() == KeyEvent.VK_ENTER){
106 if(getEditingColumn() == -1 && getEditingRow() == -1){
107 getParent().dispatchEvent(e);
108 }
109 }
110 }
111
112 public void keyPressed(KeyEvent e) {
113 }
114
115 public void keyReleased(KeyEvent e) {
116 }
117 });
118 }
119
120
123 public void cleanup(){
124 Gate.getCreoleRegister().removeCreoleListener(this);
125 if(parameterDisjunctions != null && parameterDisjunctions.size() > 0){
126 for (int i = 0; i < parameterDisjunctions.size(); i++){
127 ((ParameterDisjunction)parameterDisjunctions.get(i)).cleanup();
128 }
129 }
130 resource = null;
131 }
132
133
150
153
154
158 public void setParameters() throws ResourceInstantiationException{
159 if(resource == null || parameterDisjunctions == null) return;
160 if(getEditingColumn() != -1 && getEditingRow() != -1){
162 editingStopped(new ChangeEvent(getCellEditor(getEditingRow(),
163 getEditingColumn())));
164 }
165 for(int i = 0; i < parameterDisjunctions.size(); i++){
167 ParameterDisjunction pDisj = (ParameterDisjunction)
168 parameterDisjunctions.get(i);
169 resource.setParameterValue(pDisj.getName(), pDisj.getValue());
170 }
171 }
172
173
176
177 public Resource getResource() {
178 return resource;
179 }
180
181
186 public FeatureMap getParameterValues(){
187 if(getEditingColumn() != -1 && getEditingRow() != -1){
189 editingStopped(new ChangeEvent(getCellEditor(getEditingRow(),
190 getEditingColumn())));
191 }
192 FeatureMap values = Factory.newFeatureMap();
194 if(parameterDisjunctions != null){
195 for(int i = 0; i < parameterDisjunctions.size(); i++){
196 ParameterDisjunction pDisj = (ParameterDisjunction)
197 parameterDisjunctions.get(i);
198 values.put(pDisj.getName(), pDisj.getValue());
199 }
200 }
201 return values;
202 }
203
204 public void resourceLoaded(CreoleEvent e) {
205 repaint();
206 }
207 public void resourceUnloaded(CreoleEvent e) {
208 repaint();
209 }
210
211 public void resourceRenamed(Resource resource, String oldName,
212 String newName){
213 repaint();
214 }
215 public void datastoreOpened(CreoleEvent e) {
216 }
217 public void datastoreCreated(CreoleEvent e) {
218 }
219 public void datastoreClosed(CreoleEvent e) {
220 }
221
222 public void setEditable(boolean editable) {
223 this.editable = editable;
224 }
225
226 public boolean isEditable() {
227 return editable;
228 }
229
230
234 void removeCreoleListenerLink(){
235 Gate.getCreoleRegister().removeCreoleListener(this);
238 if(parameterDisjunctions != null && parameterDisjunctions.size() > 0){
239 for (int i = 0; i < parameterDisjunctions.size(); i++){
240 ((ParameterDisjunction)parameterDisjunctions.get(i)).removeCreoleListenerLink();
241 }
242 }
243
244 }
245
246 ParametersTableModel tableModel;
247 Resource resource;
248
249
250
251
254 protected List parameterDisjunctions;
255 protected boolean editable = true;
256
257 protected class ParametersTableModel extends AbstractTableModel{
259
260 public int getColumnCount(){return 4;}
261
262 public Class getColumnClass(int columnIndex){
263 switch(columnIndex){
264 case 0: return ParameterDisjunction.class;
265 case 1: return String.class;
266 case 2: return Boolean.class;
267 case 3: return Object.class;
268 default: return Object.class;
269 }
270 }
272 public String getColumnName(int columnIndex){
273 switch(columnIndex){
274 case 0: return "Name";
275 case 1: return "Type";
276 case 2: return "Required";
277 case 3: return "Value";
278 default: return "?";
279 }
280 }
282 public boolean isCellEditable(int rowIndex,
283 int columnIndex) {
284 switch(columnIndex){
285 case 0: return ((ParameterDisjunction)
286 parameterDisjunctions.get(rowIndex)).size() > 1;
287 case 1: return false;
288 case 2: return false;
289 case 3: return editable;
290 default: return false;
291 }
292 }
294 public int getRowCount(){
295 return (parameterDisjunctions == null) ? 0 : parameterDisjunctions.size();
296 }
297
298 public Object getValueAt(int rowIndex,
299 int columnIndex) {
300 ParameterDisjunction pDisj = (ParameterDisjunction)
301 parameterDisjunctions.get(rowIndex);
302 switch(columnIndex){
303 case 0: return pDisj;
304 case 1: return pDisj.getType();
305 case 2: return pDisj.isRequired();
306 case 3: return pDisj.getValue();
307 default: return "?";
308 }
309 }
311 public void setValueAt(Object aValue, int rowIndex, int columnIndex){
312 ParameterDisjunction pDisj = (ParameterDisjunction)
313 parameterDisjunctions.get(rowIndex);
314 switch(columnIndex){
315 case 0:{
316 pDisj.setSelectedIndex(((Integer)aValue).intValue());
317 break;
318 }
319 case 1:{
320 break;
321 }
322 case 2:{
323 break;
324 }
325 case 3:{
326 pDisj.setValue(aValue);
327 break;
328 }
329 default:{}
330 }
331 } }
334 class ParameterDisjunctionRenderer extends DefaultTableCellRenderer {
335 public ParameterDisjunctionRenderer(){
336 combo = new JComboBox();
337 class CustomRenderer extends JLabel implements ListCellRenderer {
338 public Component getListCellRendererComponent(JList list,
339 Object value,
340 int index,
341 boolean isSelected,
342 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,
353 Object value,
354 boolean isSelected,
355 boolean hasFocus,
356 int row,
357 int column) {
358 ParameterDisjunction pDisj = (ParameterDisjunction)value;
359 text = pDisj.getName();
360 String type = pDisj.getType();
361 iconName = "param.gif";
362 if(Gate.isGateType(type)){
363 ResourceData rData = (ResourceData)Gate.getCreoleRegister().get(type);
364 if(rData != null) iconName = rData.getIcon();
365 }
366 if(pDisj.size() > 1){
367 combo.setModel(new DefaultComboBoxModel(new Object[]{text}));
368 return combo;
369 }
370 Component comp = super.getTableCellRendererComponent(table,
372 text,
373 isSelected, hasFocus,
374 row, column);
375 setIcon(MainFrame.getIcon(iconName));
376 return this;
377 }
379 JComboBox combo;
381 String iconName;
382 String text;
383 }
385
386
390 class ParameterValueRenderer extends ObjectRenderer {
391 ParameterValueRenderer() {
392 fileButton = new JButton(MainFrame.getIcon("loadFile.gif"));
393 fileButton.setToolTipText("Set from file...");
394 listButton = new JButton(MainFrame.getIcon("editList.gif"));
395 listButton.setToolTipText("Edit the list");
396 textField = new JTextField();
397 textButtonBox = new JPanel();
398 textButtonBox.setLayout(new BoxLayout(textButtonBox, BoxLayout.X_AXIS));
399 textButtonBox.setOpaque(false);
400
401 combo = new JComboBox();
402 combo.setRenderer(new ResourceRenderer());
403 }
405 public Component getTableCellRendererComponent(JTable table,
406 Object value,
407 boolean isSelected,
408 boolean hasFocus,
409 int row,
410 int column) {
411
412 String type = ((ParameterDisjunction)table.getValueAt(row, 0)).getType();
413
414 if(Gate.isGateType(type)){
415 if(ResourceParametersEditor.this.isEditable()){
417 combo.setModel(new DefaultComboBoxModel(new Object[]{value == null ?
418 "<none>" :
419 value }));
420 return combo;
421 }else{
422 String text = value == null ? "<none>" : value.toString();
425 textField.setText(text);
428 return textField;
429 }
430 }else{
431 Class typeClass = null;
432 try{
433 typeClass = Class.forName(type, true, Gate.getClassLoader());
435 }catch(ClassNotFoundException cnfe){
436 }
437 String text = (value == null) ?
439 " " +
440 " " :
441 value.toString();
442 textField.setText(text);
444
447 if(type.equals("java.net.URL")){
448 if(ResourceParametersEditor.this.isEditable()){
449 textButtonBox.removeAll();
450 textField.setText(text);
451 textButtonBox.add(textField);
453 textButtonBox.add(Box.createHorizontalStrut(5));
456 textButtonBox.add(fileButton);
457 return textButtonBox;
458 }else{
459 return textField;
461 }
462 }else if(typeClass != null &&
463 List.class.isAssignableFrom(typeClass)){
464 textField.setText(textForList((List)value));
467 if(ResourceParametersEditor.this.isEditable()){
468 textButtonBox.removeAll();
469 textButtonBox.add(textField);
471 textButtonBox.add(Box.createHorizontalStrut(5));
474 textButtonBox.add(listButton);
475 return textButtonBox;
476 }else{
477 return textField;
479 }
480 }else return textField;
481 }
482 }
484
487 protected String textForList(List list){
488 if(list == null || list.isEmpty()) return "[]";
489 StringBuffer res = new StringBuffer("[");
490 Iterator elemIter = list.iterator();
491 while(elemIter.hasNext()){
492 Object elem = elemIter.next();
493 res.append( ((elem instanceof NameBearer) ?
494 ((NameBearer)elem).getName() :
495 elem.toString()) + ", ");
496 }
497 res.delete(res.length() - 2, res.length() - 1);
498 res.append("]");
499 return res.toString();
500 }
501
502 JButton fileButton;
503 JButton listButton;
504 JComboBox combo;
505 JPanel textButtonBox;
506 JTextField textField;
507 }
509 class ParameterDisjunctionComparator implements Comparator{
510 public int compare(Object o1, Object o2){
511 ParameterDisjunction pDisj1 = (ParameterDisjunction)o1;
512 ParameterDisjunction pDisj2 = (ParameterDisjunction)o2;
513 return pDisj1.getName().compareTo(pDisj2.getName());
514 }
515 }
516
517 class ParameterDisjunctionEditor extends DefaultCellEditor{
518 public ParameterDisjunctionEditor(){
519 super(new JComboBox());
520 combo = (JComboBox)super.getComponent();
521 class CustomRenderer extends JLabel implements ListCellRenderer {
522 public CustomRenderer(){
523 setOpaque(true);
524 }
525 public Component getListCellRendererComponent(JList list,
526 Object value,
527 int index,
528 boolean isSelected,
529 boolean cellHasFocus){
530 if (isSelected) {
531 setBackground(list.getSelectionBackground());
532 setForeground(list.getSelectionForeground());
533 }
534 else {
535 setBackground(list.getBackground());
536 setForeground(list.getForeground());
537 }
538
539 setFont(list.getFont());
540
541 setText((String)value);
542
543 String iconName = "param.gif";
544 Parameter[] params = pDisj.getParameters();
545 for(int i = 0; i < params.length; i++){
546 Parameter param = (Parameter)params[i];
547 if(param.getName().equals(value)){
548 String type = param.getTypeName();
549 if(Gate.getCreoleRegister().containsKey(type)){
550 ResourceData rData = (ResourceData)
551 Gate.getCreoleRegister().get(type);
552 if(rData != null) iconName = rData.getIcon();
553 }
554 break;
555 } }
558 setIcon(MainFrame.getIcon(iconName));
559 return this;
560 }
561 }; combo.setRenderer(new CustomRenderer());
563 combo.addActionListener(new ActionListener() {
564 public void actionPerformed(ActionEvent e) {
565 stopCellEditing();
566 }
567 });
568 }
570 public Component getTableCellEditorComponent(JTable table,
571 Object value,
572 boolean isSelected,
573 int row,
574 int column){
575 pDisj = (ParameterDisjunction)value;
576 combo.setModel(new DefaultComboBoxModel(pDisj.getNames()));
577 return combo;
578 }
580 public Object getCellEditorValue(){
581 return new Integer(combo.getSelectedIndex());
582 }
583
584 public boolean stopCellEditing(){
585 combo.hidePopup();
586 return super.stopCellEditing();
587 }
588
589 JComboBox combo;
590 ParameterDisjunction pDisj;
591 }
593 class ParameterValueEditor extends AbstractCellEditor
594 implements TableCellEditor{
595 ParameterValueEditor(){
596 combo = new JComboBox();
597 combo.setRenderer(new ResourceRenderer());
598 combo.setEditable(false);
599
600 textField = new JTextField();
601
602 fileChooser = MainFrame.getFileChooser();
603 fileButton = new JButton(MainFrame.getIcon("loadFile.gif"));
604 fileButton.setToolTipText("Set from file...");
605 fileButton.addActionListener(new ActionListener() {
606 public void actionPerformed(ActionEvent e) {
607 fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
608 fileChooser.setDialogTitle("Select a file");
609 int res = fileChooser.showOpenDialog(ResourceParametersEditor.this);
610 if(res == JFileChooser.APPROVE_OPTION){
611 try {
612 textField.setText(fileChooser.getSelectedFile().
613 toURL().toExternalForm());
614 } catch(IOException ioe){}
615 fireEditingStopped();
616 }else{
617 fireEditingCanceled();
618 }
619 }
620 });
621
622 listButton = new JButton(MainFrame.getIcon("editList.gif"));
623 listButton.setToolTipText("Edit the list");
624 listButton.addActionListener(new ActionListener() {
625 public void actionPerformed(ActionEvent e) {
626 List returnedList = listEditor.showDialog();
627 if(returnedList != null){
628 listValue = returnedList;
629 fireEditingStopped();
630 }else{
631 fireEditingCanceled();
632 }
633 }
634 });
635
636 textButtonBox = new JPanel();
637 textButtonBox.setLayout(new BoxLayout(textButtonBox, BoxLayout.X_AXIS));
638 textButtonBox.setOpaque(false);
639 textFieldBoolean = new JTextField();
646 textFieldBoolean.setEditable(false);
647 textFieldBoolean.addMouseListener(new MouseAdapter() {
648 public void mouseClicked(MouseEvent e) {
649 Boolean value = new Boolean(textFieldBoolean.getText());
650 value = new Boolean(!value.booleanValue());
651 textFieldBoolean.setText(value.toString());
652 }
653 });
654 textFieldBoolean.addKeyListener(new KeyAdapter() {
655 public void keyTyped(KeyEvent e) {
656 Boolean value = new Boolean(textFieldBoolean.getText());
657 value = new Boolean(!value.booleanValue());
658 textFieldBoolean.setText(value.toString());
659 }
660 });
661
662 textButtonBox.addFocusListener(new FocusAdapter() {
663 public void focusGained(FocusEvent e) {
664 if(comboUsed){
665
666 }else{
667 textField.requestFocusInWindow();
668 }
669 }
670
671 public void focusLost(FocusEvent e) {
672 }
673 });
674
675 }
677 public Component getTableCellEditorComponent(JTable table,
678 Object value,
679 boolean isSelected,
680 int row,
681 int column){
682 comboUsed = false;
683 listUsed = false;
684 ParameterDisjunction pDisj = (ParameterDisjunction)
685 table.getValueAt(row, 0);
686 type = pDisj.getType();
687
689 if(Gate.isGateType(type)){
690 comboUsed = true;
692 ArrayList values = new ArrayList();
693 try{
694 values.addAll(Gate.getCreoleRegister().
695 getAllInstances(type));
696 }catch(GateException ge){
697 ge.printStackTrace(Err.getPrintWriter());
698 }
699 values.add(0, "<none>");
700 combo.setModel(new DefaultComboBoxModel(values.toArray()));
701 combo.setSelectedItem(value == null ? "<none>" : value);
702 return combo;
703 }else{
704 Class typeClass = null;
706 try{
707 typeClass = Class.forName(type, true, Gate.getClassLoader());
709 }catch(ClassNotFoundException cnfe){
710 }
711
712 textField.setText((value == null) ? "" : value.toString());
713 if(type.equals("java.net.URL")){
714 fileChooser.resetChoosableFileFilters();
716 fileChooser.setAcceptAllFileFilterUsed(true);
717 fileChooser.setFileFilter(fileChooser.getAcceptAllFileFilter());
718 Parameter param = pDisj.getParameter();
719 Set sufixes = param.getSuffixes();
720 if(sufixes != null){
721 ExtensionFileFilter fileFilter = new ExtensionFileFilter();
722 Iterator sufIter = sufixes.iterator();
723 while(sufIter.hasNext()){
724 fileFilter.addExtension((String)sufIter.next());
725 }
726 fileFilter.setDescription("Known file types " + sufixes.toString());
727 fileChooser.addChoosableFileFilter(fileFilter);
728 fileChooser.setFileFilter(fileFilter);
729 }
730
731 textField.setEditable(true);
732 textButtonBox.removeAll();
733 textButtonBox.add(textField);
734 textButtonBox.add(Box.createHorizontalStrut(5));
735 textButtonBox.add(fileButton);
736 return textButtonBox;
737 }else if(type.equals("java.lang.Boolean")){
738 textFieldBoolean.setText(value == null ? "false" : value.toString());
739 return textFieldBoolean;
740 }else if(typeClass != null &&
741 List.class.isAssignableFrom(typeClass)){
742 listUsed = true;
744 Parameter param = pDisj.getParameter();
745 Set sufixes = param.getSuffixes();
746
747 listValue = (List)value;
748 listEditor = new ListEditorDialog(
749 SwingUtilities.getAncestorOfClass(
750 Window.class, ResourceParametersEditor.this),
751 (List)value, param.getItemClassName());
752
753 textField.setEditable(false);
754 textField.setText(textForList((List)value));
755 textButtonBox.removeAll();
756 textButtonBox.add(textField);
757 textButtonBox.add(Box.createHorizontalStrut(5));
758 textButtonBox.add(listButton);
759 return textButtonBox;
760 }else{
761 textField.setEditable(true);
762 return textField;
763 }
764 }
765 }
767
770 protected String textForList(List list){
771 if(list == null || list.isEmpty()) return "[]";
772 StringBuffer res = new StringBuffer("[");
773 Iterator elemIter = list.iterator();
774 while(elemIter.hasNext()){
775 Object elem = elemIter.next();
776 res.append( ((elem instanceof NameBearer) ?
777 ((NameBearer)elem).getName() :
778 elem.toString()) + ", ");
779 }
780 res.delete(res.length() - 2, res.length() - 1);
781 res.append("]");
782 return res.toString();
783 }
784
785 public Object getCellEditorValue(){
786 if(comboUsed){
787 Object value = combo.getSelectedItem();
788 return value == "<none>" ? null : value;
789 }
790 else if(listUsed){
791 return listValue;
792 }else{
793 if(type.equals("java.lang.Boolean")){
794 return new Boolean(textFieldBoolean.getText());
796 }else{
797 return textField.getText();
799 }
802 }
803 }
805
808 String type;
809
810
813 JComboBox combo;
814
815
820
823 JTextField textField;
824
825
828 JTextField textFieldBoolean;
829
832 JFileChooser fileChooser;
833
834 ListEditorDialog listEditor = null;
835 List listValue;
836
837 boolean comboUsed;
838 boolean listUsed;
839 JButton fileButton;
840 JButton listButton;
841 JPanel textButtonBox;
842 }}