001/* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2022, by David Gilbert and Contributors. 006 * 007 * Project Info: http://www.jfree.org/jfreechart/index.html 008 * 009 * This library is free software; you can redistribute it and/or modify it 010 * under the terms of the GNU Lesser General Public License as published by 011 * the Free Software Foundation; either version 2.1 of the License, or 012 * (at your option) any later version. 013 * 014 * This library is distributed in the hope that it will be useful, but 015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 017 * License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this library; if not, write to the Free Software 021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 022 * USA. 023 * 024 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 025 * Other names may be trademarks of their respective owners.] 026 * 027 * ---------------------- 028 * MouseWheelHandler.java 029 * ---------------------- 030 * (C) Copyright 2009-2022 by David Gilbert and Contributors. 031 * 032 * Original Author: David Gilbert; 033 * Contributor(s): Ulrich Voigt - patch 2686040; 034 * Jim Goodwin - bug fix; 035 * 036 */ 037 038package org.jfree.chart.swing; 039 040import java.awt.event.MouseWheelEvent; 041import java.awt.event.MouseWheelListener; 042import java.awt.geom.Point2D; 043import java.io.Serializable; 044import org.jfree.chart.ChartRenderingInfo; 045import org.jfree.chart.JFreeChart; 046 047import org.jfree.chart.plot.pie.PiePlot; 048import org.jfree.chart.plot.Plot; 049import org.jfree.chart.plot.PlotRenderingInfo; 050import org.jfree.chart.plot.Zoomable; 051 052/** 053 * A class that handles mouse wheel events for the {@link ChartPanel} class. 054 */ 055public class MouseWheelHandler implements MouseWheelListener, Serializable { 056 057 /** The chart panel. */ 058 private final ChartPanel chartPanel; 059 060 /** The zoom factor. */ 061 double zoomFactor; 062 063 /** 064 * Creates a new instance for the specified chart panel. 065 * 066 * @param chartPanel the chart panel ({@code null} not permitted). 067 */ 068 public MouseWheelHandler(ChartPanel chartPanel) { 069 this.chartPanel = chartPanel; 070 this.zoomFactor = 0.10; 071 this.chartPanel.addMouseWheelListener(this); 072 } 073 074 /** 075 * Returns the current zoom factor. The default value is 0.10 (ten 076 * percent). 077 * 078 * @return The zoom factor. 079 * 080 * @see #setZoomFactor(double) 081 */ 082 public double getZoomFactor() { 083 return this.zoomFactor; 084 } 085 086 /** 087 * Sets the zoom factor. 088 * 089 * @param zoomFactor the zoom factor. 090 * 091 * @see #getZoomFactor() 092 */ 093 public void setZoomFactor(double zoomFactor) { 094 this.zoomFactor = zoomFactor; 095 } 096 097 /** 098 * Handles a mouse wheel event from the underlying chart panel. 099 * 100 * @param e the event. 101 */ 102 @Override 103 public void mouseWheelMoved(MouseWheelEvent e) { 104 JFreeChart chart = this.chartPanel.getChart(); 105 if (chart == null) { 106 return; 107 } 108 Plot plot = chart.getPlot(); 109 if (plot instanceof Zoomable) { 110 Zoomable zoomable = (Zoomable) plot; 111 handleZoomable(zoomable, e); 112 } 113 else if (plot instanceof PiePlot) { 114 PiePlot pp = (PiePlot) plot; 115 pp.handleMouseWheelRotation(e.getWheelRotation()); 116 } 117 } 118 119 /** 120 * Handle the case where a plot implements the {@link Zoomable} interface. 121 * 122 * @param zoomable the zoomable plot. 123 * @param e the mouse wheel event. 124 */ 125 private void handleZoomable(Zoomable zoomable, MouseWheelEvent e) { 126 // don't zoom unless the mouse pointer is in the plot's data area 127 ChartRenderingInfo info = this.chartPanel.getChartRenderingInfo(); 128 PlotRenderingInfo pinfo = info.getPlotInfo(); 129 Point2D p = this.chartPanel.translateScreenToJava2D(e.getPoint()); 130 if (!pinfo.getDataArea().contains(p)) { 131 return; 132 } 133 134 Plot plot = (Plot) zoomable; 135 // do not notify while zooming each axis 136 boolean notifyState = plot.isNotify(); 137 plot.setNotify(false); 138 int clicks = e.getWheelRotation(); 139 double zf = 1.0 + this.zoomFactor; 140 if (clicks < 0) { 141 zf = 1.0 / zf; 142 } 143 if (chartPanel.isDomainZoomable()) { 144 zoomable.zoomDomainAxes(zf, pinfo, p, true); 145 } 146 if (chartPanel.isRangeZoomable()) { 147 zoomable.zoomRangeAxes(zf, pinfo, p, true); 148 } 149 plot.setNotify(notifyState); // this generates the change event too 150 } 151 152}