/* *------------------------------------------------------------------------------ * Copyright (C) 2006-2014 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.agents.metadata.editor; import java.awt.Font; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.text.DecimalFormat; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import javax.swing.BoxLayout; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import org.openmicroscopy.shoola.agents.util.DataComponent; import org.openmicroscopy.shoola.agents.util.EditorUtil; import org.openmicroscopy.shoola.util.CommonsLangUtils; import org.openmicroscopy.shoola.util.ui.JLabelButton; import org.openmicroscopy.shoola.util.ui.NumericalTextField; import org.openmicroscopy.shoola.util.ui.OMETextArea; import org.openmicroscopy.shoola.util.ui.UIUtilities; import ome.formats.model.UnitsFactory; import omero.model.Length; import omero.model.LengthI; import omero.model.PressureI; import omero.model.TemperatureI; import omero.gateway.model.ImageAcquisitionData; /** * Displays the acquisition metadata related to the image itself. * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author Donald MacDonald      * <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a> * @version 3.0 * @since 3.0-Beta4 */ class ImageAcquisitionComponent extends JPanel implements PropertyChangeListener { /** Action ID to show or hide the unset stage data. */ private static final int STAGE = 0; /** Action ID to show or hide the unset environment data. */ private static final int ENVIRONMENT = 1; /** Reference to the Model. */ private EditorModel model; /** Reference to the parent of this component. */ private AcquisitionDataUI parent; /** The fields displaying the metadata. */ private Map<String, DataComponent> fieldsEnv; /** The fields displaying the metadata. */ private Map<String, DataComponent> fieldsStage; /** Flag indicating if the components have been initialized. */ private boolean init; /** The UI component hosting the objective metadata. */ private ObjectiveComponent objectivePane; /** Button to show or hides the unset fields. */ private JLabelButton unsetEnv; /** Flag indicating the unset fields for the environment are displayed. */ private boolean unsetEnvShown; /** The UI component hosting the environment metadata. */ private JPanel envPane; /** Button to show or hides the unset fields. */ private JLabelButton unsetStage; /** Flag indicating the unset fields for the stage are displayed. */ private boolean unsetStageShown; /** The UI component hosting the stage metadata. */ private JPanel stagePane; /** Shows or hides the unset fields. */ private void displayUnsetEnvFields() { unsetEnvShown = !unsetEnvShown; String s = AcquisitionDataUI.SHOW_UNSET; if (unsetEnvShown) s = AcquisitionDataUI.HIDE_UNSET; unsetEnv.setText(s); parent.layoutFields(envPane, unsetEnv, fieldsEnv, unsetEnvShown); } /** Shows or hides the unset fields. */ private void displayUnsetStageFields() { unsetStageShown = !unsetStageShown; String s = AcquisitionDataUI.SHOW_UNSET; if (unsetStageShown) s = AcquisitionDataUI.HIDE_UNSET; unsetStage.setText(s); parent.layoutFields(stagePane, unsetStage, fieldsStage, unsetStageShown); } /** Initializes the components. */ private void initComponents() { setBackground(UIUtilities.BACKGROUND_COLOR); setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); fieldsEnv = new LinkedHashMap<String, DataComponent>(); fieldsStage = new LinkedHashMap<String, DataComponent>(); objectivePane = new ObjectiveComponent(parent, model); unsetEnv = null; unsetEnvShown = false; envPane = new JPanel(); parent.format(envPane, "Environment"); unsetStage = null; unsetStageShown = false; stagePane = new JPanel(); parent.format(stagePane, "Position"); } /** * Transforms the position metadata into the corresponding UI objects. * * @param details The metadata to transform. */ private void transformStage(Map<String, Object> details) { DataComponent comp; JLabel label; JComponent area; String key; Object value; label = new JLabel(); Font font = label.getFont(); int sizeLabel = font.getSize()-2; List notSet = (List) details.get(EditorUtil.NOT_SET); details.remove(EditorUtil.NOT_SET); if (notSet.size() > 0 && unsetStage == null) { unsetStage = parent.formatUnsetFieldsControl(); unsetStage.setActionID(STAGE); unsetStage.addPropertyChangeListener(this); } Set entrySet = details.entrySet(); Entry entry; boolean set; Iterator i = entrySet.iterator(); while (i.hasNext()) { entry = (Entry) i.next(); key = (String) entry.getKey(); set = !notSet.contains(key); value = entry.getValue(); label = UIUtilities.setTextFont(key, Font.BOLD, sizeLabel); label.setBackground(UIUtilities.BACKGROUND_COLOR); if (value instanceof String) { area = UIUtilities.createComponent(OMETextArea.class, null); if (CommonsLangUtils.isBlank((String)value)) { value = AnnotationUI.DEFAULT_TEXT; set = false; } ((OMETextArea) area).setText((String) value); ((OMETextArea) area).setEditedColor(UIUtilities.EDITED_COLOR); } else if (value instanceof Length) { Length l = (Length) value; area = UIUtilities.createComponent(OMETextArea.class, null); if (value == null) { value = AnnotationUI.DEFAULT_TEXT; set = false; ((OMETextArea) area).setText((String) value); } else { DecimalFormat df = new DecimalFormat("0.##"); ((OMETextArea) area).setText(df.format(l.getValue())+" "+l.getSymbol()); } ((OMETextArea) area).setEditedColor(UIUtilities.EDITED_COLOR); } else { area = UIUtilities.createComponent(NumericalTextField.class, null); ((NumericalTextField) area).setNegativeAccepted(true); if (value instanceof Double) ((NumericalTextField) area).setNumberType(Double.class); else if (value instanceof Float) ((NumericalTextField) area).setNumberType(Float.class); ((NumericalTextField) area).setText(""+value); ((NumericalTextField) area).setEditedColor( UIUtilities.EDITED_COLOR); } area.setEnabled(!set); comp = new DataComponent(label, area); comp.setEnabled(false); comp.setSetField(!notSet.contains(key)); fieldsStage.put(key, comp); } } /** * Transforms the environment metadata into the corresponding UI objects. * * @param details The metadata to transform. */ private void transformEnv(Map<String, Object> details) { DataComponent comp; JLabel label; JComponent area; String key; Object value; label = new JLabel(); Font font = label.getFont(); int sizeLabel = font.getSize()-2; List notSet = (List) details.get(EditorUtil.NOT_SET); details.remove(EditorUtil.NOT_SET); if (notSet.size() > 0 && unsetEnv == null) { unsetEnv = parent.formatUnsetFieldsControl(); unsetEnv.setActionID(ENVIRONMENT); unsetEnv.addPropertyChangeListener(this); } Set entrySet = details.entrySet(); Entry entry; boolean set; Iterator i = entrySet.iterator(); while (i.hasNext()) { entry = (Entry) i.next(); key = (String) entry.getKey(); set = !notSet.contains(key); value = entry.getValue(); label = UIUtilities.setTextFont(key, Font.BOLD, sizeLabel); label.setBackground(UIUtilities.BACKGROUND_COLOR); if (value instanceof Number) { area = UIUtilities.createComponent( NumericalTextField.class, null); if (value instanceof Double) ((NumericalTextField) area).setNumberType(Double.class); else if (value instanceof Float) ((NumericalTextField) area).setNumberType(Float.class); if (EditorUtil.TEMPERATURE.equals(key)) { ((NumericalTextField) area).setMinimum(-Double.MAX_VALUE); } ((NumericalTextField) area).setText(""+value); ((NumericalTextField) area).setEditedColor( UIUtilities.EDITED_COLOR); } else { area = UIUtilities.createComponent( OMETextArea.class, null); if (value == null || value.equals("")) { value = AnnotationUI.DEFAULT_TEXT; set = false; } ((OMETextArea) area).setText((String) value); ((OMETextArea) area).setEditedColor( UIUtilities.EDITED_COLOR); } area.setEnabled(!set); comp = new DataComponent(label, area); comp.setEnabled(false); comp.setSetField(set); fieldsEnv.put(key, comp); } } /** Builds and lays out the UI. */ private void buildGUI() { removeAll(); if (objectivePane.isVisible()) add(objectivePane); if (envPane.isVisible()) { parent.layoutFields(envPane, unsetEnv, fieldsEnv, unsetEnvShown); add(envPane); parent.attachListener(fieldsEnv); } if (stagePane.isVisible()) { parent.layoutFields(stagePane, unsetStage, fieldsStage, unsetStageShown); add(stagePane); parent.attachListener(fieldsStage); } } /** * Creates a new instance. * * @param parent Reference to the Parent. Mustn't be <code>null</code>. * @param model Reference to the Model. Mustn't be <code>null</code>. */ ImageAcquisitionComponent(AcquisitionDataUI parent, EditorModel model) { if (model == null) throw new IllegalArgumentException("No model."); if (parent == null) throw new IllegalArgumentException("No parent."); this.parent = parent; this.model = model; initComponents(); } /** Sets the metadata. */ void setImageAcquisitionData() { if (init) return; init = true; fieldsEnv.clear(); fieldsStage.clear(); ImageAcquisitionData data = model.getImageAcquisitionData(); Map<String, Object> details = EditorUtil.transformObjectiveAndSettings(data); List notSet = (List) details.get(EditorUtil.NOT_SET); objectivePane.setVisible(false); if (notSet.size() != EditorUtil.MAX_FIELDS_OBJECTIVE_AND_SETTINGS) { objectivePane.displayObjective(details); objectivePane.setVisible(true); } details = EditorUtil.transformImageEnvironment(data); notSet = (List) details.get(EditorUtil.NOT_SET); envPane.setVisible(false); if (notSet.size() != EditorUtil.MAX_FIELDS_ENVIRONMENT) { transformEnv(details); envPane.setVisible(true); } details = EditorUtil.transformStageLabel(data); notSet = (List) details.get(EditorUtil.NOT_SET); stagePane.setVisible(false); if (notSet.size() != EditorUtil.MAX_FIELDS_STAGE_LABEL) { transformStage(details); stagePane.setVisible(true); } buildGUI(); } /** Clears the data. */ void setRootObject() { init = false; removeAll(); } /** * Returns <code>true</code> if data to save, <code>false</code> * otherwise. * * @return See above. */ boolean hasDataToSave() { boolean b = objectivePane.hasDataToSave(); if (b) return true; b = parent.hasDataToSave(fieldsEnv); if (b) return true; b = parent.hasDataToSave(fieldsStage); if (b) return true; return false; } /** * Prepares the data to save. * * @return See above. */ ImageAcquisitionData prepareDataToSave() { if (!hasDataToSave()) return null; ImageAcquisitionData data = model.getImageAcquisitionData(); objectivePane.prepareDataToSave(); String key; DataComponent comp; Object value; Number number; Entry entry; //environment Iterator i = fieldsEnv.entrySet().iterator(); float v; while (i.hasNext()) { entry = (Entry) i.next(); key = (String) entry.getKey(); comp = (DataComponent) entry.getValue(); if (comp.isDirty()) { value = comp.getAreaValue(); if (EditorUtil.TEMPERATURE.equals(key)) { number = UIUtilities.extractNumber((String) value, Float.class); if (number != null) data.setTemperature(new TemperatureI((Float) number, UnitsFactory.ImagingEnvironment_Temperature)); } else if (EditorUtil.AIR_PRESSURE.equals(key)) { number = UIUtilities.extractNumber((String) value, Float.class); if (number != null) data.setAirPressure(new PressureI((Float) number, UnitsFactory.ImagingEnvironment_AirPressure)); } else if (EditorUtil.HUMIDITY.equals(key)) { number = UIUtilities.extractNumber((String) value, Float.class); if (number != null) { v = ((Float) number) /100; data.setHumidity(v); } } else if (EditorUtil.CO2_PERCENT.equals(key)) { number = UIUtilities.extractNumber((String) value, Float.class); if (number != null) { v = ((Float) number) /100; data.setCo2Percent(v); } } } } //stage label i = fieldsStage.entrySet().iterator(); while (i.hasNext()) { entry = (Entry) i.next(); key = (String) entry.getKey(); comp = (DataComponent) entry.getValue(); if (comp.isDirty()) { value = comp.getAreaValue(); if (EditorUtil.NAME.equals(key)) { data.setLabelName((String) value); } else if (EditorUtil.POSITION_X.equals(key)) { number = UIUtilities.extractNumber((String) value, Float.class); if (number != null) data.setPositionX(new LengthI((Float) number, UnitsFactory.StageLabel_X)); } else if (EditorUtil.POSITION_Y.equals(key)) { number = UIUtilities.extractNumber((String) value, Float.class); if (number != null) data.setPositionY(new LengthI((Float) number, UnitsFactory.StageLabel_Z)); } else if (EditorUtil.POSITION_Z.equals(key)) { number = UIUtilities.extractNumber((String) value, Float.class); if (number != null) data.setPositionZ(new LengthI((Float) number, UnitsFactory.StageLabel_Y)); } } } return data; } /** * Reacts to property fired by the <code>JLabelButton</code>. * @see PropertyChangeListener#propertyChange(PropertyChangeEvent) */ public void propertyChange(PropertyChangeEvent evt) { String name = evt.getPropertyName(); if (JLabelButton.SELECTED_PROPERTY.equals(name)) { int id = ((Long) evt.getNewValue()).intValue(); switch (id) { case STAGE: displayUnsetStageFields(); break; case ENVIRONMENT: displayUnsetEnvFields(); } } } }