001: /* ===========================================================
002: * JFreeChart : a free chart library for the Java(tm) platform
003: * ===========================================================
004: *
005: * (C) Copyright 2000-2005, by Object Refinery Limited 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: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
025: * in the United States and other countries.]
026: *
027: * ----------------------------
028: * DefaultNumberAxisEditor.java
029: * ----------------------------
030: * (C) Copyright 2005, Object Refinery Limited and Contributors.
031: *
032: * Original Author: David Gilbert (for Object Refinery Limited);
033: * Contributor(s): Arnaud Lelievre;
034: *
035: * $Id: DefaultNumberAxisEditor.java,v 1.1.2.1 2005/11/24 16:11:48 mungady Exp $
036: *
037: * Changes:
038: * --------
039: * 24-Nov-2005 : Version 1, based on NumberAxisPropertyEditor (DG);
040: */
041:
042: package org.jfree.chart.editor;
043:
044: import java.awt.BasicStroke;
045: import java.awt.Color;
046: import java.awt.event.ActionEvent;
047: import java.awt.event.FocusEvent;
048: import java.awt.event.FocusListener;
049: import java.util.ResourceBundle;
050:
051: import javax.swing.BorderFactory;
052: import javax.swing.JCheckBox;
053: import javax.swing.JColorChooser;
054: import javax.swing.JLabel;
055: import javax.swing.JOptionPane;
056: import javax.swing.JPanel;
057: import javax.swing.JTabbedPane;
058: import javax.swing.JTextField;
059:
060: import org.jfree.chart.axis.Axis;
061: import org.jfree.chart.axis.NumberAxis;
062: import org.jfree.layout.LCBLayout;
063: import org.jfree.ui.PaintSample;
064: import org.jfree.ui.StrokeChooserPanel;
065: import org.jfree.ui.StrokeSample;
066:
067: /**
068: * A panel for editing the properties of a value axis.
069: */
070: class DefaultNumberAxisEditor extends DefaultAxisEditor implements
071: FocusListener {
072:
073: /** A flag that indicates whether or not the axis range is determined
074: * automatically.
075: */
076: private boolean autoRange;
077:
078: /** The lowest value in the axis range. */
079: private double minimumValue;
080:
081: /** The highest value in the axis range. */
082: private double maximumValue;
083:
084: /** A checkbox that indicates whether or not the axis range is determined
085: * automatically.
086: */
087: private JCheckBox autoRangeCheckBox;
088:
089: /** A text field for entering the minimum value in the axis range. */
090: private JTextField minimumRangeValue;
091:
092: /** A text field for entering the maximum value in the axis range. */
093: private JTextField maximumRangeValue;
094:
095: /** The paint selected for drawing the gridlines. */
096: private PaintSample gridPaintSample;
097:
098: /** The stroke selected for drawing the gridlines. */
099: private StrokeSample gridStrokeSample;
100:
101: /** An array of stroke samples to choose from (since I haven't written a
102: * decent StrokeChooser component yet).
103: */
104: private StrokeSample[] availableStrokeSamples;
105:
106: /** The resourceBundle for the localization. */
107: protected static ResourceBundle localizationResources = ResourceBundle
108: .getBundle("org.jfree.chart.editor.LocalizationBundle");
109:
110: /**
111: * Standard constructor: builds a property panel for the specified axis.
112: *
113: * @param axis the axis, which should be changed.
114: */
115: public DefaultNumberAxisEditor(NumberAxis axis) {
116:
117: super (axis);
118:
119: this .autoRange = axis.isAutoRange();
120: this .minimumValue = axis.getLowerBound();
121: this .maximumValue = axis.getUpperBound();
122:
123: this .gridPaintSample = new PaintSample(Color.blue);
124: this .gridStrokeSample = new StrokeSample(new BasicStroke(1.0f));
125:
126: this .availableStrokeSamples = new StrokeSample[3];
127: this .availableStrokeSamples[0] = new StrokeSample(
128: new BasicStroke(1.0f));
129: this .availableStrokeSamples[1] = new StrokeSample(
130: new BasicStroke(2.0f));
131: this .availableStrokeSamples[2] = new StrokeSample(
132: new BasicStroke(3.0f));
133:
134: JTabbedPane other = getOtherTabs();
135:
136: JPanel range = new JPanel(new LCBLayout(3));
137: range.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
138:
139: range.add(new JPanel());
140: this .autoRangeCheckBox = new JCheckBox(localizationResources
141: .getString("Auto-adjust_range"), this .autoRange);
142: this .autoRangeCheckBox.setActionCommand("AutoRangeOnOff");
143: this .autoRangeCheckBox.addActionListener(this );
144: range.add(this .autoRangeCheckBox);
145: range.add(new JPanel());
146:
147: range.add(new JLabel(localizationResources
148: .getString("Minimum_range_value")));
149: this .minimumRangeValue = new JTextField(Double
150: .toString(this .minimumValue));
151: this .minimumRangeValue.setEnabled(!this .autoRange);
152: this .minimumRangeValue.setActionCommand("MinimumRange");
153: this .minimumRangeValue.addActionListener(this );
154: this .minimumRangeValue.addFocusListener(this );
155: range.add(this .minimumRangeValue);
156: range.add(new JPanel());
157:
158: range.add(new JLabel(localizationResources
159: .getString("Maximum_range_value")));
160: this .maximumRangeValue = new JTextField(Double
161: .toString(this .maximumValue));
162: this .maximumRangeValue.setEnabled(!this .autoRange);
163: this .maximumRangeValue.setActionCommand("MaximumRange");
164: this .maximumRangeValue.addActionListener(this );
165: this .maximumRangeValue.addFocusListener(this );
166: range.add(this .maximumRangeValue);
167: range.add(new JPanel());
168:
169: other.add(localizationResources.getString("Range"), range);
170:
171: }
172:
173: /**
174: * Returns the current setting of the auto-range property.
175: *
176: * @return <code>true</code> if auto range is enabled.
177: */
178: public boolean isAutoRange() {
179: return this .autoRange;
180: }
181:
182: /**
183: * Returns the current setting of the minimum value in the axis range.
184: *
185: * @return The current setting of the minimum value in the axis range.
186: */
187: public double getMinimumValue() {
188: return this .minimumValue;
189: }
190:
191: /**
192: * Returns the current setting of the maximum value in the axis range.
193: *
194: * @return The current setting of the maximum value in the axis range.
195: */
196: public double getMaximumValue() {
197: return this .maximumValue;
198: }
199:
200: /**
201: * Handles actions from within the property panel.
202: * @param event an event.
203: */
204: public void actionPerformed(ActionEvent event) {
205: String command = event.getActionCommand();
206: if (command.equals("GridStroke")) {
207: attemptGridStrokeSelection();
208: } else if (command.equals("GridPaint")) {
209: attemptGridPaintSelection();
210: } else if (command.equals("AutoRangeOnOff")) {
211: toggleAutoRange();
212: } else if (command.equals("MinimumRange")) {
213: validateMinimum();
214: } else if (command.equals("MaximumRange")) {
215: validateMaximum();
216: } else {
217: // pass to the super-class for handling
218: super .actionPerformed(event);
219: }
220: }
221:
222: /**
223: * Handle a grid stroke selection.
224: */
225: private void attemptGridStrokeSelection() {
226: StrokeChooserPanel panel = new StrokeChooserPanel(null,
227: this .availableStrokeSamples);
228: int result = JOptionPane
229: .showConfirmDialog(this , panel, localizationResources
230: .getString("Stroke_Selection"),
231: JOptionPane.OK_CANCEL_OPTION,
232: JOptionPane.PLAIN_MESSAGE);
233:
234: if (result == JOptionPane.OK_OPTION) {
235: this .gridStrokeSample.setStroke(panel.getSelectedStroke());
236: }
237: }
238:
239: /**
240: * Handle a grid paint selection.
241: */
242: private void attemptGridPaintSelection() {
243: Color c;
244: c = JColorChooser.showDialog(this , localizationResources
245: .getString("Grid_Color"), Color.blue);
246: if (c != null) {
247: this .gridPaintSample.setPaint(c);
248: }
249: }
250:
251: /**
252: * Does nothing.
253: *
254: * @param event the event.
255: */
256: public void focusGained(FocusEvent event) {
257: // don't need to do anything
258: }
259:
260: /**
261: * Revalidates minimum/maximum range.
262: *
263: * @param event the event.
264: */
265: public void focusLost(FocusEvent event) {
266: if (event.getSource() == this .minimumRangeValue) {
267: validateMinimum();
268: } else if (event.getSource() == this .maximumRangeValue) {
269: validateMaximum();
270: }
271: }
272:
273: /**
274: * Toggle the auto range setting.
275: */
276: public void toggleAutoRange() {
277: this .autoRange = this .autoRangeCheckBox.isSelected();
278: if (this .autoRange) {
279: this .minimumRangeValue.setText(Double
280: .toString(this .minimumValue));
281: this .minimumRangeValue.setEnabled(false);
282: this .maximumRangeValue.setText(Double
283: .toString(this .maximumValue));
284: this .maximumRangeValue.setEnabled(false);
285: } else {
286: this .minimumRangeValue.setEnabled(true);
287: this .maximumRangeValue.setEnabled(true);
288: }
289: }
290:
291: /**
292: * Revalidate the range minimum.
293: */
294: public void validateMinimum() {
295: double newMin;
296: try {
297: newMin = Double.parseDouble(this .minimumRangeValue
298: .getText());
299: if (newMin >= this .maximumValue) {
300: newMin = this .minimumValue;
301: }
302: } catch (NumberFormatException e) {
303: newMin = this .minimumValue;
304: }
305:
306: this .minimumValue = newMin;
307: this .minimumRangeValue.setText(Double
308: .toString(this .minimumValue));
309: }
310:
311: /**
312: * Revalidate the range maximum.
313: */
314: public void validateMaximum() {
315: double newMax;
316: try {
317: newMax = Double.parseDouble(this .maximumRangeValue
318: .getText());
319: if (newMax <= this .minimumValue) {
320: newMax = this .maximumValue;
321: }
322: } catch (NumberFormatException e) {
323: newMax = this .maximumValue;
324: }
325:
326: this .maximumValue = newMax;
327: this .maximumRangeValue.setText(Double
328: .toString(this .maximumValue));
329: }
330:
331: /**
332: * Sets the properties of the specified axis to match the properties
333: * defined on this panel.
334: *
335: * @param axis the axis.
336: */
337: public void setAxisProperties(Axis axis) {
338: super .setAxisProperties(axis);
339: NumberAxis numberAxis = (NumberAxis) axis;
340: numberAxis.setAutoRange(this.autoRange);
341: if (!this.autoRange) {
342: numberAxis.setRange(this.minimumValue, this.maximumValue);
343: }
344: }
345:
346: }
|