// // ContourWidget.java // /* VisAD system for interactive analysis and visualization of numerical data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and Tommy Jasmin. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ package visad.browser; import java.awt.*; import java.awt.event.*; import java.util.StringTokenizer; /** * A widget that allows users to control graphics mode parameters. */ public class ContourWidget extends Widget implements ActionListener, ItemListener { Checkbox contours; Checkbox labels; Checkbox dashed; TextField interval; TextField base; Label surfaceLabel; Slider surface; ContourRangeSlider contourRange; private String cwName; private double cwMinValue; private double cwMaxValue; private boolean cwMainContours; private boolean cwLabels; private float cwSurfaceValue; private float cwContourInterval; private float cwLowLimit; private float cwHiLimit; private float cwBase; /** * Constructs a new ContourWidget. */ public ContourWidget() { // lay out components with GridBagLayout GridBagLayout gridbag = new GridBagLayout(); setLayout(gridbag); // construct GUI components contours = new Checkbox("contours", cwMainContours); labels = new Checkbox("labels", cwLabels); dashed = new Checkbox("dashed lines below base", cwContourInterval < 0); interval = new TextField(Convert.shortString(Math.abs(cwContourInterval))); base = new TextField(Convert.shortString(cwBase)); surfaceLabel = new Label(RangeSlider.DEFAULT_NAME + " = 0"); surface = new Slider(0, 0, 1); contourRange = new ContourRangeSlider(0, 1, this); // add listeners contours.addItemListener(this); labels.addItemListener(this); dashed.addItemListener(this); interval.addActionListener(this); base.addActionListener(this); surface.addActionListener(this); // lay out Components addComponent(contours, gridbag, 1, 0, 1, 1, 0.0, 0.0); addComponent(labels, gridbag, 2, 0, 2, 1, 0.0, 0.0); addComponent(dashed, gridbag, 1, 1, 3, 1, 0.0, 0.0); addComponent(new Label("interval:"), gridbag, 0, 2, 1, 1, 0.0, 0.0); addComponent(interval, gridbag, 1, 2, 1, 1, 1.0, 0.0); addComponent(new Label("base:"), gridbag, 2, 2, 1, 1, 0.0, 0.0); addComponent(base, gridbag, 3, 2, 1, 1, 1.0, 0.0); addComponent(surfaceLabel, gridbag, 0, 3, 4, 1, 1.0, 0.0); addComponent(surface, gridbag, 0, 4, 4, 1, 1.0, 0.0); addComponent(contourRange, gridbag, 0, 5, 4, 1, 1.0, 1.0); } /** * Gets the name of the variable. */ public String getName() { return cwName; } /** * Sets the name of the variable. */ public void setName(String name) { cwName = name; contourRange.setName(name); refreshSurfaceLabel(); } /** * Gets the minimum contouring value. */ public double getMinValue() { return cwMinValue; } /** * Gets the maximum contouring value. */ public double getMaxValue() { return cwMaxValue; } /** * Sets the minimum and maximum contouring values. */ public void setRange(float min, float max) { cwMinValue = min; cwMaxValue = max; surface.setBounds(min, max); contourRange.setBounds(min, max); } /** * Gets the value of the contours checkbox. */ public boolean getMainContours() { return cwMainContours; } /** * Sets the value of the contours checkbox. */ public void setMainContours(boolean mc) { cwMainContours = mc; contours.setState(mc); } /** * Gets the value of the labels checkbox. */ public boolean getLabels() { return cwLabels; } /** * Sets the value of the labels checkbox. */ public void setLabels(boolean lb) { cwLabels = lb; labels.setState(lb); } /** * Gets the value of the surface value slider. */ public float getSurfaceValue() { return cwSurfaceValue; } /** * Sets the value of the surface value slider. */ public void setSurfaceValue(float sv) { cwSurfaceValue = sv; surface.setValue(sv); refreshSurfaceLabel(); } /** * Gets the value of the interval text field. */ public float getContourInterval() { return cwContourInterval; } /** * Sets the value of the interval text field. */ public void setContourInterval(float ci) { cwContourInterval = ci; interval.setText(Convert.shortString(Math.abs(ci))); dashed.setState(ci < 0); } /** * Gets the low value of the contour range slider. */ public float getLowLimit() { return cwLowLimit; } /** * Gets the hi value of the contour range slider. */ public float getHiLimit() { return cwHiLimit; } /** * Sets the range of the contour range slider. */ public void setLimits(float lo, float hi) { cwLowLimit = lo; cwHiLimit = hi; contourRange.setValues(lo, hi); } /** * Gets the value of the base text field. */ public float getBase() { return cwBase; } /** * Sets the value of the base text field. */ public void setBase(float bs) { cwBase = bs; base.setText(Convert.shortString(bs)); } /** * Gets a string representing this widget's current state. */ public String getSaveString() { return cwMainContours + " " + cwLabels + " " + cwSurfaceValue + " " + cwContourInterval + " " + cwLowLimit + " " + cwHiLimit + " " + cwBase; } /** * Reconstructs this widget's state using the specified save string. */ public void setSaveString(String save) { if (save == null) { if (DEBUG) System.err.println("Invalid save string"); return; } StringTokenizer st = new StringTokenizer(save); if (st.countTokens() < 7) { if (DEBUG) System.err.println("Invalid save string"); return; } // determine contour settings boolean mc = Convert.getBoolean(st.nextToken()); boolean lb = Convert.getBoolean(st.nextToken()); float sv = Convert.getFloat(st.nextToken()); float ci = Convert.getFloat(st.nextToken()); float lo = Convert.getFloat(st.nextToken()); float hi = Convert.getFloat(st.nextToken()); float bs = Convert.getFloat(st.nextToken()); // reset contour settings setMainContours(mc); setLabels(lb); setSurfaceValue(sv); setContourInterval(ci); setLimits(lo, hi); setBase(bs); } /** * Refreshes the surface label text. */ private void refreshSurfaceLabel() { surfaceLabel.setText((cwName == null ? RangeSlider.DEFAULT_NAME : cwName) + " = " + (Float.isNaN(cwSurfaceValue) ? "---" : Convert.shortString(cwSurfaceValue))); } /** * Handles TextField changes. */ public void actionPerformed(ActionEvent e) { Object source = e.getSource(); if (source == interval) { // interval changed float iv = Float.NaN; try { iv = Float.valueOf(interval.getText()).floatValue(); } catch (NumberFormatException exc) { interval.setText(Convert.shortString(Math.abs(cwContourInterval))); } if (iv > 0) { if (dashed.getState()) iv = -iv; setContourInterval(iv); contours.requestFocus(); notifyListeners(new WidgetEvent(this)); } } else if (source == base) { // base value changed float bs = Float.NaN; try { bs = Float.valueOf(base.getText()).floatValue(); } catch (NumberFormatException exc) { base.setText(Convert.shortString(cwBase)); } if (bs == bs) { setBase(bs); contours.requestFocus(); notifyListeners(new WidgetEvent(this)); } } else if (source == surface) { // surface slider value changed float sv = surface.getValue(); setSurfaceValue(sv); notifyListeners(new WidgetEvent(this)); } } /** * Handles Checkbox changes. */ public void itemStateChanged(ItemEvent e) { Object source = e.getItemSelectable(); boolean on = (e.getStateChange() == ItemEvent.SELECTED); if (source == contours) setMainContours(on); else if (source == labels) setLabels(on); else if (source == dashed) setContourInterval(-cwContourInterval); notifyListeners(new WidgetEvent(this)); } /** * Tests ContourWidget. */ public static void main(String[] args) { new ContourWidget().testWidget(); } /** * Subclass of RangeSlider for selecting min and max values. */ class ContourRangeSlider extends RangeSlider { /** * Parent of this range slider. */ private ContourWidget widget; /** * Constructs a new range slider for the contour widget. */ ContourRangeSlider(float min, float max, ContourWidget parent) { super(DEFAULT_NAME, min, max); widget = parent; } /** * Tells parent when the values have changed. */ public void valuesUpdated() { widget.setLimits(minValue, maxValue); widget.notifyListeners(new WidgetEvent(widget)); } } }