ucar.unidata.idv.control.chart.WayPoint.java Source code

Java tutorial

Introduction

Here is the source code for ucar.unidata.idv.control.chart.WayPoint.java

Source

/*
 * Copyright 1997-2019 Unidata Program Center/University Corporation for
 * Atmospheric Research, P.O. Box 3000, Boulder, CO 80307,
 * support@unidata.ucar.edu.
 * 
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 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 Lesser
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser 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 ucar.unidata.idv.control.chart;

import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.event.AnnotationChangeListener;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.ui.RectangleEdge;

import ucar.unidata.util.GuiUtils;
import ucar.unidata.util.MidiManager;
import ucar.unidata.util.MidiProperties;
import ucar.unidata.util.Misc;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.Rectangle2D;

import java.util.Date;
import java.util.List;

import javax.swing.JLabel;
import javax.swing.JTextField;

/**
 * Class WayPoint is used in the time series chart to show a way point
 * along the time domain
 *
 *
 * @author IDV Development Team
 * @version $Revision: 1.22 $
 */
public class WayPoint extends ChartAnnotation {

    /** Plays sounds */
    private MidiManager midiManager;

    /** Draws the clock */
    private static Image clockImage;

    /** Draws the clock */
    private static Image noteImage;

    /** Used for property changed when waypoint is moved */
    public static final String PROP_WAYPOINTVALUE = "prop.waypointvalue";

    /** Arrow width */
    public static final int ANNOTATION_WIDTH = 10;

    /** The domain value */
    private double domainValue = 0.0;

    /** Is this the special way point used to show time animation */
    private boolean isForAnimation = false;

    /** Span */
    private double minutesSpan = 0.0;

    /** For properties */
    private JTextField spanFld;

    /** MidiProperties */
    private MidiProperties midiProperties = new MidiProperties();

    /**
     * Default ctor
     */
    public WayPoint() {
    }

    /**
     * Ctor
     *
     * @param domainValue The domain value
     * @param timeseries The chart I'm in
     */
    public WayPoint(double domainValue, TimeSeriesChartWrapper timeseries) {
        super(timeseries);
        this.domainValue = domainValue;
    }

    /**
     * Create, if needed, and return the midimanager that plays sounds
     *
     * @return The midi manager
     */
    public MidiManager getMidiManager() {
        if (midiManager == null) {
            midiManager = new MidiManager(midiProperties);
        }
        return midiManager;
    }

    /**
     * Get the tool tip text
     *
     * @return Tool tip text
     */
    public String getToolTipText() {
        return "<html>Way point: <b>" + new Date((long) domainValue) + "</b></html>";
    }

    /**
     * Type of annotation
     *
     * @return Type of annotation
     */
    public String getTypeName() {
        return "Waypoint";
    }

    /**
     * Set the position to the given x/y screen coordinate
     *
     * @param x x
     * @param y y
     */
    public void setPosition(int x, int y) {
        TimeSeriesChartWrapper tscw = (TimeSeriesChartWrapper) getPlotWrapper();
        double domainValue = tscw.getDomainValue(x);
        setDomainValue(domainValue);
        this.x = x;
        this.y = y;
    }

    /**
     * What color should we use. If selected use the selected color
     *
     * @return The color
     */
    public Color getColorToUse() {
        if (getSelected()) {
            return COLOR_SELECTED;
        } else {
            return getColor();
        }
    }

    /**
     * Should the color swatch be shown in the properties dialog
     *
     * @return Show color in properties
     */
    protected boolean showColorInProperties() {
        return true;
    }

    /**
     * return the array of tab names for the proeprties dialog
     *
     * @return array of tab names
     */
    public String[] getPropertyTabs() {
        return new String[] { "Display", "Sound" };
    }

    /**
     * Add to properties gui
     *
     *
     * @param comps List of comps
     * @param tabIdx Which tab in the properties dialog
     */
    protected void getPropertiesComponents(List comps, int tabIdx) {
        super.getPropertiesComponents(comps, tabIdx);
        if (tabIdx == 0) {
            comps.add(GuiUtils.rLabel("Span: "));
            comps.add(GuiUtils
                    .left(GuiUtils.hbox(spanFld = new JTextField("" + minutesSpan, 5), new JLabel(" (minutes)"))));
        } else {
            midiProperties.getPropertiesComponents(comps);
        }
    }

    /**
     * Can the waypoint play sound
     *
     * @return Can this waypoint play sound
     */
    public boolean canPlaySound() {
        return !getMidiProperties().getMuted();
    }

    /**
     * Apply properties
     *
     * @return success
     */
    protected boolean applyProperties() {
        if (!super.applyProperties()) {
            return false;
        }
        minutesSpan = Misc.parseNumber(spanFld.getText().trim());
        if (!midiProperties.applyProperties()) {
            return false;
        }
        if (!midiProperties.getMuted()) {
            getMidiManager().setInstrument(midiProperties.getInstrumentName());
            getMidiManager().play(64, 500);
        }

        return true;
    }

    /**
     * Draws the annotation.
     *
     * @param g2  the graphics device.
     * @param plot  the plot.
     * @param dataArea  the data area.
     * @param domainAxis  the domain axis.
     * @param rangeAxis  the range axis.
     * @param rendererIndex  the renderer index.
     * @param info  an optional info object that will be populated with
     *              entity information.
     */
    public void draw(Graphics2D g2, XYPlot plot, Rectangle2D dataArea, ValueAxis domainAxis, ValueAxis rangeAxis,
            int rendererIndex, PlotRenderingInfo info) {
        super.setGraphicsState(g2);
        if (!getPlotWrapper().okToDraw(this)) {
            return;
        }

        g2.setStroke(new BasicStroke());
        if (false && getSelected()) {
            g2.setColor(COLOR_SELECTED);
        } else {
            g2.setColor(getColor());
        }
        x = getXFromValue(dataArea, domainAxis);

        int width2 = (int) (ANNOTATION_WIDTH / 2);
        int bottom = (int) (dataArea.getY() + dataArea.getHeight());
        y = bottom;
        int[] xs = { x - width2, x + width2, x, x - width2 };
        int[] ys = { bottom - ANNOTATION_WIDTH, bottom - ANNOTATION_WIDTH, bottom, bottom - ANNOTATION_WIDTH };
        g2.fillPolygon(xs, ys, xs.length);

        if ((getName() != null) && !isForAnimation) {
            FontMetrics fm = g2.getFontMetrics();
            int width = fm.stringWidth(getName());
            int textLeft = x - width / 2;
            g2.drawString(getName(), textLeft, bottom - ANNOTATION_WIDTH - 2);
        }

        if (getSelected()) {
            g2.setColor(COLOR_SELECTED);
            g2.drawPolygon(xs, ys, xs.length);
        }

        if (getPropertyListeners().hasListeners(PROP_WAYPOINTVALUE) || isForAnimation) {
            g2.setColor(Color.gray);
            g2.drawLine(x, y - ANNOTATION_WIDTH, x, (int) dataArea.getY());
        }

        boolean playSound = canPlaySound();

        if (isForAnimation) {
            if (clockImage == null) {
                clockImage = GuiUtils.getImage("/auxdata/ui/icons/clock.gif");
            }
            if (playSound) {
                g2.drawImage(clockImage, x - 8, (int) dataArea.getY() + 1, null);
            } else {
                g2.drawImage(clockImage, x - 8, (int) dataArea.getY() + 1, null);
            }
        }

        if (canPlaySound()) {
            if (noteImage == null) {
                noteImage = GuiUtils.getImage("/auxdata/ui/icons/note.gif");
            }
            if (isForAnimation) {
                g2.drawImage(noteImage, x + 8, (int) dataArea.getY() + 1, null);
            } else {
                g2.drawImage(noteImage, x, (int) dataArea.getY() + 1, null);
            }
        }

        if (minutesSpan > 0.0) {
            int left = (int) domainAxis.valueToJava2D(domainValue - (minutesSpan * 60000) / 2, dataArea,
                    RectangleEdge.BOTTOM);
            int right = (int) domainAxis.valueToJava2D(domainValue + (minutesSpan * 60000) / 2, dataArea,
                    RectangleEdge.BOTTOM);
            g2.setPaint(Color.black);
            g2.setStroke(new BasicStroke(2.0f));
            g2.drawLine(left, y, right, y);
        }

    }

    /**
     * Get the x position from the domain value
     *
     * @param dataArea data area
     * @param domainAxis domain axis
     *
     * @return The x value
     */
    protected int getXFromValue(Rectangle2D dataArea, ValueAxis domainAxis) {
        return (int) domainAxis.valueToJava2D(domainValue, dataArea, RectangleEdge.BOTTOM);

    }

    /**
     *  Set the DomainValue property.
     *
     *  @param value The new value for DomainValue
     */
    public void setDomainValue(double value) {
        boolean different = (value != domainValue);
        domainValue = value;
        if (different) {
            firePropertyChange(PROP_WAYPOINTVALUE, null, new Double(value));
        }
    }

    /**
     *  Get the DomainValue property.
     *
     *  @return The DomainValue
     */
    public double getDomainValue() {
        return domainValue;
    }

    /**
     * Set the IsForAnimation property.
     *
     * @param value The new value for IsForAnimation
     */
    public void setIsForAnimation(boolean value) {
        isForAnimation = value;
    }

    /**
     * Get the IsForAnimation property.
     *
     * @return The IsForAnimation
     */
    public boolean getIsForAnimation() {
        return isForAnimation;
    }

    /**
     * Set the MinutesSpan property.
     *
     * @param value The new value for MinutesSpan
     */
    public void setMinutesSpan(double value) {
        minutesSpan = value;
    }

    /**
     * Get the MinutesSpan property.
     *
     * @return The MinutesSpan
     */
    public double getMinutesSpan() {
        return minutesSpan;
    }

    /**
     * Set the MidiProperties property.
     *
     * @param value The new value for MidiProperties
     */
    public void setMidiProperties(MidiProperties value) {
        midiProperties = value;
    }

    /**
     * Get the MidiProperties property.
     *
     * @return The MidiProperties
     */
    public MidiProperties getMidiProperties() {
        return midiProperties;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void addChangeListener(AnnotationChangeListener arg0) {
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void removeChangeListener(AnnotationChangeListener arg0) {
    }
}