001    package jigcell.compare.views;
002    
003    import java.awt.BorderLayout;
004    import java.awt.event.ItemEvent;
005    import java.util.Iterator;
006    import javax.swing.JFileChooser;
007    import javax.swing.JScrollPane;
008    import jigcell.compare.IConfigEditor;
009    import jigcell.compare.IProgrammableDataGenerator;
010    import jigcell.compare.impl.Compare;
011    import jigcell.compare.impl.SuffixFileFilter;
012    import jigcell.compare.objective.IObjective;
013    import jigcell.compare.objective.MetricObjective;
014    import jigcell.compare.objective.Objective;
015    import jigcell.compare.ui.ConfigEditor;
016    import jigcell.compare.ui.InterfaceBuilder;
017    import jigcell.compare.ui.ListComboBoxModel;
018    
019    /**
020     * Supports creating and editing objective functions.
021     *
022     * <p>
023     * This code is licensed under the DARPA BioCOMP Open Source License.  See LICENSE for more details.
024     * </p>
025     *
026     * @author Nicholas Allen
027     */
028    
029    public class ObjectiveEditor extends ProgrammableDataGeneratorEditor {
030    
031       /**
032        * Property key for available primitives
033        */
034    
035       public final static String CONFIG_OBJECTIVES = "ObjectiveEditor.objectives";
036    
037       /**
038        * Objective name label
039        */
040    
041       protected final static String LABEL_OBJECTIVE = "Objective name:";
042    
043       /**
044        * Metric label
045        */
046    
047       protected final static String LABEL_METRIC = "Metric:";
048    
049       /**
050        * File filter for objective catalog files
051        */
052    
053       protected final static SuffixFileFilter FILTER_OBJECTIVECATALOG = new SuffixFileFilter (".obc", "Objective Catalog (*.obc)");
054    
055       /**
056        * Model for metrics
057        */
058    
059       protected ListComboBoxModel metricModel;
060    
061       /**
062        * Creates a new editor for working with objective functions.
063        *
064        * @param compare Comparator backend to interface with
065        * @param configMarker Marker for retrieving configuration information from Comparator backend
066        */
067    
068       public ObjectiveEditor (Compare compare, String configMarker) {
069          super (compare, configMarker);
070       }
071    
072       /**
073        * {@inheritDoc}
074        */
075    
076       public void add (String name) {
077          assert name != null;
078          MetricObjective generator = new MetricObjective ();
079          IObjective metric = (IObjective) metricModel.getSelectedItem ();
080          if (metric == null)
081             return;
082          metric = (IObjective) metric.copy (false);
083          generator.setMetric (metric);
084          metric.setOption (IProgrammableDataGenerator.OPTION_COMPARE, compare);
085          add (name, generator);
086          compare.firePropertyChange (IObjective.RESOURCE_OBJECTIVES);
087       }
088    
089       /**
090        * {@inheritDoc}
091        */
092    
093       public IConfigEditor createConfigEditor () {
094          IConfigEditor editor = new ConfigEditor (compare, this, configMarkers, getConfigForView ());
095          editor.addOption (CONFIG_TABNAME, "Name", String.class);
096          editor.addOption (CONFIG_RECENTSOURCECOUNT, "File History Size", Integer.class);
097          editor.addOption (CONFIG_OBJECTIVES, "Primitive Objective Functions", Class [].class);
098          return editor;
099       }
100    
101       /**
102        * {@inheritDoc}
103        */
104    
105       public void duplicate (String name) {
106          assert name != null;
107          MetricObjective generator = new MetricObjective ();
108          IObjective metric = (IObjective) ((MetricObjective) objectModel.getSelectedItem ()).getMetric ().copy (false);
109          generator.setMetric (metric);
110          metric.setOption (IProgrammableDataGenerator.OPTION_COMPARE, compare);
111          add (name, generator);
112          compare.firePropertyChange (Objective.RESOURCE_OBJECTIVES);
113       }
114    
115       public void itemStateChanged (ItemEvent e) {
116          String name = manager.getComponentName (e.getSource ());
117          if (name == LABEL_METRIC)
118             updateMetricSelection ();
119          else if (name == LABEL_OBJECTIVE)
120             updateObjectiveSelection ();
121       }
122    
123       /**
124        * {@inheritDoc}
125        */
126    
127       public void readConfiguration (String state) {
128          super.readConfiguration (state);
129          if (state == STATE_INITIALIZE && primitives == null)
130             createPrimitiveList (CONFIG_OBJECTIVES);
131       }
132    
133       /**
134        * {@inheritDoc}
135        */
136    
137       protected JFileChooser createFileChooser () {
138          return InterfaceBuilder.createFileChooser (FILTER_OBJECTIVECATALOG);
139       }
140    
141       /**
142        * {@inheritDoc}
143        */
144    
145       protected JFileChooser createFileChooserSet () {
146          return InterfaceBuilder.createFileChooser (ObjectiveSeriesView.FILTER_OBJECTIVESET);
147       }
148    
149       /**
150        * {@inheritDoc}
151        */
152    
153       protected void createUI () {
154          manager.addLabel (LABEL_OBJECTIVE);
155          objectModel = new ListComboBoxModel (objects.asList ());
156          manager.addComboBox (LABEL_OBJECTIVE, objectModel);
157          manager.addButton (BUTTON_ADD);
158          manager.endRow ();
159          manager.addLabel (LABEL_METRIC);
160          metricModel = new ListComboBoxModel (primitives.asList ());
161          manager.addComboBox (LABEL_METRIC, metricModel).setEnabled (false);
162          setLayout (new BorderLayout ());
163          add (BorderLayout.NORTH, manager.endInterface ());
164          JScrollPane pane = new JScrollPane (JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
165          customizer = pane.getViewport ();
166          add (BorderLayout.CENTER, pane);
167          pane.setBorder (null);
168       }
169    
170       /**
171        * {@inheritDoc}
172        */
173    
174       protected void initialize () {
175          resourceKey = IObjective.RESOURCE_OBJECTIVES;
176          propertyKey = IObjective.PROPERTY_OBJECTIVE_EDIT;
177          super.initialize ();
178       }
179    
180       /**
181        * {@inheritDoc}
182        */
183    
184       protected void setCustomizerView (IProgrammableDataGenerator object) {
185          super.setCustomizerView (object);
186          manager.setComponentEnabled (LABEL_METRIC, object != null);
187       }
188    
189       /**
190        * {@inheritDoc}
191        */
192    
193       protected void updateList () {
194          super.updateList ();
195          for (Iterator iterator = objects.iterator (); iterator.hasNext (); ) {
196             MetricObjective generator = (MetricObjective) iterator.next ();
197             generator.getMetric ().setOption (IProgrammableDataGenerator.OPTION_COMPARE, compare);
198          }
199       }
200    
201       /**
202        * Updates the internal metric selection to match the selection in the view.
203        */
204    
205       protected void updateMetricSelection () {
206          int item = objectModel.getSelectedIndex ();
207          if (item == -1)
208             return;
209          IObjective function = (IObjective) metricModel.getSelectedItem ();
210          if (function == null)
211             return;
212          MetricObjective generator = (MetricObjective) objects.get (item);
213          if (function.isCopyRelated (generator.getMetric ()))
214             return;
215          function = (IObjective) function.copy (false);
216          generator.setMetric (function);
217          function.setOption (IProgrammableDataGenerator.OPTION_COMPARE, compare);
218          setCustomizerView (function);
219          compare.firePropertyChange (IObjective.PROPERTY_OBJECTIVE_EDIT);
220       }
221    
222       /**
223        * Updates the internal objective selection to match the selection in the view.
224        */
225    
226       protected void updateObjectiveSelection () {
227          int item = objectModel.getSelectedIndex ();
228          if (item == -1) {
229             setCustomizerView (null);
230             return;
231          }
232          MetricObjective generator = (MetricObjective) objects.get (item);
233          IObjective metric = generator.getMetric ();
234          setCustomizerView (metric);
235          metricModel.setSelectedItem (metric);
236       }
237    }