/******************************************************************************* * Mission Control Technologies, Copyright (c) 2009-2012, United States Government * as represented by the Administrator of the National Aeronautics and Space * Administration. All rights reserved. * * The MCT platform is licensed under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * MCT includes source code licensed under additional open source licenses. See * the MCT Open Source Licenses file included with this distribution or the About * MCT Licenses dialog available at runtime from the MCT Help menu for additional * information. *******************************************************************************/ package plotter.xy; import java.awt.Graphics; import java.util.HashSet; import java.util.Set; import plotter.Axis; import plotter.Rotation; /** * An XY axis is an axis for an XYPlot. * @author Adam Crume */ public abstract class XYAxis extends Axis { private static final long serialVersionUID = 1L; private static final int[] EMPTY = new int[0]; /** Specifies which dimension this axis controls. */ private final XYDimension plotDimension; /** Distance in pixels of the major ticks from the min location. */ private int[] majorTicks = EMPTY; /** Distance in pixels of the minor ticks from the min location. */ private int[] minorTicks = EMPTY; /** Number of pixels this axis overlaps the other axis. */ private int startMargin; /** Number of pixels at the end that serve as margin. */ private int endMargin; /** Listeners that get notified when the tick marks change. */ private Set<TicksChangedListener> tickListeners = new HashSet<TicksChangedListener>(); /** Specifies how the labels are oriented. */ private Rotation labelRotation; /** Displays the time system axis label name. Defaults to GMT. */ private String timeSystemLabelName = Axis.DEFAULT_TIME_SYSTEM_NAME; /** * Creates an axis. * @param d dimension controlled by this axis */ public XYAxis(XYDimension d) { assert d != null; this.plotDimension = d; setOpaque(false); } @Override protected void paintComponent(Graphics g) { int width = getWidth(); int height = getHeight(); g = g.create(); if(plotDimension == XYDimension.X) { width -= startMargin + endMargin; g.translate(startMargin, 0); } else { height -= startMargin + endMargin; g.translate(0, endMargin); } g.setColor(getForeground()); int majorTickLength = getMajorTickLength(); int minorTickLength = getMinorTickLength(); if(plotDimension == XYDimension.X) { g.drawLine(0, 0, width - 1, 0); for(int x : getMajorTicks()) { g.drawLine(x, 0, x, majorTickLength); } for(int x : getMinorTicks()) { g.drawLine(x, 0, x, minorTickLength); } } else { g.drawLine(width - 1, height - 1, width - 1, 0); for(int y : getMajorTicks()) { g.drawLine(width - 1 - majorTickLength, height - 1 - y, width - 1, height - 1 - y); } for(int y : getMinorTicks()) { g.drawLine(width - 1 - minorTickLength, height - 1 - y, width - 1, height - 1 - y); } } } /** * Converts a logical coordinate to a physical one. * @param d logical coordinate * @return physical coordinate */ public abstract int toPhysical(double d); /** * Converts a physical coordinate to a logical one. * @param n physical coordinate * @return logical coordinate */ public abstract double toLogical(int n); /** * Returns the dimension this axis controls. * @return the dimension this axis controls */ public XYDimension getPlotDimension() { return plotDimension; } /** * Returns the number of pixels at the start that serve as margin. * @return margin, in pixels */ public int getStartMargin() { return startMargin; } /** * Sets the number of pixels at the start that serve as margin. * @param startMargin margin, in pixels */ public void setStartMargin(int startMargin) { this.startMargin = startMargin; } /** * Returns the number of pixels at the end that serve as margin. * @return margin, in pixels */ public int getEndMargin() { return endMargin; } /** * Sets the number of pixels at the end that serve as margin. * @param endMargin margin, in pixels */ public void setEndMargin(int endMargin) { this.endMargin = endMargin; } /** * Do not modify the returned array. * @return distance of the major tick marks from the beginning of the axis, in pixels */ public int[] getMajorTicks() { return majorTicks; } /** * Sets the major tick marks. * All {@link TicksChangedListener}s are notified. * @param majorTicks physical locations of the major tick marks */ protected void setMajorTicks(int[] majorTicks) { assert majorTicks != null; this.majorTicks = majorTicks; for(TicksChangedListener listener : tickListeners) { listener.ticksChanged(this); } } /** * Do not modify the returned array. * @return distance of the minor ticks from the beginning of the axis, in pixels */ public int[] getMinorTicks() { return minorTicks; } /** * Sets the locations of the minor ticks. * @param minorTicks physical locations of the minor tick marks */ protected void setMinorTicks(int[] minorTicks) { assert minorTicks != null; this.minorTicks = minorTicks; } /** * Adds a tick listener. * @param listener listener to add */ public void addTickListener(TicksChangedListener listener) { tickListeners.add(listener); } /** * Returns the label rotation. * @return the label rotation */ public Rotation getLabelRotation() { return labelRotation; } /** * Sets the label rotation. * @param labelRotation the label rotation */ public void setLabelRotation(Rotation labelRotation) { this.labelRotation = labelRotation; } /** * A TicksChangedListener gets notified when tick marks change. * @author Adam Crume */ public static interface TicksChangedListener { /** * Notifies this listener that an axis's tick marks changed. * @param a axis whose tick marks changed */ public void ticksChanged(XYAxis a); } /** * Returns the time system axis label name. * @return time system axis label name. */ @Override public String getTimeSystemAxisLabelName() { return timeSystemLabelName; } /** * Sets the time system axis label name. * @param labelName time system. */ @Override public void setTimeSystemAxisLabelName(String labelName) { timeSystemLabelName = labelName; } }