/**
  * Reacts to property change.
  *
  * @see PropertyChangeListener#propertyChange(PropertyChangeEvent)
  */
 public void propertyChange(PropertyChangeEvent evt) {
   String name = evt.getPropertyName();
   if (SAVE_PROPERTY.equals(name)
       || DataComponent.DATA_MODIFIED_PROPERTY.equals(name)
       || PreviewPanel.PREVIEW_EDITED_PROPERTY.equals(name)) {
     view.setDataToSave(view.hasDataToSave());
   } else if (MetadataViewer.SAVE_DATA_PROPERTY.equals(name)) {
     Boolean b = (Boolean) evt.getNewValue();
     view.saveData(b.booleanValue());
   } else if (MetadataViewer.CLEAR_SAVE_DATA_PROPERTY.equals(name)
       || MetadataViewer.ON_DATA_SAVE_PROPERTY.equals(name)
       || MetadataViewer.ADMIN_UPDATED_PROPERTY.equals(name)) {
     view.clearData();
   } else if (UIUtilities.COLLAPSED_PROPERTY_JXTASKPANE.equals(name)) {
     view.handleTaskPaneCollapsed((JXTaskPane) evt.getSource());
   } else if (FileChooser.APPROVE_SELECTION_PROPERTY.equals(name)) {
     File[] files = (File[]) evt.getNewValue();
     view.attachFiles(files);
   } else if (AnnotationUI.REMOVE_ANNOTATION_PROPERTY.equals(name)) {
     Object object = evt.getNewValue();
     if (object instanceof DocComponent) {
       DocComponent doc = (DocComponent) object;
       Object data = doc.getData();
       if (data instanceof File) view.removeAttachedFile(data);
       else if (data instanceof FileAnnotationData) view.removeAttachedFile(data);
       else if (data instanceof TagAnnotationData) view.removeObject((DataObject) data);
     }
   } else if (AnnotationUI.DELETE_ANNOTATION_PROPERTY.equals(name)) {
     Object object = evt.getNewValue();
     if (object instanceof DocComponent) {
       DocComponent doc = (DocComponent) object;
       Object data = doc.getData();
       if (data instanceof FileAnnotationData) {
         view.deleteAnnotation((FileAnnotationData) data);
         view.removeAttachedFile(data);
       }
     } else if (object instanceof TextualAnnotationComponent) {
       TextualAnnotationComponent doc = (TextualAnnotationComponent) object;
       TextualAnnotationData data = doc.getData();
       // view.deleteAnnotation((TextualAnnotationData) data);
       view.removeObject(data);
     }
   } else if (AnnotationUI.EDIT_TAG_PROPERTY.equals(name)) {
     Object object = evt.getNewValue();
     if (object instanceof DocComponent) {
       // Save the tag w/o update.
       DataObject d = (DataObject) ((DocComponent) object).getData();
       // Save the tag
       OmeroMetadataService svc = MetadataViewerAgent.getRegistry().getMetadataService();
       long id = MetadataViewerAgent.getUserDetails().getId();
       try {
         svc.saveData(model.getSecurityContext(), Arrays.asList(d), null, null, id);
       } catch (Exception e) {
         Logger l = MetadataViewerAgent.getRegistry().getLogger();
         LogMessage msg = new LogMessage();
         msg.print("Saving object");
         msg.print(e);
         l.error(this, msg);
       }
     }
   } else if (OMEWikiComponent.WIKI_DATA_OBJECT_PROPERTY.equals(name)) {
     WikiDataObject object = (WikiDataObject) evt.getNewValue();
     long id;
     switch (object.getIndex()) {
       case WikiDataObject.IMAGE:
         id = object.getId();
         if (id < 0) viewImage(object.getName());
         else viewImage(id);
         break;
       case WikiDataObject.PROTOCOL:
         viewProtocol(object.getId());
         break;
     }
   } else if (SelectionWizard.SELECTED_ITEMS_PROPERTY.equals(name)) {
     Map m = (Map) evt.getNewValue();
     if (m == null || m.size() != 1) return;
     Set set = m.entrySet();
     Entry entry;
     Iterator i = set.iterator();
     Class type;
     while (i.hasNext()) {
       entry = (Entry) i.next();
       type = (Class) entry.getKey();
       view.handleObjectsSelection(type, (Collection) entry.getValue());
     }
   } else if (PreviewPanel.OPEN_FILE_PROPERTY.equals(name)) {
     Long id = (Long) evt.getNewValue();
     if (id != null) viewProtocol(id.longValue());
   } else if (MetadataViewer.SETTINGS_APPLIED_PROPERTY.equals(name)) {
     model.loadRenderingControl(RenderingControlLoader.RELOAD);
     view.onSettingsApplied(true);
   } else if (MetadataViewer.ACTIVITY_OPTIONS_PROPERTY.equals(name)) {
     List l = (List) evt.getNewValue();
     view.activityOptions((Component) l.get(0), (Point) l.get(1), (Integer) l.get(2));
   } else if (FigureDialog.CREATE_FIGURE_PROPERTY.equals(name)) {
     view.createFigure(evt.getNewValue());
   } else if (FigureDialog.CLOSE_FIGURE_PROPERTY.equals(name)) {
     figureDialog = null;
   } else if (MetadataViewer.CLOSE_RENDERER_PROPERTY.equals(name)) {
     view.discardRenderer(evt.getNewValue());
   } else if (MetadataViewer.RELATED_NODES_PROPERTY.equals(name)) {
     view.onRelatedNodesSet();
   } else if (ScriptingDialog.RUN_SELECTED_SCRIPT_PROPERTY.equals(name)) {
     // view.manageScript((ScriptObject) evt.getNewValue(),
     //		MetadataViewer.RUN);
   } else if (ScriptingDialog.DOWNLOAD_SELECTED_SCRIPT_PROPERTY.equals(name)) {
     Object value = evt.getNewValue();
     if (value instanceof ScriptObject)
       view.manageScript((ScriptObject) value, MetadataViewer.DOWNLOAD);
     else if (value instanceof String) {
       ScriptObject script = view.getScriptFromName((String) value);
       if (script != null) view.manageScript(script, MetadataViewer.DOWNLOAD);
     }
   } else if (ScriptingDialog.VIEW_SELECTED_SCRIPT_PROPERTY.equals(name)) {
     Object value = evt.getNewValue();
     if (value instanceof ScriptObject)
       view.manageScript((ScriptObject) value, MetadataViewer.VIEW);
     else if (value instanceof String) {
       ScriptObject script = view.getScriptFromName((String) value);
       if (script != null) view.manageScript(script, MetadataViewer.VIEW);
     }
   } else if (AnalysisResultsItem.ANALYSIS_RESULTS_DELETE.equals(name)) {
     AnalysisResultsItem item = (AnalysisResultsItem) evt.getNewValue();
     List<FileAnnotationData> list = item.getAttachments();
     view.fireAnnotationsDeletion(list);
   } else if (AnalysisResultsItem.ANALYSIS_RESULTS_VIEW.equals(name)) {
     AnalysisResultsItem item = (AnalysisResultsItem) evt.getNewValue();
     if (view.getRndIndex() == MetadataViewer.RND_GENERAL) {
       model.displayAnalysisResults(item);
       /*
       ViewImage event = new ViewImage(item.getData(), null);
       event.setAnalysis(item);
       EventBus bus = MetadataViewerAgent.getRegistry().getEventBus();
       bus.post(event);
       */
     } else {
       model.displayAnalysisResults(item);
     }
   } else if (AnalysisResultsItem.ANALYSIS_RESULTS_CANCEL.equals(name)) {
     AnalysisResultsItem item = (AnalysisResultsItem) evt.getNewValue();
     view.cancelAnalysisResultsLoading(item);
   }
 }
  /** Builds and lays out the UI. */
  private void buildGUI() {
    removeAll();
    JLabel l = new JLabel();
    Font f = l.getFont();
    int size = f.getSize() - 1;
    content.removeAll();
    content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));

    // layout button.
    // filters
    JPanel p = UIUtilities.buildComponentPanel(createBar(filterButton, null), 0, 0);
    p.setBackground(UIUtilities.BACKGROUND_COLOR);
    content.add(p);
    // rating
    p = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
    p.setBackground(UIUtilities.BACKGROUND_COLOR);
    p.add(UIUtilities.setTextFont("rate", Font.BOLD, size));
    p.add(createBar(unrateButton, null));
    p.add(Box.createHorizontalStrut(2));
    p.add(rating);
    // p.add(Box.createHorizontalStrut(2));
    // p.add(otherRating);
    content.add(p);

    // tags and attachments.
    p = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
    p.setBackground(UIUtilities.BACKGROUND_COLOR);
    p.add(UIUtilities.setTextFont("tag", Font.BOLD, size));
    p.add(createBar(addTagsButton, removeTagsButton));

    JPanel panel = new JPanel(new GridBagLayout());
    panel.setBorder(null);
    panel.setBackground(UIUtilities.BACKGROUND_COLOR);
    GridBagConstraints c = new GridBagConstraints();
    // c.fill = GridBagConstraints.HORIZONTAL;
    c.anchor = GridBagConstraints.WEST;
    c.gridwidth = GridBagConstraints.RELATIVE; // next-to-last
    c.fill = GridBagConstraints.NONE; // reset to default
    c.insets = new Insets(0, 2, 2, 0);
    c.gridy = 0;
    c.gridx = 0;
    panel.add(p, c);

    p = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
    p.setBackground(UIUtilities.BACKGROUND_COLOR);

    p.add(UIUtilities.setTextFont("attachment", Font.BOLD, size));
    p.add(createBar(addDocsButton, removeDocsButton));
    c.gridy = 3;
    panel.add(p, c);
    c.gridy = 0;
    c.gridx++;
    // c.ipady = 2;
    c.gridheight = 2;
    panel.add(tagsPane, c);
    c.gridy = 3;
    panel.add(docRef, c);
    content.add(panel);

    // analysis results
    List results = model.getAnalysisResults();
    if (results != null && results.size() > 0) {
      // panel = new JPanel(new GridBagLayout());
      // panel.setBorder(null);
      // panel.setBackground(UIUtilities.BACKGROUND_COLOR);
      // c = new GridBagConstraints();
      // c.fill = GridBagConstraints.HORIZONTAL;
      c.anchor = GridBagConstraints.WEST;
      c.gridwidth = GridBagConstraints.RELATIVE; // next-to-last
      c.fill = GridBagConstraints.NONE; // reset to default
      c.insets = new Insets(0, 2, 2, 0);
      c.gridy = 4;
      c.gridx = 0;

      p = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
      p.setBackground(UIUtilities.BACKGROUND_COLOR);
      p.setBorder(null);
      l = UIUtilities.setTextFont("analysis", Font.BOLD, size);
      l.setToolTipText("Displays the results of analysis run.");
      p.add(l);
      panel.add(p, c);
      Iterator i = results.iterator();
      AnalysisResultsItem item;
      JPanel list = new JPanel();
      list.setLayout(new BoxLayout(list, BoxLayout.Y_AXIS));
      list.setBackground(UIUtilities.BACKGROUND_COLOR);
      int n = 0;
      JPanel row = null;
      while (i.hasNext()) {
        item = (AnalysisResultsItem) i.next();
        item.addPropertyChangeListener(controller);
        if (n == 0) {
          row = initRow();
          row.add(item);
          n++;
        } else if (n == 1) {
          row.add(item);
          list.add(row);
          n = 0;
        }
      }
      if (row != null) list.add(row);
      c.gridx++;
      c.gridheight = 2;
      panel.add(UIUtilities.buildComponentPanel(list, 0, 0), c);
    }
    setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
    setBackground(UIUtilities.BACKGROUND);
    setBorder(new SeparatorOneLineBorder());
    add(content);
  }