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 * DefaultPolarPlotEditor.java
029 * ----------------------
030 * (C) Copyright 2005-2022, by David Gilbert and Contributors.
031 *
032 * Original Author:  Martin Hoeller;
033 * Contributor(s):   -;
034 *
035 */
036
037
038package org.jfree.chart.swing.editor;
039
040import java.awt.event.ActionEvent;
041import java.awt.event.FocusEvent;
042import java.awt.event.FocusListener;
043
044import javax.swing.BorderFactory;
045import javax.swing.JLabel;
046import javax.swing.JPanel;
047import javax.swing.JTabbedPane;
048import javax.swing.JTextField;
049
050import org.jfree.chart.axis.NumberTickUnit;
051import org.jfree.chart.plot.Plot;
052import org.jfree.chart.plot.PolarPlot;
053
054/**
055 * A panel for editing the properties of a {@link PolarPlot}.
056 */
057public class DefaultPolarPlotEditor extends DefaultPlotEditor
058    implements FocusListener {
059
060    /** A text field to enter a manual TickUnit. */
061    private JTextField manualTickUnit;
062
063    /** A text field to enter the angleOffset. */
064    private JTextField angleOffset;
065
066    /** The size for the manual TickUnit. */
067    private double manualTickUnitValue;
068
069    /** The value for the plot's angle offset. */
070    private double angleOffsetValue;
071
072    
073    /**
074     * Standard constructor - constructs a panel for editing the properties of
075     * the specified plot.
076     *
077     * @param plot  the plot, which should be changed.
078     */
079    public DefaultPolarPlotEditor(PolarPlot plot) {
080        super(plot);
081        this.angleOffsetValue = plot.getAngleOffset();
082        this.angleOffset.setText(Double.toString(this.angleOffsetValue));
083        this.manualTickUnitValue = plot.getAngleTickUnit().getSize();
084        this.manualTickUnit.setText(Double.toString(this.manualTickUnitValue));
085    }
086
087    /**
088     * Creates a tabbed pane for editing the plot attributes.
089     * 
090     * @param plot  the plot.
091     * 
092     * @return A tabbed pane. 
093     */
094    @Override
095    protected JTabbedPane createPlotTabs(Plot plot) {
096        JTabbedPane tabs = super.createPlotTabs(plot);
097        // TODO find a better localization key
098        tabs.insertTab(localizationResources.getString("General1"), null, 
099                createPlotPanel(), null, 0);
100        tabs.setSelectedIndex(0);
101        return tabs;
102    }
103
104    private JPanel createPlotPanel() {
105        JPanel plotPanel = new JPanel(new LCBLayout(3));
106        plotPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
107
108        plotPanel.add(new JLabel(localizationResources.getString(
109                "AngleOffset")));
110        this.angleOffset = new JTextField(Double.toString(
111                this.angleOffsetValue));
112        this.angleOffset.setActionCommand("AngleOffsetValue");
113        this.angleOffset.addActionListener(this);
114        this.angleOffset.addFocusListener(this);
115        plotPanel.add(this.angleOffset);
116        plotPanel.add(new JPanel());
117
118        plotPanel.add(new JLabel(localizationResources.getString(
119                "Manual_TickUnit_value")));
120        this.manualTickUnit = new JTextField(Double.toString(
121                this.manualTickUnitValue));
122        this.manualTickUnit.setActionCommand("TickUnitValue");
123        this.manualTickUnit.addActionListener(this);
124        this.manualTickUnit.addFocusListener(this);
125        plotPanel.add(this.manualTickUnit);
126        plotPanel.add(new JPanel());
127
128        return plotPanel;
129    }
130
131    /**
132     * Does nothing.
133     *
134     * @param event  the event.
135     */
136    @Override
137    public void focusGained(FocusEvent event) {
138        // don't need to do anything
139    }
140
141    /**
142     *  Revalidates minimum/maximum range.
143     *
144     *  @param event  the event.
145     */
146    @Override
147    public void focusLost(FocusEvent event) {
148        if (event.getSource() == this.angleOffset) {
149            validateAngleOffset();
150        }
151        else if (event.getSource() == this.manualTickUnit) {
152            validateTickUnit();
153        }
154    }
155
156    /**
157     * Handles actions from within the property panel.
158     * @param event an event.
159     */
160    @Override
161    public void actionPerformed(ActionEvent event) {
162        String command = event.getActionCommand();
163        if (command.equals("AngleOffsetValue")) {
164            validateAngleOffset();
165        }
166        else if (command.equals("TickUnitValue")) {
167            validateTickUnit();
168        }
169    }
170
171    /**
172     * Validates the angle offset entered by the user.
173     */
174    public void validateAngleOffset() {
175        double newOffset;
176        try {
177            newOffset = Double.parseDouble(this.angleOffset.getText());
178        }
179        catch (NumberFormatException e) {
180            newOffset = this.angleOffsetValue;
181        }
182        this.angleOffsetValue = newOffset;
183        this.angleOffset.setText(Double.toString(this.angleOffsetValue));
184    }
185
186    /**
187     * Validates the tick unit entered by the user.
188     */
189    public void validateTickUnit() {
190        double newTickUnit;
191        try {
192            newTickUnit = Double.parseDouble(this.manualTickUnit.getText());
193        }
194        catch (NumberFormatException e) {
195            newTickUnit = this.manualTickUnitValue;
196        }
197
198        if (newTickUnit > 0.0 && newTickUnit < 360.0) {
199            this.manualTickUnitValue = newTickUnit;
200        }
201        this.manualTickUnit.setText(Double.toString(this.manualTickUnitValue));
202    }
203
204    @Override
205    public void updatePlotProperties(Plot plot) {
206        super.updatePlotProperties(plot);
207        PolarPlot pp = (PolarPlot) plot;
208        pp.setAngleTickUnit(new NumberTickUnit(this.manualTickUnitValue));
209        pp.setAngleOffset(this.angleOffsetValue);
210    }
211}