This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository tutti. See http://git.codelutin.com/tutti.git commit afa891ceacc67b4d11e13f18828b75ce65ed8bb9 Author: Tony CHEMIT <chemit@codelutin.com> Date: Tue Feb 10 16:00:57 2015 +0100 fixes #6630 (ajout d'une nouvelle couleur pour les macro-déchets + changement des libellés fixes #6636 Report des actions et suppression de l'ancien code --- .../operation/catches/EditCatchesSvgHandler.java | 735 +++++++++++++++++++++ 1 file changed, 735 insertions(+) diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/EditCatchesSvgHandler.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/EditCatchesSvgHandler.java new file mode 100644 index 0000000..e31ce1f --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/EditCatchesSvgHandler.java @@ -0,0 +1,735 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches; + +import com.google.common.base.Function; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import com.google.common.collect.Sets; +import fr.ifremer.tutti.TuttiConfiguration; +import fr.ifremer.tutti.persistence.entities.data.CatchBatch; +import fr.ifremer.tutti.persistence.entities.data.FishingOperation; +import fr.ifremer.tutti.type.WeightUnit; +import fr.ifremer.tutti.ui.swing.TuttiUIContext; +import fr.ifremer.tutti.ui.swing.util.TuttiUIUtil; +import fr.ifremer.tutti.ui.swing.util.catches.EnterWeightUI; +import fr.ifremer.tutti.ui.swing.util.computable.ComputableData; +import fr.ifremer.tutti.util.Numbers; +import fr.ifremer.tutti.util.Weights; +import jaxx.runtime.JAXXUtil; +import org.apache.batik.dom.svg.SAXSVGDocumentFactory; +import org.apache.batik.dom.svg.SVGOMRectElement; +import org.apache.batik.dom.svg.SVGOMTextElement; +import org.apache.batik.swing.JSVGCanvas; +import org.apache.batik.swing.gvt.GVTTreeRendererAdapter; +import org.apache.batik.swing.gvt.GVTTreeRendererEvent; +import org.apache.batik.swing.svg.SVGUserAgentAdapter; +import org.apache.batik.util.XMLResourceDescriptor; +import org.apache.commons.beanutils.BeanUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.util.Resource; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.css.CSSStyleDeclaration; +import org.w3c.dom.events.EventListener; +import org.w3c.dom.events.EventTarget; +import org.w3c.dom.svg.SVGRect; +import org.w3c.dom.svg.SVGStylable; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.IOException; +import java.net.URL; +import java.util.Objects; +import java.util.Set; + +import static org.nuiton.i18n.I18n.n; +import static org.nuiton.i18n.I18n.t; + +/** + * Created on 2/10/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.13 + */ +public class EditCatchesSvgHandler { + + /** Logger. */ + private static final Log log = LogFactory.getLog(EditCatchesSvgHandler.class); + + protected Multimap<String, PropertyChangeListener> svgRelatedPropertyChangeListeners = HashMultimap.create(); + + protected JSVGCanvas canvas; + + protected Document svgDocument; + + protected final TuttiUIContext context; + + protected final EditCatchesUI ui; + + protected final EditCatchesUIModel model; + + protected final SVGUserAgentAdapter ua = new SVGUserAgentAdapter() { + @Override + public void displayError(String message) { + if (log.isErrorEnabled()) { + log.error("Canvas error: " + message); + } + } + + @Override + public void displayError(Exception ex) { + if (log.isErrorEnabled()) { + log.error("Canvas error", ex); + } + } + }; + + public EditCatchesSvgHandler(TuttiUIContext context, EditCatchesUI ui, EditCatchesUIModel model) { + this.context = context; + this.ui = ui; + this.model = model; + } + + + { + n("tutti.editCatchBatch.field.speciesDistinctSortedSpeciesCount"); + n("tutti.editCatchBatch.field.benthosDistinctSortedSpeciesCount"); + + } + + + public void clearSVG() { + for (String property : svgRelatedPropertyChangeListeners.keySet()) { + for (PropertyChangeListener listener : svgRelatedPropertyChangeListeners.get(property)) { + if (property != null) { + model.removePropertyChangeListener(property, listener); + } else { + model.removePropertyChangeListener(listener); + } + } + } + svgRelatedPropertyChangeListeners.clear(); + + if (canvas != null) { + canvas.dispose(); + ui.getSvgCanvasPanel().remove(canvas); + } + } + + public void initResumeSvg() { + try { + String parser = XMLResourceDescriptor.getXMLParserClassName(); + SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser); + URL url = Resource.getURL("EcranResume.svg"); + svgDocument = f.createDocument(url.toString()); + + // redefine user agent to avoid displaying errors about css + canvas = new JSVGCanvas(ua, true, true); + canvas.setBackground(Color.decode("#d6d9df")); + canvas.setSize(new Dimension(1, 1)); + canvas.setMySize(new Dimension(1, 1)); + + canvas.setRecenterOnResize(true); + + final TuttiConfiguration config = context.getConfig(); + + final Color catchColor = config.getColorCatch(); + final Color speciesColor = config.getColorSpecies(); + final Color benthosColor = config.getColorBenthos(); + + canvas.addGVTTreeRendererListener(new GVTTreeRendererAdapter() { + @Override + public void gvtRenderingCompleted(GVTTreeRendererEvent gvtTreeRendererEvent) { + if (log.isDebugEnabled()) { + log.debug("gvtRenderingCompleted"); + } + WeightUnit catchWeightUnit = WeightUnit.KG; + WeightUnit speciesWeightUnit = config.getSpeciesWeightUnit(); + WeightUnit benthosWeightUnit = config.getBenthosWeightUnit(); + WeightUnit marineLitterWeightUnit = config.getMarineLitterWeightUnit(); + + initSvgField(CatchBatch.PROPERTY_CATCH_TOTAL_WEIGHT, + CatchBatch.PROPERTY_CATCH_TOTAL_COMPUTED_WEIGHT, + model.getCatchTotalComputedOrNotWeight(), + catchWeightUnit, + catchColor); + + initSvgField(CatchBatch.PROPERTY_CATCH_TOTAL_SORTED_COMPUTED_WEIGHT, catchWeightUnit, catchColor); + initSvgField(CatchBatch.PROPERTY_CATCH_TOTAL_REJECTED_WEIGHT, + CatchBatch.PROPERTY_CATCH_TOTAL_REJECTED_COMPUTED_WEIGHT, + model.getCatchTotalRejectedComputedOrNotWeight(), + catchWeightUnit, + catchColor); + initSvgField(CatchBatch.PROPERTY_CATCH_TOTAL_SORTED_SORTED_COMPUTED_WEIGHT, catchWeightUnit, catchColor); + + initSvgField(CatchBatch.PROPERTY_SPECIES_TOTAL_SORTED_WEIGHT, + CatchBatch.PROPERTY_SPECIES_TOTAL_SORTED_COMPUTED_WEIGHT, + model.getSpeciesTotalSortedComputedOrNotWeight(), + speciesWeightUnit, + speciesColor); + initSvgField(CatchBatch.PROPERTY_SPECIES_TOTAL_SAMPLE_SORTED_COMPUTED_WEIGHT, speciesWeightUnit, speciesColor); + + initSvgField(CatchBatch.PROPERTY_BENTHOS_TOTAL_SORTED_WEIGHT, + CatchBatch.PROPERTY_BENTHOS_TOTAL_SORTED_COMPUTED_WEIGHT, + model.getBenthosTotalSortedComputedOrNotWeight(), + benthosWeightUnit, + benthosColor); + initSvgField(CatchBatch.PROPERTY_BENTHOS_TOTAL_SAMPLE_SORTED_COMPUTED_WEIGHT, benthosWeightUnit, benthosColor); + + initSvgField(CatchBatch.PROPERTY_CATCH_TOTAL_UNSORTED_COMPUTED_WEIGHT, catchWeightUnit, catchColor); + initSvgField(CatchBatch.PROPERTY_SPECIES_TOTAL_UNSORTED_COMPUTED_WEIGHT, speciesWeightUnit, speciesColor); + initSvgField(CatchBatch.PROPERTY_BENTHOS_TOTAL_UNSORTED_COMPUTED_WEIGHT, benthosWeightUnit, benthosColor); + + addSvgRelatedPropertyChangeListener(null, new ChangeElementBackgroundColorPropertyChangeListener( + CatchBatch.PROPERTY_SPECIES_TOTAL_UNSORTED_COMPUTED_WEIGHT, + Sets.newHashSet(CatchBatch.PROPERTY_CATCH_TOTAL_REJECTED_WEIGHT, + CatchBatch.PROPERTY_CATCH_TOTAL_REJECTED_COMPUTED_WEIGHT, + CatchBatch.PROPERTY_SPECIES_TOTAL_SORTED_WEIGHT, + CatchBatch.PROPERTY_SPECIES_TOTAL_SORTED_COMPUTED_WEIGHT, + CatchBatch.PROPERTY_SPECIES_TOTAL_SAMPLE_SORTED_COMPUTED_WEIGHT), + new Function<EditCatchesUIModel, Color>() { + @Override + public Color apply(EditCatchesUIModel model) { + boolean warning = model.isSpeciesTotalUnsortedComputedWeightInWarning(); + return warning ? Color.ORANGE : speciesColor; + } + })); + + addSvgRelatedPropertyChangeListener(null, new ChangeElementBackgroundColorPropertyChangeListener( + CatchBatch.PROPERTY_BENTHOS_TOTAL_UNSORTED_COMPUTED_WEIGHT, + Sets.newHashSet(CatchBatch.PROPERTY_CATCH_TOTAL_REJECTED_WEIGHT, + CatchBatch.PROPERTY_CATCH_TOTAL_REJECTED_COMPUTED_WEIGHT, + CatchBatch.PROPERTY_BENTHOS_TOTAL_SORTED_WEIGHT, + CatchBatch.PROPERTY_BENTHOS_TOTAL_SORTED_COMPUTED_WEIGHT, + CatchBatch.PROPERTY_BENTHOS_TOTAL_SAMPLE_SORTED_COMPUTED_WEIGHT), + new Function<EditCatchesUIModel, Color>() { + @Override + public Color apply(EditCatchesUIModel model) { + boolean warning = model.isBenthosTotalUnsortedComputedWeightInWarning(); + return warning ? Color.ORANGE : benthosColor; + } + })); + + initSvgField(CatchBatch.PROPERTY_SPECIES_TOTAL_COMPUTED_WEIGHT, + speciesWeightUnit, + speciesColor, + CatchBatch.PROPERTY_BENTHOS_TOTAL_COMPUTED_WEIGHT, + CatchBatch.PROPERTY_MARINE_LITTER_TOTAL_WEIGHT); + initSvgField(CatchBatch.PROPERTY_BENTHOS_TOTAL_COMPUTED_WEIGHT, + benthosWeightUnit, + benthosColor, + CatchBatch.PROPERTY_SPECIES_TOTAL_COMPUTED_WEIGHT, + CatchBatch.PROPERTY_MARINE_LITTER_TOTAL_WEIGHT); + initSvgField(CatchBatch.PROPERTY_MARINE_LITTER_TOTAL_WEIGHT, + CatchBatch.PROPERTY_MARINE_LITTER_TOTAL_COMPUTED_WEIGHT, + model.getMarineLitterTotalComputedOrNotWeight(), + marineLitterWeightUnit, + catchColor, + CatchBatch.PROPERTY_SPECIES_TOTAL_COMPUTED_WEIGHT, + CatchBatch.PROPERTY_BENTHOS_TOTAL_COMPUTED_WEIGHT); + + addSvgRelatedPropertyChangeListener(null, new RatioPropertyChangeListener("ratioSpeciesSampleSortedOverSpeciesSortedWeightLabel", + CatchBatch.PROPERTY_SPECIES_TOTAL_SAMPLE_SORTED_COMPUTED_WEIGHT, + CatchBatch.PROPERTY_SPECIES_TOTAL_SORTED_WEIGHT, + CatchBatch.PROPERTY_SPECIES_TOTAL_SORTED_COMPUTED_WEIGHT)); + addSvgRelatedPropertyChangeListener(null, new RatioPropertyChangeListener("ratioBenthosSampleSortedOverBenthosSortedWeightLabel", + CatchBatch.PROPERTY_BENTHOS_TOTAL_SAMPLE_SORTED_COMPUTED_WEIGHT, + CatchBatch.PROPERTY_BENTHOS_TOTAL_SORTED_WEIGHT, + CatchBatch.PROPERTY_BENTHOS_TOTAL_SORTED_COMPUTED_WEIGHT)); + addSvgRelatedPropertyChangeListener(null, new RatioPropertyChangeListener("ratioSortedSortedOverSortedWeightLabel", + CatchBatch.PROPERTY_CATCH_TOTAL_SORTED_SORTED_COMPUTED_WEIGHT, + CatchBatch.PROPERTY_CATCH_TOTAL_SORTED_COMPUTED_WEIGHT, + CatchBatch.PROPERTY_CATCH_TOTAL_SORTED_COMPUTED_WEIGHT)); + + initSpeciesCount(CatchBatch.PROPERTY_SPECIES_DISTINCT_SORTED_SPECIES_COUNT); + initSpeciesCount(CatchBatch.PROPERTY_BENTHOS_DISTINCT_SORTED_SPECIES_COUNT); + + initTremieCarrouselField(CatchBatch.PROPERTY_CATCH_TOTAL_SORTED_CAROUSSEL_WEIGHT, catchWeightUnit); + initTremieCarrouselField(CatchBatch.PROPERTY_CATCH_TOTAL_SORTED_TREMIS_WEIGHT, catchWeightUnit); + + ui.getSvgCanvasPanel().add(canvas, BorderLayout.CENTER); + } + }); + + canvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC); + canvas.setDocument(svgDocument); + + } catch (IOException err) { + if (log.isErrorEnabled()) { + log.error("error while initializing the resume background", err); + } + context.getErrorHelper().showErrorDialog(t("tutti.editCatchBatch.svgLoading.error"), err); + } + } + + protected void initSvgField(String computedProperty, WeightUnit weightUnit, Color bgColor, String... idsInGroup) { + initSvgField(null, computedProperty, null, weightUnit, bgColor, idsInGroup); + } + + protected void initSvgField(String property, + String computedProperty, + final ComputableData<Float> computableData, + final WeightUnit weightUnit, + final Color bgColor, + final String... idsInGroup) { + + if (log.isDebugEnabled()) { + log.debug("init " + property + " field"); + } + + final String notNullProperty = property != null ? property : computedProperty; + + OnDataOrComputedDataValueChangedListener listener = new OnDataOrComputedDataValueChangedListener(notNullProperty, computableData, weightUnit, idsInGroup); + if (property != null) { + addSvgRelatedPropertyChangeListener(property, listener); + } + if (computedProperty != null) { + addSvgRelatedPropertyChangeListener(computedProperty, listener); + } + + if (computableData != null) { + // data or computed data value + Element element = svgDocument.getElementById(property); + EventTarget target = (EventTarget) element; + target.addEventListener("click", new OnValueClickListener(computableData, property, weightUnit), false); + } + + updateOnCanvas(new Runnable() { + @Override + public void run() { + + SVGOMRectElement rectElement = (SVGOMRectElement) svgDocument.getElementById(notNullProperty + "Rect"); + SVGRect bbox = rectElement.getBBox(); + Float x = bbox.getX(); + + SVGOMTextElement labelElement = (SVGOMTextElement) svgDocument.getElementById(notNullProperty + "Label"); + CSSStyleDeclaration style = labelElement.getStyle(); + if (computableData == null) { + style.setProperty("font-style", "italic", null); + } + int colorBrightness = TuttiUIUtil.getColorBrightness(bgColor); + String textColor = colorBrightness > 150 ? "#000000" : "#FFFFFF"; + style.setProperty("fill", textColor, null); + + labelElement.setTextContent(weightUnit.decorateLabel(t("tutti.editCatchBatch.field." + notNullProperty))); + bbox = labelElement.getBBox(); + float labelX = bbox.getX(); + float width = Math.abs(x - labelX) + 10; + + SVGOMRectElement labelRectElement = (SVGOMRectElement) svgDocument.getElementById(notNullProperty + "LabelRect"); + float actualWidth = Math.abs(labelRectElement.getBBox().getX() - labelX) + 10; + + if (actualWidth < width) { + labelRectElement.setAttribute("width", Float.toString(width)); + labelRectElement.setAttribute("x", String.valueOf(labelX - 10)); + + for (String id : idsInGroup) { + Element el = svgDocument.getElementById(id + "LabelRect"); + el.setAttribute("width", Float.toString(width)); + el.setAttribute("x", String.valueOf(labelX - 10)); + } + } + + style = labelRectElement.getStyle(); + String hexaColor = "#" + Integer.toHexString(bgColor.getRGB()).substring(2); + style.setProperty("fill", hexaColor, null); + + Float value; + boolean computed; + if (computableData == null) { + computed = true; + value = getModelPropertyValue(notNullProperty); + + } else if (computableData.getData() == null) { + computed = true; + value = computableData.getComputedData(); + + } else { + computed = false; + value = computableData.getData(); + } + + updateValue(notNullProperty, value, weightUnit, computed, idsInGroup); + } + }); + + } + + protected void updateOnCanvas(Runnable runnable) { + try { + canvas.getUpdateManager().getUpdateRunnableQueue().invokeLater(runnable); + } catch (IllegalStateException e) { + if (log.isErrorEnabled()) { + log.error("error while updating canvas, reload it"); + } + clearSVG(); + initResumeSvg(); + } + } + + protected void addSvgRelatedPropertyChangeListener(String property, PropertyChangeListener listener) { + svgRelatedPropertyChangeListeners.put(property, listener); + if (property != null) { + model.addPropertyChangeListener(property, listener); + } else { + model.addPropertyChangeListener(listener); + } + } + + protected void updateValue(final String property, + final Float value, + final WeightUnit weightUnit, + final boolean computed, + final String... idsInGroup) { + + updateOnCanvas(new Runnable() { + public void run() { + if (log.isDebugEnabled()) { + log.debug("update " + property + " field"); + } + + SVGOMTextElement valueElement = (SVGOMTextElement) svgDocument.getElementById(property + "Value"); + if (valueElement == null) { + return; + } + + //TODO i18n ? + String textContent; + if (value != null) { + textContent = Weights.getWeightStringValue(value) + " " + weightUnit.getShortLabel(); + } else { + textContent = null; + } + valueElement.setTextContent(textContent); + + CSSStyleDeclaration style = valueElement.getStyle(); + + Color colorComputedWeights = context.getConfig().getColorComputedWeights(); + String computedColor = "#" + Integer.toHexString(colorComputedWeights.getRGB()).substring(2); + style.setProperty("fill", computed ? computedColor : "#000000", null); + style.setProperty("font-style", computed ? "italic" : "normal", null); + + SVGRect bbox = valueElement.getBBox(); + SVGOMRectElement rectElement = (SVGOMRectElement) svgDocument.getElementById(property + "Rect"); + if (bbox != null && rectElement != null) { + float width = bbox.getWidth() + 15; + float actualWidth = rectElement.getBBox().getWidth(); + if (actualWidth < width) { + rectElement.setAttribute("width", Float.toString(width)); + for (String id : idsInGroup) { + Element el = svgDocument.getElementById(id + "Rect"); + el.setAttribute("width", Float.toString(width)); + } + } + } + } + }); + + } + + protected Float getModelPropertyValue(String property) { + Float value; + try { + String sValue = BeanUtils.getProperty(model, property); + if (sValue != null) { + value = Float.parseFloat(sValue); + } else { + value = null; + } + + } catch (ReflectiveOperationException e) { + if (log.isErrorEnabled()) { + log.error("error on reading model's property " + property, e); + } + value = null; + } + return value; + } + + protected void initSpeciesCount(final String property) { + + if (log.isDebugEnabled()) { + log.debug("init " + property + " field"); + } + + updateOnCanvas(new Runnable() { + @Override + public void run() { + Element labelElement = svgDocument.getElementById(property + "Label"); + labelElement.setTextContent(t("tutti.editCatchBatch.field." + property)); + + Element valueElement = svgDocument.getElementById(property + "Value"); + Integer value; + try { + String sValue = BeanUtils.getProperty(model, property); + if (sValue != null) { + value = Integer.parseInt(sValue); + } else { + value = null; + } + + } catch (ReflectiveOperationException e) { + if (log.isErrorEnabled()) { + log.error("error on reading model's property " + property, e); + } + value = null; + } + valueElement.setTextContent(JAXXUtil.getStringValue(value)); + } + }); + + addSvgRelatedPropertyChangeListener(property, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + Integer value = (Integer) evt.getNewValue(); + Element labelElement = svgDocument.getElementById(property + "Value"); + labelElement.setTextContent(JAXXUtil.getStringValue(value)); + } + }); + } + + protected void initTremieCarrouselField(final String property, final WeightUnit weightUnit) { + if (log.isDebugEnabled()) { + log.debug("init " + property + " field"); + } + + updateOnCanvas(new Runnable() { + @Override + public void run() { + Element labelElement = svgDocument.getElementById(property + "Label"); + labelElement.setTextContent(weightUnit.decorateLabel(t("tutti.editCatchBatch.field." + property))); + } + }); + + addSvgRelatedPropertyChangeListener(property, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + Float value = (Float) evt.getNewValue(); + updateValue(property, value, weightUnit, true); + } + }); + + Float value = getModelPropertyValue(property); + updateValue(property, value, weightUnit, true); + + addSvgRelatedPropertyChangeListener(EditCatchesUIModel.PROPERTY_FISHING_OPERATION, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + updateTremieCarrouselVisibility(property); + } + }); + updateTremieCarrouselVisibility(property); + } + + + protected void updateTremieCarrouselVisibility(String property) { + FishingOperation fishingOperation = model.getFishingOperation(); + if (fishingOperation != null) { + boolean tremieCarrouselFieldsVisisble = fishingOperation.getVessel() != null + && fishingOperation.getVessel().getId().equals(context.getConfig().getTremieCarousselVesselId()); + + Element labelElement = svgDocument.getElementById(property + "Label"); + labelElement.setAttribute("visibility", tremieCarrouselFieldsVisisble ? "visible" : "hidden"); + + Element valueElement = svgDocument.getElementById(property + "Value"); + valueElement.setAttribute("visibility", tremieCarrouselFieldsVisisble ? "visible" : "hidden"); + } + } + + private class OnValueClickListener implements EventListener { + + private final ComputableData<Float> computableData; + + private final String property; + + private final WeightUnit weightUnit; + + public OnValueClickListener(ComputableData<Float> computableData, String property, WeightUnit weightUnit) { + this.computableData = computableData; + this.property = property; + this.weightUnit = weightUnit; + } + + public void handleEvent(org.w3c.dom.events.Event evt) { + log.info("element clicked"); + EnterWeightUI dialog = new EnterWeightUI(context); + Float originalWeight = computableData.getData(); + Float weight = dialog.openAndGetWeightValue(t("tutti.editCatchBatch.field." + property), + originalWeight, + weightUnit); + + if (!Objects.equals(originalWeight, weight)) { + + computableData.setData(weight); + } + } + } + + private class OnDataOrComputedDataValueChangedListener implements PropertyChangeListener { + + private final String property; + + private final ComputableData<Float> computableData; + + private final WeightUnit weightUnit; + + private final String[] idsInGroup; + + public OnDataOrComputedDataValueChangedListener(String property, + ComputableData<Float> computableData, + WeightUnit weightUnit, + String... idsInGroup) { + this.property = property; + this.computableData = computableData; + this.weightUnit = weightUnit; + this.idsInGroup = idsInGroup; + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + boolean computedData; + Float newValue; + + if (computableData == null) { + computedData = true; + newValue = (Float) evt.getNewValue(); + + } else { + if (computableData.getData() == null) { + computedData = true; + newValue = computableData.getComputedData(); + + } else { + computedData = false; + newValue = computableData.getData(); + } + } + updateValue(property, newValue, weightUnit, computedData, idsInGroup); + } + + } + + private class ChangeElementBackgroundColorPropertyChangeListener implements PropertyChangeListener { + + private final String elementId; + + private Set<String> propertiesToListen; + + private Function<EditCatchesUIModel, Color> colorFunction; + + public ChangeElementBackgroundColorPropertyChangeListener(String elementId, + Set<String> propertiesToListen, + Function<EditCatchesUIModel, Color> colorFunction) { + this.elementId = elementId; + this.propertiesToListen = propertiesToListen; + this.colorFunction = colorFunction; + + updateColor(); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (propertiesToListen.contains(evt.getPropertyName())) { + updateColor(); + } + } + + protected void updateColor() { + updateOnCanvas(new Runnable() { + public void run() { + if (log.isDebugEnabled()) { + log.debug("update " + elementId + " field"); + } + + Element rectElement = svgDocument.getElementById(elementId + "LabelRect"); + SVGStylable field = (SVGStylable) rectElement; + CSSStyleDeclaration style = field.getStyle(); + + final Color background = colorFunction.apply(model); + String color = "#" + Integer.toHexString(background.getRGB()).substring(2); + style.setProperty("fill", color, null); + } + }); + } + } + + private class RatioPropertyChangeListener implements PropertyChangeListener { + + private final String elementId; + + private final String numeratorProperty; + + private final String denominatorProperty; + + private final String denominatorComputedProperty; + + private Integer ratio = null; + + public RatioPropertyChangeListener(String elementId, + String numeratorProperty, + String denominatorProperty, + String denominatorComputedProperty) { + this.elementId = elementId; + this.numeratorProperty = numeratorProperty; + this.denominatorProperty = denominatorProperty; + this.denominatorComputedProperty = denominatorComputedProperty; + + updateRatioText(); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + String propertyName = evt.getPropertyName(); + + if (propertyName.equals(numeratorProperty) || propertyName.equals(denominatorProperty)) { + updateRatioText(); + } + } + + protected void updateRatioText() { + + try { + String numerator = BeanUtils.getProperty(model, numeratorProperty); + String denominator = BeanUtils.getProperty(model, denominatorProperty); + if (denominator == null) { + denominator = BeanUtils.getProperty(model, denominatorComputedProperty); + } + + if (numerator != null && denominator != null) { + Float numeratorValue = Float.valueOf(numerator); + Float denominatorValue = Float.valueOf(denominator); + + if (denominatorValue != 0) { + ratio = Numbers.roundToInt(100f * numeratorValue / denominatorValue); + } + } + + } catch (ReflectiveOperationException e) { + if (log.isErrorEnabled()) { + log.error("Error while computing the ration", e); + } + } + + updateOnCanvas(new Runnable() { + public void run() { + if (log.isDebugEnabled()) { + log.debug("update " + elementId + " field"); + } + + Element ratioElement = svgDocument.getElementById(elementId); + String textContent; + if (ratio != null) { + textContent = ratio + "%"; + } else { + textContent = null; + } + ratioElement.setTextContent(textContent); + } + }); + } + } + +} -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.