Java tutorial
/* * uDig - User Friendly Desktop Internet GIS client * http://udig.refractions.net * (C) 2011, Refractions Research Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * (http://www.eclipse.org/legal/epl-v10.html), and the Refractions BSD * License v1.0 (http://udig.refractions.net/files/bsd3-v10.html). */ package net.refractions.udig.style.sld.editor.raster; import java.awt.Color; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import net.refractions.udig.style.sld.SLDPlugin; import net.refractions.udig.style.sld.internal.Messages; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.ListViewer; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.opengis.coverage.grid.GridCoverageReader; /** * Classify dialog for classifying raster values * into different bins. * * @author Emily * */ public class ClassifyDialog extends TitleAreaDialog { private static final String GENERATE_LABEL = Messages.ClassifyDialog_GenerateBreaksButtonText; private ComboViewer cmbClass; private ListViewer cmbRanges; private Text txtIgnore; private Text txtSampleSize; private Label lblOp; private Text txtOp; private Button btnCompute; private Button chSampleSize; private List<Double> breaks; private GridCoverageReader layer; private ClassifyFunction currentSelection = null; private Number currentOption = null; private String currentIgnore = null; private Long currentSampleSize = null; private double[] defaultNoData = null; /** * Supported classifications * */ private enum ClassifyFunction { EQUAL_INTERNAL(Messages.ClassifyDialog_EqualIntervalLabel, Messages.ClassifyDialog_NumberofIntervalsLabel), DEFINED_INTERVAL( Messages.ClassifyDialog_DefinedIntervalLabel, Messages.ClassifyDialog_IntervalSizeLabel), QUANTILE(Messages.ClassifyDialog_QuantileLabel, Messages.ClassifyDialog_NumberOfBinsLabel); String guiName; String opName; private ClassifyFunction(String guiName, String opName) { this.guiName = guiName; this.opName = opName; } } /** * Creates a new classify dialog * @param parentShell parent shell * @param layer layer to classify */ public ClassifyDialog(Shell parentShell, GridCoverageReader layer, double[] noDataValues) { super(parentShell); this.layer = layer; this.defaultNoData = noDataValues; } /* (non-Javadoc) * @see org.eclipse.jface.dialogs.Dialog#close() */ public boolean close() { computeValuesJob.cancel(); return super.close(); } @Override protected Control createDialogArea(Composite parent) { breaks = new ArrayList<Double>(); Composite main = new Composite((Composite) super.createDialogArea(parent), SWT.NONE); main.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); GridLayout gl = new GridLayout(2, false); gl.marginWidth = gl.marginHeight = 20; main.setLayout(gl); Label lbl = new Label(main, SWT.NONE); lbl.setText(Messages.ClassifyDialog_ClassificationFunctionLabel); cmbClass = new ComboViewer(main, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER); cmbClass.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); cmbClass.setContentProvider(ArrayContentProvider.getInstance()); cmbClass.setLabelProvider(new LabelProvider() { public String getText(Object x) { if (x instanceof ClassifyFunction) { return ((ClassifyFunction) x).guiName; } return super.getText(x); } }); cmbClass.setInput(ClassifyFunction.values()); cmbClass.getCombo().addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { lblOp.setText(getCurrentSelection().opName); lblOp.getParent().layout(); } }); lblOp = new Label(main, SWT.NONE); lblOp.setText(ClassifyFunction.EQUAL_INTERNAL.opName); txtOp = new Text(main, SWT.BORDER); txtOp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); txtOp.setText("10"); //$NON-NLS-1$ Label lbl4 = new Label(main, SWT.NONE); lbl4.setText(Messages.ClassifyDialog_ValuesToIgnoreLabel + "*"); //$NON-NLS-1$ txtIgnore = new Text(main, SWT.BORDER); txtIgnore.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); if (defaultNoData == null) { txtIgnore.setText(String.valueOf(IColorMapTypePanel.DEFAULT_NO_DATA)); } else { StringBuilder sb = new StringBuilder(); for (double d : defaultNoData) { sb.append(d); sb.append(","); //$NON-NLS-1$ } //remove last "," if (sb.length() > 0) { sb.deleteCharAt(sb.length() - 1); } txtIgnore.setText(sb.toString()); } Label lbls = new Label(main, SWT.NONE); lbls.setText(Messages.ClassifyDialog_LimitSizeLabel); lbls.setToolTipText(Messages.ClassifyDialog_LimitSizeTooltip); Composite compSample = new Composite(main, SWT.NONE); GridLayout gla = new GridLayout(2, false); gla.marginHeight = gla.marginWidth = 0; compSample.setLayout(gla); compSample.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); chSampleSize = new Button(compSample, SWT.CHECK); chSampleSize.setSelection(false); chSampleSize.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { txtSampleSize.setEnabled(chSampleSize.getSelection()); } }); txtSampleSize = new Text(compSample, SWT.BORDER); txtSampleSize.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); txtSampleSize.setText("100000"); //$NON-NLS-1$ txtSampleSize.setEnabled(false); btnCompute = new Button(main, SWT.PUSH); btnCompute.setText(GENERATE_LABEL); btnCompute.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true, false, 2, 1)); btnCompute.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { computeValues(); } }); Label lblSep = new Label(main, SWT.SEPARATOR | SWT.HORIZONTAL); lblSep.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); Label lblRange = new Label(main, SWT.NONE); lblRange.setText(Messages.ClassifyDialog_BreaksLabel); lblRange.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); cmbRanges = new ListViewer(main, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1); gd.widthHint = 150; gd.heightHint = 200; cmbRanges.getControl().setLayoutData(gd); cmbRanges.setLabelProvider(new LabelProvider()); cmbRanges.setContentProvider(ArrayContentProvider.getInstance()); cmbRanges.setInput(breaks); Label lbl3 = new Label(main, SWT.WRAP); lbl3.setText("*" + Messages.ClassifyDialog_IgnoreValuesInfo); //$NON-NLS-1$ lbl3.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); cmbClass.setSelection(new StructuredSelection(ClassifyFunction.EQUAL_INTERNAL)); setMessage(Messages.ClassifyDialog_DialogMessage); setTitle(Messages.ClassifyDialog_DialogTitle); getShell().setText(Messages.ClassifyDialog_ShellTitle); return main; } /** * * @return current selected classification function */ private ClassifyFunction getCurrentSelection() { return (ClassifyFunction) ((IStructuredSelection) cmbClass.getSelection()).getFirstElement(); } /* * computes the breaks */ private void computeValues() { computeValuesJob.cancel(); currentIgnore = txtIgnore.getText(); currentSelection = getCurrentSelection(); currentSampleSize = null; if (chSampleSize.getSelection()) { try { currentSampleSize = Long.parseLong(txtSampleSize.getText()); } catch (Exception ex) { MessageDialog.openError(getShell(), Messages.ClassifyDialog_ErrorDialogTitle, Messages.ClassifyDialog_ErrorMessage); return; } } if (currentSelection == ClassifyFunction.EQUAL_INTERNAL || currentSelection == ClassifyFunction.QUANTILE) { try { currentOption = Integer.parseInt(txtOp.getText()); } catch (Exception ex) { MessageDialog.openError(getShell(), Messages.ClassifyDialog_ErrorDialogTitle, MessageFormat.format( Messages.ClassifyDialog_InvalidValueOption, new Object[] { currentSelection.opName })); return; } if (currentOption.intValue() >= SingleBandEditorPage.MAX_ENTRIES) { MessageDialog.openError(getShell(), Messages.ClassifyDialog_ErrorDialogTitle, MessageFormat.format(Messages.ClassifyDialog_MaxValueError, new Object[] { SingleBandEditorPage.MAX_ENTRIES - 1 })); return; } } else if (currentSelection == ClassifyFunction.DEFINED_INTERVAL) { try { currentOption = Double.parseDouble(txtOp.getText()); } catch (Exception ex) { MessageDialog.openError(getShell(), Messages.ClassifyDialog_ErrorDialogTitle3, MessageFormat.format( Messages.ClassifyDialog_InvalidValueOption2, new Object[] { currentSelection.opName })); } } if (currentOption.doubleValue() <= 0) { MessageDialog.openError(getShell(), Messages.ClassifyDialog_ErrorDialogTitle3, MessageFormat .format(Messages.ClassifyDialog_InvalidValue, new Object[] { currentSelection.opName })); } computeValuesJob.schedule(); } @Override protected boolean isResizable() { return true; } /** * Updates the given panel with the new breaks. * * @param panel must be IntervalValuesPanel or RampValuesPanel */ public void updatePanel(IColorMapTypePanel panel) { if (panel instanceof IntervalValuesPanel || panel instanceof RampValuesPanel) { List<ColorEntry> entries = new ArrayList<ColorEntry>(); for (Double d : breaks) { ColorEntry ce = new ColorEntry(Color.BLACK, 1, d, ""); //$NON-NLS-1$ entries.add(ce); } if (panel instanceof IntervalValuesPanel) { ((IntervalValuesPanel) panel).setBreaks(entries); } else if (panel instanceof RampValuesPanel) { ((RampValuesPanel) panel).setBreaks(entries); } } } /* * Job for computing breaks */ private Job computeValuesJob = new Job(Messages.ClassifyDialog_ComputeBreaksJobName) { @Override protected IStatus run(IProgressMonitor monitor) { ClassifyFunction function = currentSelection; Number op = currentOption; Long sampleSize = currentSampleSize; String ignore = currentIgnore; List<Double> toIgnore = new ArrayList<Double>(); if (ignore.trim().length() > 0) { String[] str = ignore.split(","); //$NON-NLS-1$ for (int i = 0; i < str.length; i++) { try { Double d = Double.parseDouble(str[i]); toIgnore.add(d); } catch (Exception ex) { //eatme } } } double[] valuesToIgnore = new double[toIgnore.size()]; for (int i = 0; i < toIgnore.size(); i++) { valuesToIgnore[i] = toIgnore.get(i); } breaks.clear(); final ClassificationEngine engine = new ClassificationEngine(); if (function == null || op == null) { return Status.CANCEL_STATUS; } try { Display.getDefault().syncExec(new Runnable() { @Override public void run() { cmbRanges.refresh(); btnCompute.setEnabled(false); } }); List<Double> newBreaks = null; if (function == ClassifyFunction.EQUAL_INTERNAL) { newBreaks = engine.computeEqualInterval(((Integer) op).intValue(), valuesToIgnore, layer, sampleSize); } else if (function == ClassifyFunction.DEFINED_INTERVAL) { newBreaks = engine.computeDefinedInterval(((Double) op).doubleValue(), valuesToIgnore, layer, sampleSize); } else if (function == ClassifyFunction.QUANTILE) { newBreaks = engine.computeQuantile(((Integer) op).intValue(), valuesToIgnore, layer, sampleSize, monitor); } if (newBreaks == null || monitor.isCanceled()) { return Status.CANCEL_STATUS; } else { breaks.clear(); breaks.addAll(newBreaks); } } catch (final Exception ex) { Display.getDefault().syncExec(new Runnable() { @Override public void run() { MessageDialog.openError(getShell(), Messages.ClassifyDialog_ErrorDialogTitle5, MessageFormat.format(Messages.ClassifyDialog_ErrorComputingValues, new Object[] { ex.getLocalizedMessage() })); } }); SLDPlugin.log("Error classifying values", ex); //$NON-NLS-1$ } finally { Display.getDefault().syncExec(new Runnable() { @Override public void run() { if (!cmbRanges.getControl().isDisposed()) { setErrorMessage(engine.getLastErrorMessage()); cmbRanges.refresh(); btnCompute.setEnabled(true); } } }); } return Status.OK_STATUS; } }; }