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 * Ian Roberts 14/02/2009
011 *
012 * $Id: InputOutputAnnotationSetsDialog.java 12006 2009-12-01 17:24:28Z thomas_heitz $
013 *
014 */
015
016 package gate.gui.teamware;
017
018 import gate.Controller;
019
020 import java.awt.Component;
021 import java.awt.GridBagConstraints;
022 import java.awt.GridBagLayout;
023 import java.awt.GridLayout;
024 import java.awt.event.ActionEvent;
025 import java.util.Arrays;
026 import java.util.Collection;
027 import java.util.Comparator;
028 import java.util.Set;
029
030 import javax.swing.AbstractAction;
031 import javax.swing.Action;
032 import javax.swing.BorderFactory;
033 import javax.swing.Box;
034 import javax.swing.DefaultListModel;
035 import javax.swing.JButton;
036 import javax.swing.JComboBox;
037 import javax.swing.JList;
038 import javax.swing.JOptionPane;
039 import javax.swing.JPanel;
040 import javax.swing.JScrollPane;
041
042 /**
043 * Dialog box to edit the lists of input and output annotation set names
044 * for the "export to teamware" option.
045 */
046 public class InputOutputAnnotationSetsDialog {
047
048 /**
049 * The controller being exported.
050 */
051 private Controller controller;
052
053 private JPanel panel;
054
055 /**
056 * Editor component for the input annotation set names.
057 */
058 private AnnotationSetsList inputList;
059
060 private Set<String> inputSetNames;
061
062 /**
063 * Editor component for the output annotation set names.
064 */
065 private AnnotationSetsList outputList;
066
067 private Set<String> outputSetNames;
068
069 public InputOutputAnnotationSetsDialog(Controller controller) {
070 this.controller = controller;
071 initGuiComponents();
072 }
073
074 /**
075 * Set up the GUI.
076 */
077 protected void initGuiComponents() {
078 panel = new JPanel();
079 panel.setLayout(new GridLayout(1, 2, 5, 5));
080
081 // get the list of annotation set names from last time the app was
082 // saved, or make an educated guess if it hasn't been saved before.
083 inputSetNames = TeamwareUtils.getInputAnnotationSets(controller);
084 outputSetNames = TeamwareUtils.getOutputAnnotationSets(controller);
085
086 Set<String> likelyInputSetNames = TeamwareUtils
087 .getLikelyInputAnnotationSets(controller);
088 Set<String> likelyOutputSetNames = TeamwareUtils
089 .getLikelyOutputAnnotationSets(controller);
090
091 inputList = new AnnotationSetsList(likelyInputSetNames, inputSetNames);
092 outputList = new AnnotationSetsList(likelyOutputSetNames, outputSetNames);
093
094 inputList.setBorder(BorderFactory.createTitledBorder(BorderFactory
095 .createEtchedBorder(), "Input annotation sets"));
096 outputList.setBorder(BorderFactory.createTitledBorder(BorderFactory
097 .createEtchedBorder(), "Output annotation sets"));
098
099 panel.add(inputList);
100 panel.add(outputList);
101 }
102
103 /**
104 * Show the dialog. If the dialog is closed with the OK button, the
105 * contents of the two lists (input and output annotation set names)
106 * are persisted back to the relevant Controller features.
107 *
108 * @return true if the dialog was closed with the OK button, false
109 * otherwise.
110 */
111 public boolean showDialog(Component parent) {
112 int selectedOption = JOptionPane.showConfirmDialog(parent, panel,
113 "Select input and output annotation sets",
114 JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
115 if(selectedOption == JOptionPane.OK_OPTION) {
116 inputSetNames.clear();
117 for(int i = 0; i < inputList.listModel.size(); i++) {
118 inputSetNames.add((String)inputList.listModel.get(i));
119 }
120
121 outputSetNames.clear();
122 for(int i = 0; i < outputList.listModel.size(); i++) {
123 outputSetNames.add((String)outputList.listModel.get(i));
124 }
125
126 return true;
127 }
128 else {
129 return false;
130 }
131 }
132
133 /**
134 * Panel representing the list of annotation set names for either
135 * input or output.
136 */
137 class AnnotationSetsList extends JPanel {
138 private JList annotationSetsList;
139
140 private DefaultListModel listModel;
141
142 private JComboBox combo;
143
144 private JButton addButton;
145
146 private JButton removeButton;
147
148 /**
149 * Adds the currently selected annotation set name to the list, if
150 * it is not already present.
151 */
152 protected class AddAction extends AbstractAction {
153 AddAction() {
154 super("Add");
155 putValue(SHORT_DESCRIPTION, "Add the edited value to the list");
156 }
157
158 public void actionPerformed(ActionEvent e) {
159 String selected = (String)combo.getSelectedItem();
160 // find where to insert
161 int index = 0;
162 while(index < listModel.size()
163 && NATURAL_COMPARATOR.compare((String)listModel.get(index),
164 selected) < 0) {
165 index++;
166 }
167 if(index == listModel.size()) {
168 // moved past the end of the list, so add there
169 listModel.addElement(selected);
170 }
171 else {
172 // add if the value is not already present
173 if(NATURAL_COMPARATOR.compare((String)listModel.get(index), selected) != 0) {
174 listModel.add(index, selected);
175 }
176 }
177 }
178 }
179
180 /**
181 * Removes the selected element(s) from the list
182 */
183 protected class RemoveAction extends AbstractAction {
184 RemoveAction() {
185 super("Remove");
186 putValue(SHORT_DESCRIPTION,
187 "Remove the selected value(s) from the list");
188 }
189
190 public void actionPerformed(ActionEvent e) {
191 int[] indices = annotationSetsList.getSelectedIndices();
192 Arrays.sort(indices);
193 for(int i = indices.length - 1; i >= 0; i--) {
194 listModel.remove(indices[i]);
195 }
196 }
197 }
198
199 AnnotationSetsList(Collection<String> hintSetNames,
200 Collection<String> initialSetNames) {
201 GridBagLayout layout = new GridBagLayout();
202 setLayout(layout);
203 GridBagConstraints c = new GridBagConstraints();
204 c.gridx = 0;
205 c.ipady = 2;
206 c.weightx = 1.0;
207
208 String[] hintSetNamesArray = hintSetNames.toArray(new String[hintSetNames
209 .size()]);
210 Arrays.sort(hintSetNamesArray, NATURAL_COMPARATOR);
211 combo = new JComboBox(hintSetNamesArray);
212 combo.setEditable(true);
213 // custom editor to handle the default annotation set.
214 combo.setEditor(new AnnotationSetNameComboEditor(combo.getEditor()));
215
216 // set up renderer
217 combo.setRenderer(new AnnotationSetNameCellRenderer());
218
219 c.fill = GridBagConstraints.HORIZONTAL;
220 add(combo, c);
221
222 // add and remove buttons
223 Action addAction = new AddAction();
224 Action removeAction = new RemoveAction();
225
226 Box buttonsBox = Box.createHorizontalBox();
227 buttonsBox.add(Box.createHorizontalGlue());
228 addButton = new JButton(addAction);
229 buttonsBox.add(addButton);
230 buttonsBox.add(Box.createHorizontalStrut(5));
231 removeButton = new JButton(removeAction);
232 buttonsBox.add(removeButton);
233 buttonsBox.add(Box.createHorizontalGlue());
234
235 add(buttonsBox, c);
236
237 listModel = new DefaultListModel();
238 String[] initialSetNamesArray = initialSetNames
239 .toArray(new String[initialSetNames.size()]);
240 Arrays.sort(initialSetNamesArray, NATURAL_COMPARATOR);
241 for(String name : initialSetNamesArray) {
242 listModel.addElement(name);
243 }
244
245 annotationSetsList = new JList(listModel);
246 // set up list cell renderer
247 annotationSetsList.setCellRenderer(new AnnotationSetNameCellRenderer());
248
249 c.fill = GridBagConstraints.BOTH;
250 c.weighty = 1.0;
251 add(new JScrollPane(annotationSetsList), c);
252 }
253 }
254
255 /**
256 * A comparator for strings that uses their natural order, treating
257 * <code>null</code> as less than anything non-<code>null</code>.
258 */
259 protected static class NaturalComparator implements Comparator<String> {
260 public int compare(String a, String b) {
261 if(a == null) {
262 if(b == null) {
263 return 0;
264 }
265 else {
266 return -1;
267 }
268 }
269 else if(b == null) {
270 return 1;
271 }
272 else {
273 return a.compareTo(b);
274 }
275 }
276 }
277
278 private static final Comparator<String> NATURAL_COMPARATOR = new NaturalComparator();
279
280 }
|