/* * Copyright (C) 2011 Brockmann Consult GmbH (info@brockmann-consult.de) * * 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 3 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, see http://www.gnu.org/licenses/ */ package org.esa.snap.rcp.colormanip; import com.bc.ceres.core.ProgressMonitor; import com.bc.ceres.core.SubProgressMonitor; import com.bc.ceres.swing.ActionLabel; import com.bc.ceres.swing.progress.ProgressMonitorSwingWorker; import org.esa.snap.core.datamodel.RasterDataNode; import org.esa.snap.core.datamodel.Scaling; import org.esa.snap.core.datamodel.Stx; import org.esa.snap.core.util.math.MathUtils; import org.esa.snap.ui.ImageInfoEditor; import org.esa.snap.ui.ImageInfoEditorModel; import org.esa.snap.ui.UIUtils; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.SwingWorker; import javax.swing.border.EmptyBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.BorderLayout; import java.awt.Color; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.text.DecimalFormat; class ImageInfoEditor2 extends ImageInfoEditor { private final ColorManipulationForm parentForm; private boolean showExtraInfo; ImageInfoEditor2(final ColorManipulationForm parentForm) { this.parentForm = parentForm; setLayout(new BorderLayout()); setShowExtraInfo(true); addPropertyChangeListener("model", new ModelChangeHandler()); } public boolean getShowExtraInfo() { return showExtraInfo; } public ColorManipulationForm getParentForm() { return parentForm; } public void setShowExtraInfo(boolean showExtraInfo) { boolean oldValue = this.showExtraInfo; if (oldValue != showExtraInfo) { this.showExtraInfo = showExtraInfo; updateStxOverlayComponent(); firePropertyChange("showExtraInfo", oldValue, this.showExtraInfo); } } private void updateStxOverlayComponent() { removeAll(); add(createStxOverlayComponent(), BorderLayout.NORTH); revalidate(); repaint(); } private JPanel createStxOverlayComponent() { JPanel stxOverlayComponent = new JPanel(new FlowLayout(FlowLayout.RIGHT)); stxOverlayComponent.setOpaque(false); final ImageInfoEditorModel model = getModel(); if (!showExtraInfo || model == null) { return stxOverlayComponent; } stxOverlayComponent.setBorder(new EmptyBorder(4, 0, 0, 8)); JComponent labels = new JComponent() { @Override protected void paintComponent(Graphics g) { g.setColor(getBackground()); g.fillRect(0, 0, getWidth(), getHeight()); } }; labels.setBorder(new EmptyBorder(0, 2, 0, 2)); labels.setLayout(new GridLayout(-1, 1)); labels.setBackground(new Color(255, 255, 255, 127)); stxOverlayComponent.add(labels); labels.add(new JLabel("Name: " + model.getParameterName())); labels.add(new JLabel("Unit: " + model.getParameterUnit())); final Stx stx = model.getSampleStx(); if (stx == null) { return stxOverlayComponent; } labels.add(new JLabel("Min: " + getValueForDisplay(model.getMinSample()))); labels.add(new JLabel("Max: " + getValueForDisplay(model.getMaxSample()))); if (stx.getResolutionLevel() > 0 && model.getSampleScaling() == Scaling.IDENTITY) { final ActionLabel label = new ActionLabel("Rough statistics!"); label.setToolTipText("Click to compute accurate statistics."); label.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { askUser(); } }); labels.add(label); } return stxOverlayComponent; } private String getValueForDisplay(double value) { if (!Double.isNaN(value)) { // prevents NaN to be converted to zero if (value < 0.001 && value > -0.001 && value != 0.0) { return new DecimalFormat("0.##E0").format(value); } value = MathUtils.round(value, 1000.0); } return "" + value; } void askUser() { final int i = JOptionPane.showConfirmDialog(this, "Compute accurate statistics?\n" + "Note that this action may take some time.", "Question", JOptionPane.YES_NO_OPTION); if (i == JOptionPane.YES_OPTION) { SwingWorker sw = new StxComputer(); sw.execute(); } } @Override protected void applyChanges() { parentForm.applyChanges(); } private class ModelChangeHandler implements PropertyChangeListener, ChangeListener { @Override public void stateChanged(ChangeEvent e) { updateStxOverlayComponent(); } @Override public void propertyChange(PropertyChangeEvent evt) { if (!"model".equals(evt.getPropertyName())) { return; } final ImageInfoEditorModel oldModel = (ImageInfoEditorModel) evt.getOldValue(); final ImageInfoEditorModel newModel = (ImageInfoEditorModel) evt.getNewValue(); if (oldModel != null) { oldModel.removeChangeListener(this); } if (newModel != null) { newModel.addChangeListener(this); } updateStxOverlayComponent(); } } private class StxComputer extends ProgressMonitorSwingWorker { private StxComputer() { super(ImageInfoEditor2.this, "Computing statistics"); } @Override protected Object doInBackground(ProgressMonitor pm) throws Exception { UIUtils.setRootFrameWaitCursor(ImageInfoEditor2.this); if (parentForm.getFormModel().isValid()) { final RasterDataNode[] rasters = parentForm.getFormModel().getRasters(); try { pm.beginTask("Computing statistics", rasters.length); for (RasterDataNode raster : rasters) { raster.getStx(true, SubProgressMonitor.create(pm, 1)); } } finally { pm.done(); } } return null; } @Override protected void done() { UIUtils.setRootFrameDefaultCursor(ImageInfoEditor2.this); } } }