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 * PolarChartPanel.java
029 * --------------------
030 * (C) Copyright 2004-2021, by Solution Engineering, Inc. and Contributors.
031 *
032 * Original Author:  Daniel Bridenbecker, Solution Engineering, Inc.;
033 * Contributor(s):   David Gilbert;
034 *                   Martin Hoeller;
035 *
036 */
037
038package org.jfree.chart.swing;
039
040import java.awt.Component;
041import java.awt.event.ActionEvent;
042
043import javax.swing.JMenuItem;
044import javax.swing.JPopupMenu;
045import org.jfree.chart.JFreeChart;
046
047import org.jfree.chart.plot.Plot;
048import org.jfree.chart.plot.PolarPlot;
049
050/**
051 * {@code PolarChartPanel} is the top level object for using the
052 * {@link PolarPlot}. Since this class has a {@code JPanel} in the
053 * inheritance hierarchy, one uses this class to integrate the Polar plot into
054 * their application.
055 * <p>
056 * The main modification to {@code ChartPanel} is the popup menu.  It
057 * removes {@code ChartPanel}'s versions of:
058 * <ul>
059 *    <li>{@code Zoom In}</li>
060 *    <li>{@code Zoom Out}</li>
061 *    <li>{@code Auto Range}</li>
062 * </ul>
063 * and replaces them with versions more appropriate for {@link PolarPlot}.
064 */
065public class PolarChartPanel extends ChartPanel {
066
067    /** Zoom in command string. */
068    private static final String POLAR_ZOOM_IN_ACTION_COMMAND = "Polar Zoom In";
069
070    /** Zoom out command string. */
071    private static final String POLAR_ZOOM_OUT_ACTION_COMMAND
072        = "Polar Zoom Out";
073
074    /** Auto range command string. */
075    private static final String POLAR_AUTO_RANGE_ACTION_COMMAND
076        = "Polar Auto Range";
077
078    /**
079     * Constructs a JFreeChart panel.
080     *
081     * @param chart  the chart.
082     */
083    public PolarChartPanel(JFreeChart chart) {
084        this(chart, true);
085    }
086
087    /**
088     * Creates a new panel.
089     *
090     * @param chart  the chart.
091     * @param useBuffer  buffered?
092     */
093    public PolarChartPanel(JFreeChart chart, boolean useBuffer) {
094        super(chart, useBuffer);
095        checkChart(chart);
096        setMinimumDrawWidth(200);
097        setMinimumDrawHeight(200);
098        setMaximumDrawWidth(2000);
099        setMaximumDrawHeight(2000);
100    }
101
102    /**
103     * Sets the chart that is displayed in the panel.
104     *
105     * @param chart  The chart.
106     */
107    @Override
108    public void setChart(JFreeChart chart) {
109        checkChart(chart);
110        super.setChart(chart);
111    }
112
113    /**
114     * Creates a popup menu for the panel.
115     *
116     * @param properties  include a menu item for the chart property editor.
117     * @param copy  include a menu item for copying the chart.
118     * @param save  include a menu item for saving the chart.
119     * @param print  include a menu item for printing the chart.
120     * @param zoom  include menu items for zooming.
121     *
122     * @return The popup menu.
123     */
124    @Override
125    protected JPopupMenu createPopupMenu(boolean properties, boolean copy, 
126            boolean save, boolean print, boolean zoom) {
127
128       JPopupMenu result = super.createPopupMenu(properties, copy, save, print, zoom);
129       int zoomInIndex = getPopupMenuItem(result,
130               localizationResources.getString("Zoom_In"));
131       int zoomOutIndex = getPopupMenuItem(result,
132               localizationResources.getString("Zoom_Out"));
133       int autoIndex = getPopupMenuItem(result,
134               localizationResources.getString("Auto_Range"));
135       if (zoom) {
136           JMenuItem zoomIn = new JMenuItem(
137                   localizationResources.getString("Zoom_In"));
138           zoomIn.setActionCommand(POLAR_ZOOM_IN_ACTION_COMMAND);
139           zoomIn.addActionListener(this);
140
141           JMenuItem zoomOut = new JMenuItem(
142                   localizationResources.getString("Zoom_Out"));
143           zoomOut.setActionCommand(POLAR_ZOOM_OUT_ACTION_COMMAND);
144           zoomOut.addActionListener(this);
145
146           JMenuItem auto = new JMenuItem(
147                   localizationResources.getString("Auto_Range"));
148           auto.setActionCommand(POLAR_AUTO_RANGE_ACTION_COMMAND);
149           auto.addActionListener(this);
150
151           if (zoomInIndex != -1) {
152               result.remove(zoomInIndex);
153           }
154           else {
155               zoomInIndex = result.getComponentCount() - 1;
156           }
157           result.add(zoomIn, zoomInIndex);
158           if (zoomOutIndex != -1) {
159               result.remove(zoomOutIndex);
160           }
161           else {
162               zoomOutIndex = zoomInIndex + 1;
163           }
164           result.add(zoomOut, zoomOutIndex);
165           if (autoIndex != -1) {
166               result.remove(autoIndex);
167           }
168           else {
169               autoIndex = zoomOutIndex + 1;
170           }
171           result.add(auto, autoIndex);
172       }
173       return result;
174    }
175
176    /**
177     * Handles action events generated by the popup menu.
178     *
179     * @param event  the event.
180     */
181    @Override
182    public void actionPerformed(ActionEvent event) {
183       String command = event.getActionCommand();
184
185       if (command.equals(POLAR_ZOOM_IN_ACTION_COMMAND)) {
186           PolarPlot plot = (PolarPlot) getChart().getPlot();
187           plot.zoom(0.5);
188       }
189       else if (command.equals(POLAR_ZOOM_OUT_ACTION_COMMAND)) {
190           PolarPlot plot = (PolarPlot) getChart().getPlot();
191           plot.zoom(2.0);
192       }
193       else if (command.equals(POLAR_AUTO_RANGE_ACTION_COMMAND)) {
194           PolarPlot plot = (PolarPlot) getChart().getPlot();
195           plot.getAxis().setAutoRange(true);
196       }
197       else {
198           super.actionPerformed(event);
199       }
200    }
201
202    /**
203     * Test that the chart is using an xy plot with time as the domain axis.
204     *
205     * @param chart  the chart.
206     */
207    private void checkChart(JFreeChart chart) {
208        Plot plot = chart.getPlot();
209        if (!(plot instanceof PolarPlot)) {
210            throw new IllegalArgumentException("plot is not a PolarPlot");
211       }
212    }
213
214    /**
215     * Returns the index of an item in a popup menu.
216     *
217     * @param menu  the menu.
218     * @param text  the label.
219     *
220     * @return The item index.
221     */
222    private int getPopupMenuItem(JPopupMenu menu, String text) {
223        int index = -1;
224        for (int i = 0; (index == -1) && (i < menu.getComponentCount()); i++) {
225            Component comp = menu.getComponent(i);
226            if (comp instanceof JMenuItem) {
227                JMenuItem item = (JMenuItem) comp;
228                if (text.equals(item.getText())) {
229                    index = i;
230                }
231            }
232       }
233       return index;
234    }
235
236}