Java tutorial
/* * Created on Jun 11, 2008 * * This code is the proprietary confidential property of TradeDesk * Software Inc and may not be redistributed or used for any other * purpose without the express consent of TradeDesk Software Inc. * * Copyright 2005-2007 TradeDesk Software Inc. All Rights Reserved */ package com.tradedesksoftware.ets.client.charting; /** * @author tharter * * * $Id$ */ /* * Copyright 2006 CPqD - Centro de Pesquisa e Desenvolvimento em Telecomunicaes. * * File ChartPanelShiftController.java created on 26/01/2006 10:49:42 * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. * * [Java is a trademark or registered trademark of Sun Microsystems, Inc. * in the United States and other countries.] * * ------------------------ * ChartPanelShiftController.java * ------------------------ * Original Author: Gustavo H. Sberze Ribas; * Contributor(s): Ben Ogle; * * Changes * -------------------------- * 26-Jan-2006 : First Version (GR); * 16-Mar-2007 : added mouse panning (BO); */ import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Cursor; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Display; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.plot.ContourPlot; import org.jfree.chart.plot.FastScatterPlot; import org.jfree.chart.plot.Plot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; /** * This class provides ways to shift (aka pan/scroll) a plot. The shift is done * through the arrow keys and its step can be configured to be a fixed amount, * a percentual of the current axis or a range in pixels. * <p> * This class only supports plots of type {@link org.jfree.chart.plot.XYPlot XYPlot}, * {@link org.jfree.chart.plot.ContourPlot ContourPlot} and * {@link org.jfree.chart.plot.FastScatterPlot FastScatterPlot}. * <p> * Use ← and → to shift the plot left and right; <br> * Use ↑ and ↓ to shift the plot up and down; <br> * Press the SHIFT key to increase the shift by a factor of 10. * * @author Gustavo H. Sberze Ribas (CPqD) * @version 0.1 */ public class ChartShiftController implements KeyListener, MouseMotionListener, MouseListener { /** PAN plot by a fixed percentual of the range (eg. 1%) */ public static final int SHIFT_PERCENTUAL = 1; /** PAN plot by a fixed number of pixels (eg. 1px) */ public static final int SHIFT_PIXEL = 2; /** PAN plot by a fixed amout (eg. 5 range units) */ public static final int SHIFT_FIXED = 3; /** The chart panel we're using */ protected TooltipChartComposite chartPanel; /** Does this plot supports shifting? Pie charts for example don't. */ protected boolean plotSupported = false; /** The shift type. (default {@link #SHIFT_PIXEL} ) */ protected int shiftType = SHIFT_PIXEL; /** Fixed shift amount for domain axis */ protected double fixedDomainShiftUnits; /** Fixed shift amount for range axis */ protected double fixedRangeShiftUnits; protected int oldx = -1; protected int oldy = -1; protected static final Cursor MOVE = new Cursor(Display.getCurrent(), SWT.CURSOR_HAND); protected static final Cursor ARROW = new Cursor(Display.getCurrent(), SWT.CURSOR_SIZEWE); /** By default we assume that the range axis is the vertical one (ie, * PlotOrientation.VERTICAL (axesSwaped=false). If the range axis is the * horizontal one (ie, PlotOrientation.HORIZONTAL) this variable should * be set to true. */ protected boolean axesSwaped = false; /** * Creates a new controller to handle plot shifts. * @param chartPanel The panel displaying the plot. */ public ChartShiftController(TooltipChartComposite chartPanel) { super(); this.chartPanel = chartPanel; // Check to see if plot is shiftable Plot plot = chartPanel.getChart().getPlot(); if ((plot instanceof XYPlot) || (plot instanceof FastScatterPlot) || (plot instanceof ContourPlot)) { plotSupported = true; axesSwaped = isHorizontalPlot(plot); } } /** * Returns the plot orientation. * @return True = {@link org.jfree.chart.plot.PlotOrientation#VERTICAL VERTICAL}; * False = {@link org.jfree.chart.plot.PlotOrientation#HORIZONTAL HORIZONTAL} */ protected boolean isHorizontalPlot(Plot plot) { if (plot instanceof XYPlot) { return ((XYPlot) plot).getOrientation() == PlotOrientation.HORIZONTAL; } if (plot instanceof FastScatterPlot) { return ((FastScatterPlot) plot).getOrientation() == PlotOrientation.HORIZONTAL; } return false; } /** * Returns the ValueAxis for the plot or <code>null</code> if the plot * doesn't have one. * @param chart The chart * @param domain True = get Domain axis. False = get Range axis. * @return The selected ValueAxis or <code>null</code> if the plot doesn't * have one. */ protected ValueAxis getPlotAxis(JFreeChart chart, boolean domain) { // Where's the Shiftable interface when we need it ?? ;) Plot plot = chart.getPlot(); if (plot instanceof XYPlot) { return domain ? ((XYPlot) plot).getDomainAxis() : ((XYPlot) plot).getRangeAxis(); } if (plot instanceof FastScatterPlot) { return domain ? ((FastScatterPlot) plot).getDomainAxis() : ((FastScatterPlot) plot).getRangeAxis(); } if (plot instanceof ContourPlot) { return domain ? ((ContourPlot) plot).getDomainAxis() : ((ContourPlot) plot).getRangeAxis(); } return null; } /** * Pan/Shifts a plot if the arrow keys are pressed. * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent) */ public void keyPressed(KeyEvent e) { if (!plotSupported) return; int keyCode = e.getKeyCode(); // we're only interested in arrows (code 37,38,39,40) if ((keyCode < 37) || (keyCode > 40)) return; // The axis we're gonna shift ValueAxis axis = null; // Delta is the amount we'll shift in axis units. double delta; boolean domainShift = false; // used for PAN_FIXED // Calculations for the domain axis if ((keyCode == KeyEvent.VK_LEFT) || (keyCode == KeyEvent.VK_RIGHT)) { axis = getPlotAxis(chartPanel.getChart(), !axesSwaped); domainShift = true; } // Calculations for the range axis else { axis = getPlotAxis(chartPanel.getChart(), axesSwaped); } // Let's calculate 'delta', the amount by which we'll shift the plot switch (shiftType) { case SHIFT_PERCENTUAL: delta = (axis.getUpperBound() - axis.getLowerBound()) / 100.0; break; case SHIFT_FIXED: delta = (domainShift ? fixedDomainShiftUnits : fixedRangeShiftUnits); break; case SHIFT_PIXEL: // also the default default: // Let's find out what's the range for 1 pixel. final Rectangle scaledDataArea = chartPanel.getScreenDataArea(); delta = axis.getRange().getLength() / (scaledDataArea.width); break; } // Shift modifier multiplies delta by 10 if (e.isShiftDown()) { delta *= 10; } switch (keyCode) { case KeyEvent.VK_LEFT: case KeyEvent.VK_DOWN: axis.setRange(axis.getLowerBound() - delta, axis.getUpperBound() - delta); break; case KeyEvent.VK_UP: case KeyEvent.VK_RIGHT: axis.setRange(axis.getLowerBound() + delta, axis.getUpperBound() + delta); break; } } /* * @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent) */ public void keyTyped(KeyEvent e) { } /* * @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent) */ public void keyReleased(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_CONTROL) chartPanel.setCursor(ARROW); } public void mouseDragged(MouseEvent mouseEvent) { if (!mouseEvent.isControlDown()) return; if (oldx > -1 && oldy > -1) { ValueAxis domAxis = getPlotAxis(chartPanel.getChart(), !axesSwaped); ValueAxis rngAxis = getPlotAxis(chartPanel.getChart(), axesSwaped); int xdif = mouseEvent.getX() - oldx; int ydif = mouseEvent.getY() - oldy; final Rectangle scaledDataArea = chartPanel.getScreenDataArea(); double xdelta = (double) xdif * domAxis.getRange().getLength() / (scaledDataArea.width); double ydelta = (double) ydif * rngAxis.getRange().getLength() / (scaledDataArea.height); domAxis.setRange(domAxis.getLowerBound() - xdelta, domAxis.getUpperBound() - xdelta); rngAxis.setRange(rngAxis.getLowerBound() + ydelta, rngAxis.getUpperBound() + ydelta); } oldx = mouseEvent.getX(); oldy = mouseEvent.getY(); } public void mouseMoved(MouseEvent mouseEvent) { if (mouseEvent.isControlDown()) { final Rectangle scaledDataArea = chartPanel.getScreenDataArea(); if (mouseEvent.getX() > (int) scaledDataArea.x && mouseEvent.getY() > (int) scaledDataArea.y && mouseEvent.getX() < (int) scaledDataArea.x + scaledDataArea.width && mouseEvent.getY() < (int) scaledDataArea.y + scaledDataArea.height) chartPanel.setCursor(MOVE); else chartPanel.setCursor(ARROW); } } public void mouseReleased(MouseEvent mouseEvent) { oldx = -1; oldy = -1; } public void mouseClicked(MouseEvent mouseEvent) { } public void mousePressed(MouseEvent mouseEvent) { } public void mouseEntered(MouseEvent mouseEvent) { } public void mouseExited(MouseEvent mouseEvent) { } /** * Returns the fixed shift step for the domain axis. * @return the fixed shift step for the domain axis. */ public double getFixedDomainShiftUnits() { return fixedDomainShiftUnits; } /** * Sets the fixed shift step for the domain axis. * @param fixedDomainShiftUnits the fixed shift step for the domain axis. */ public void setFixedDomainShiftUnits(double fixedDomainShiftUnits) { this.fixedDomainShiftUnits = fixedDomainShiftUnits; } /** * Returns the fixed shift step for the range axis. * @return the fixed shift step for the range axis. */ public double getFixedRangeShiftUnits() { return fixedRangeShiftUnits; } /** * Sets the fixed shift step for the range axis. * @param fixedRangeShiftUnits the fixed shift step for the range axis. */ public void setFixedRangeShiftUnits(double fixedRangeShiftUnits) { this.fixedRangeShiftUnits = fixedRangeShiftUnits; } /** * Returns the current shift type. * @return the current shift type. * @see #SHIFT_FIXED * @see #SHIFT_PERCENTUAL * @see #SHIFT_PIXEL */ public int getShiftType() { return shiftType; } /** * Sets the shift type. * @param the new shift type. * @see #SHIFT_FIXED * @see #SHIFT_PERCENTUAL * @see #SHIFT_PIXEL */ public void setShiftType(int shiftType) { this.shiftType = shiftType; } /** * Returns whether or not the plot supports shifting. * @return True if plot can be shifted. */ public boolean isPlotSupported() { return plotSupported; } }