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: * DefaultPlotEditor.java
029: * ----------------------
030: * (C) Copyright 2005, by Object Refinery Limited and Contributors.
031: *
032: * Original Author: David Gilbert (for Object Refinery Limited);
033: * Contributor(s): Andrzej Porebski;
034: * Arnaud Lelievre;
035: * Daniel Gredler;
036: *
037: * $Id: DefaultPlotEditor.java,v 1.1.2.1 2005/11/24 16:11:48 mungady Exp $
038: *
039: * Changes:
040: * --------
041: * 24-Nov-2005 : Version 1, based on PlotPropertyEditPanel.java (DG);
042: *
043: */
044:
045: package org.jfree.chart.editor;
046:
047: import java.awt.BasicStroke;
048: import java.awt.BorderLayout;
049: import java.awt.Color;
050: import java.awt.Paint;
051: import java.awt.Stroke;
052: import java.awt.event.ActionEvent;
053: import java.awt.event.ActionListener;
054: import java.util.ResourceBundle;
055:
056: import javax.swing.BorderFactory;
057: import javax.swing.JButton;
058: import javax.swing.JCheckBox;
059: import javax.swing.JColorChooser;
060: import javax.swing.JComboBox;
061: import javax.swing.JLabel;
062: import javax.swing.JOptionPane;
063: import javax.swing.JPanel;
064: import javax.swing.JTabbedPane;
065:
066: import org.jfree.chart.axis.Axis;
067: import org.jfree.chart.axis.ColorBar;
068: import org.jfree.chart.plot.CategoryPlot;
069: import org.jfree.chart.plot.ContourPlot;
070: import org.jfree.chart.plot.Plot;
071: import org.jfree.chart.plot.PlotOrientation;
072: import org.jfree.chart.plot.XYPlot;
073: import org.jfree.chart.renderer.category.CategoryItemRenderer;
074: import org.jfree.chart.renderer.category.LineAndShapeRenderer;
075: import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
076: import org.jfree.chart.renderer.xy.XYItemRenderer;
077: import org.jfree.layout.LCBLayout;
078: import org.jfree.ui.PaintSample;
079: import org.jfree.ui.RectangleInsets;
080: import org.jfree.ui.StrokeChooserPanel;
081: import org.jfree.ui.StrokeSample;
082: import org.jfree.util.BooleanUtilities;
083:
084: /**
085: * A panel for editing the properties of a {@link Plot}.
086: */
087: class DefaultPlotEditor extends JPanel implements ActionListener {
088:
089: /** Orientation constants. */
090: private final static String[] orientationNames = { "Vertical",
091: "Horizontal" };
092: private final static int ORIENTATION_VERTICAL = 0;
093: private final static int ORIENTATION_HORIZONTAL = 1;
094:
095: /** The paint (color) used to fill the background of the plot. */
096: private PaintSample backgroundPaintSample;
097:
098: /** The stroke (pen) used to draw the outline of the plot. */
099: private StrokeSample outlineStrokeSample;
100:
101: /** The paint (color) used to draw the outline of the plot. */
102: private PaintSample outlinePaintSample;
103:
104: /**
105: * A panel used to display/edit the properties of the domain axis (if any).
106: */
107: private DefaultAxisEditor domainAxisPropertyPanel;
108:
109: /**
110: * A panel used to display/edit the properties of the range axis (if any).
111: */
112: private DefaultAxisEditor rangeAxisPropertyPanel;
113:
114: /**
115: * A panel used to display/edit the properties of the colorbar axis (if
116: * any).
117: */
118: private DefaultColorBarEditor colorBarAxisPropertyPanel;
119:
120: /** An array of stroke samples to choose from. */
121: private StrokeSample[] availableStrokeSamples;
122:
123: /** The insets for the plot. */
124: private RectangleInsets plotInsets;
125:
126: /**
127: * The orientation for the plot (for <tt>CategoryPlot</tt>s and
128: * <tt>XYPlot</tt>s).
129: */
130: private PlotOrientation plotOrientation;
131:
132: /**
133: * The orientation combo box (for <tt>CategoryPlot</tt>s and
134: * <tt>XYPlot</tt>s).
135: */
136: private JComboBox orientationCombo;
137:
138: /** Whether or not to draw lines between each data point (for
139: * <tt>LineAndShapeRenderer</tt>s and <tt>StandardXYItemRenderer</tt>s).
140: */
141: private Boolean drawLines;
142:
143: /**
144: * The checkbox for whether or not to draw lines between each data point.
145: */
146: private JCheckBox drawLinesCheckBox;
147:
148: /** Whether or not to draw shapes at each data point (for
149: * <tt>LineAndShapeRenderer</tt>s and <tt>StandardXYItemRenderer</tt>s).
150: */
151: private Boolean drawShapes;
152:
153: /**
154: * The checkbox for whether or not to draw shapes at each data point.
155: */
156: private JCheckBox drawShapesCheckBox;
157:
158: /** The resourceBundle for the localization. */
159: protected static ResourceBundle localizationResources = ResourceBundle
160: .getBundle("org.jfree.chart.editor.LocalizationBundle");
161:
162: /**
163: * Standard constructor - constructs a panel for editing the properties of
164: * the specified plot.
165: * <P>
166: * In designing the panel, we need to be aware that subclasses of Plot will
167: * need to implement subclasses of PlotPropertyEditPanel - so we need to
168: * leave one or two 'slots' where the subclasses can extend the user
169: * interface.
170: *
171: * @param plot the plot, which should be changed.
172: */
173: public DefaultPlotEditor(Plot plot) {
174:
175: this .plotInsets = plot.getInsets();
176: this .backgroundPaintSample = new PaintSample(plot
177: .getBackgroundPaint());
178: this .outlineStrokeSample = new StrokeSample(plot
179: .getOutlineStroke());
180: this .outlinePaintSample = new PaintSample(plot
181: .getOutlinePaint());
182: if (plot instanceof CategoryPlot) {
183: this .plotOrientation = ((CategoryPlot) plot)
184: .getOrientation();
185: } else if (plot instanceof XYPlot) {
186: this .plotOrientation = ((XYPlot) plot).getOrientation();
187: }
188: if (plot instanceof CategoryPlot) {
189: CategoryItemRenderer renderer = ((CategoryPlot) plot)
190: .getRenderer();
191: if (renderer instanceof LineAndShapeRenderer) {
192: LineAndShapeRenderer r = (LineAndShapeRenderer) renderer;
193: this .drawLines = BooleanUtilities.valueOf(r
194: .getBaseLinesVisible());
195: this .drawShapes = BooleanUtilities.valueOf(r
196: .getBaseShapesVisible());
197: }
198: } else if (plot instanceof XYPlot) {
199: XYItemRenderer renderer = ((XYPlot) plot).getRenderer();
200: if (renderer instanceof StandardXYItemRenderer) {
201: StandardXYItemRenderer r = (StandardXYItemRenderer) renderer;
202: this .drawLines = BooleanUtilities.valueOf(r
203: .getPlotLines());
204: this .drawShapes = BooleanUtilities.valueOf(r
205: .getBaseShapesVisible());
206: }
207: }
208:
209: setLayout(new BorderLayout());
210:
211: this .availableStrokeSamples = new StrokeSample[3];
212: this .availableStrokeSamples[0] = new StrokeSample(
213: new BasicStroke(1.0f));
214: this .availableStrokeSamples[1] = new StrokeSample(
215: new BasicStroke(2.0f));
216: this .availableStrokeSamples[2] = new StrokeSample(
217: new BasicStroke(3.0f));
218:
219: // create a panel for the settings...
220: JPanel panel = new JPanel(new BorderLayout());
221: panel.setBorder(BorderFactory.createTitledBorder(BorderFactory
222: .createEtchedBorder(), plot.getPlotType()
223: + localizationResources.getString(":")));
224:
225: JPanel general = new JPanel(new BorderLayout());
226: general.setBorder(BorderFactory
227: .createTitledBorder(localizationResources
228: .getString("General")));
229:
230: JPanel interior = new JPanel(new LCBLayout(7));
231: interior.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
232:
233: // interior.add(new JLabel(localizationResources.getString("Insets")));
234: // JButton button = new JButton(
235: // localizationResources.getString("Edit...")
236: // );
237: // button.setActionCommand("Insets");
238: // button.addActionListener(this);
239: //
240: // this.insetsTextField = new InsetsTextField(this.plotInsets);
241: // this.insetsTextField.setEnabled(false);
242: // interior.add(this.insetsTextField);
243: // interior.add(button);
244:
245: interior.add(new JLabel(localizationResources
246: .getString("Outline_stroke")));
247: JButton button = new JButton(localizationResources
248: .getString("Select..."));
249: button.setActionCommand("OutlineStroke");
250: button.addActionListener(this );
251: interior.add(this .outlineStrokeSample);
252: interior.add(button);
253:
254: interior.add(new JLabel(localizationResources
255: .getString("Outline_Paint")));
256: button = new JButton(localizationResources
257: .getString("Select..."));
258: button.setActionCommand("OutlinePaint");
259: button.addActionListener(this );
260: interior.add(this .outlinePaintSample);
261: interior.add(button);
262:
263: interior.add(new JLabel(localizationResources
264: .getString("Background_paint")));
265: button = new JButton(localizationResources
266: .getString("Select..."));
267: button.setActionCommand("BackgroundPaint");
268: button.addActionListener(this );
269: interior.add(this .backgroundPaintSample);
270: interior.add(button);
271:
272: if (this .plotOrientation != null) {
273: boolean isVertical = this .plotOrientation
274: .equals(PlotOrientation.VERTICAL);
275: int index = isVertical ? ORIENTATION_VERTICAL
276: : ORIENTATION_HORIZONTAL;
277: interior.add(new JLabel(localizationResources
278: .getString("Orientation")));
279: this .orientationCombo = new JComboBox(orientationNames);
280: this .orientationCombo.setSelectedIndex(index);
281: this .orientationCombo.setActionCommand("Orientation");
282: this .orientationCombo.addActionListener(this );
283: interior.add(new JPanel());
284: interior.add(this .orientationCombo);
285: }
286:
287: if (this .drawLines != null) {
288: interior.add(new JLabel(localizationResources
289: .getString("Draw_lines")));
290: this .drawLinesCheckBox = new JCheckBox();
291: this .drawLinesCheckBox.setSelected(this .drawLines
292: .booleanValue());
293: this .drawLinesCheckBox.setActionCommand("DrawLines");
294: this .drawLinesCheckBox.addActionListener(this );
295: interior.add(new JPanel());
296: interior.add(this .drawLinesCheckBox);
297: }
298:
299: if (this .drawShapes != null) {
300: interior.add(new JLabel(localizationResources
301: .getString("Draw_shapes")));
302: this .drawShapesCheckBox = new JCheckBox();
303: this .drawShapesCheckBox.setSelected(this .drawShapes
304: .booleanValue());
305: this .drawShapesCheckBox.setActionCommand("DrawShapes");
306: this .drawShapesCheckBox.addActionListener(this );
307: interior.add(new JPanel());
308: interior.add(this .drawShapesCheckBox);
309: }
310:
311: general.add(interior, BorderLayout.NORTH);
312:
313: JPanel appearance = new JPanel(new BorderLayout());
314: appearance.setBorder(BorderFactory
315: .createEmptyBorder(2, 2, 2, 2));
316: appearance.add(general, BorderLayout.NORTH);
317:
318: JTabbedPane tabs = new JTabbedPane();
319: tabs.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
320:
321: Axis domainAxis = null;
322: if (plot instanceof CategoryPlot) {
323: domainAxis = ((CategoryPlot) plot).getDomainAxis();
324: } else if (plot instanceof XYPlot) {
325: domainAxis = ((XYPlot) plot).getDomainAxis();
326: }
327: this .domainAxisPropertyPanel = DefaultAxisEditor
328: .getInstance(domainAxis);
329: if (this .domainAxisPropertyPanel != null) {
330: this .domainAxisPropertyPanel.setBorder(BorderFactory
331: .createEmptyBorder(2, 2, 2, 2));
332: tabs.add(localizationResources.getString("Domain_Axis"),
333: this .domainAxisPropertyPanel);
334: }
335:
336: Axis rangeAxis = null;
337: if (plot instanceof CategoryPlot) {
338: rangeAxis = ((CategoryPlot) plot).getRangeAxis();
339: } else if (plot instanceof XYPlot) {
340: rangeAxis = ((XYPlot) plot).getRangeAxis();
341: }
342:
343: this .rangeAxisPropertyPanel = DefaultAxisEditor
344: .getInstance(rangeAxis);
345: if (this .rangeAxisPropertyPanel != null) {
346: this .rangeAxisPropertyPanel.setBorder(BorderFactory
347: .createEmptyBorder(2, 2, 2, 2));
348: tabs.add(localizationResources.getString("Range_Axis"),
349: this .rangeAxisPropertyPanel);
350: }
351:
352: //dmo: added this panel for colorbar control. (start dmo additions)
353: ColorBar colorBar = null;
354: if (plot instanceof ContourPlot) {
355: colorBar = ((ContourPlot) plot).getColorBar();
356: }
357:
358: this .colorBarAxisPropertyPanel = DefaultColorBarEditor
359: .getInstance(colorBar);
360: if (this .colorBarAxisPropertyPanel != null) {
361: this .colorBarAxisPropertyPanel.setBorder(BorderFactory
362: .createEmptyBorder(2, 2, 2, 2));
363: tabs.add(localizationResources.getString("Color_Bar"),
364: this .colorBarAxisPropertyPanel);
365: }
366: //dmo: (end dmo additions)
367:
368: tabs.add(localizationResources.getString("Appearance"),
369: appearance);
370: panel.add(tabs);
371:
372: add(panel);
373: }
374:
375: /**
376: * Returns the current plot insets.
377: *
378: * @return The current plot insets.
379: */
380: public RectangleInsets getPlotInsets() {
381: if (this .plotInsets == null) {
382: this .plotInsets = new RectangleInsets(0.0, 0.0, 0.0, 0.0);
383: }
384: return this .plotInsets;
385: }
386:
387: /**
388: * Returns the current background paint.
389: *
390: * @return The current background paint.
391: */
392: public Paint getBackgroundPaint() {
393: return this .backgroundPaintSample.getPaint();
394: }
395:
396: /**
397: * Returns the current outline stroke.
398: *
399: * @return The current outline stroke.
400: */
401: public Stroke getOutlineStroke() {
402: return this .outlineStrokeSample.getStroke();
403: }
404:
405: /**
406: * Returns the current outline paint.
407: *
408: * @return The current outline paint.
409: */
410: public Paint getOutlinePaint() {
411: return this .outlinePaintSample.getPaint();
412: }
413:
414: /**
415: * Returns a reference to the panel for editing the properties of the
416: * domain axis.
417: *
418: * @return A reference to a panel.
419: */
420: public DefaultAxisEditor getDomainAxisPropertyEditPanel() {
421: return this .domainAxisPropertyPanel;
422: }
423:
424: /**
425: * Returns a reference to the panel for editing the properties of the
426: * range axis.
427: *
428: * @return A reference to a panel.
429: */
430: public DefaultAxisEditor getRangeAxisPropertyEditPanel() {
431: return this .rangeAxisPropertyPanel;
432: }
433:
434: /**
435: * Handles user actions generated within the panel.
436: * @param event the event
437: */
438: public void actionPerformed(ActionEvent event) {
439: String command = event.getActionCommand();
440: if (command.equals("BackgroundPaint")) {
441: attemptBackgroundPaintSelection();
442: } else if (command.equals("OutlineStroke")) {
443: attemptOutlineStrokeSelection();
444: } else if (command.equals("OutlinePaint")) {
445: attemptOutlinePaintSelection();
446: }
447: // else if (command.equals("Insets")) {
448: // editInsets();
449: // }
450: else if (command.equals("Orientation")) {
451: attemptOrientationSelection();
452: } else if (command.equals("DrawLines")) {
453: attemptDrawLinesSelection();
454: } else if (command.equals("DrawShapes")) {
455: attemptDrawShapesSelection();
456: }
457: }
458:
459: /**
460: * Allow the user to change the background paint.
461: */
462: private void attemptBackgroundPaintSelection() {
463: Color c;
464: c = JColorChooser.showDialog(this , localizationResources
465: .getString("Background_Color"), Color.blue);
466: if (c != null) {
467: this .backgroundPaintSample.setPaint(c);
468: }
469: }
470:
471: /**
472: * Allow the user to change the outline stroke.
473: */
474: private void attemptOutlineStrokeSelection() {
475: StrokeChooserPanel panel = new StrokeChooserPanel(null,
476: this .availableStrokeSamples);
477: int result = JOptionPane
478: .showConfirmDialog(this , panel, localizationResources
479: .getString("Stroke_Selection"),
480: JOptionPane.OK_CANCEL_OPTION,
481: JOptionPane.PLAIN_MESSAGE);
482:
483: if (result == JOptionPane.OK_OPTION) {
484: this .outlineStrokeSample.setStroke(panel
485: .getSelectedStroke());
486: }
487: }
488:
489: /**
490: * Allow the user to change the outline paint. We use JColorChooser, so
491: * the user can only choose colors (a subset of all possible paints).
492: */
493: private void attemptOutlinePaintSelection() {
494: Color c;
495: c = JColorChooser.showDialog(this , localizationResources
496: .getString("Outline_Color"), Color.blue);
497: if (c != null) {
498: this .outlinePaintSample.setPaint(c);
499: }
500: }
501:
502: // /**
503: // * Allow the user to edit the individual insets' values.
504: // */
505: // private void editInsets() {
506: // InsetsChooserPanel panel = new InsetsChooserPanel(this.plotInsets);
507: // int result = JOptionPane.showConfirmDialog(
508: // this, panel, localizationResources.getString("Edit_Insets"),
509: // JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE
510: // );
511: //
512: // if (result == JOptionPane.OK_OPTION) {
513: // this.plotInsets = panel.getInsets();
514: // this.insetsTextField.setInsets(this.plotInsets);
515: // }
516: //
517: // }
518: //
519: /**
520: * Allow the user to modify the plot orientation if this is an editor for a
521: * <tt>CategoryPlot</tt> or a <tt>XYPlot</tt>.
522: */
523: private void attemptOrientationSelection() {
524:
525: int index = this .orientationCombo.getSelectedIndex();
526:
527: if (index == ORIENTATION_VERTICAL) {
528: this .plotOrientation = PlotOrientation.VERTICAL;
529: } else {
530: this .plotOrientation = PlotOrientation.HORIZONTAL;
531: }
532: }
533:
534: /**
535: * Allow the user to modify whether or not lines are drawn between data
536: * points by <tt>LineAndShapeRenderer</tt>s and
537: * <tt>StandardXYItemRenderer</tt>s.
538: */
539: private void attemptDrawLinesSelection() {
540: this .drawLines = BooleanUtilities
541: .valueOf(this .drawLinesCheckBox.isSelected());
542: }
543:
544: /**
545: * Allow the user to modify whether or not shapes are drawn at data points
546: * by <tt>LineAndShapeRenderer</tt>s and <tt>StandardXYItemRenderer</tt>s.
547: */
548: private void attemptDrawShapesSelection() {
549: this .drawShapes = BooleanUtilities
550: .valueOf(this .drawShapesCheckBox.isSelected());
551: }
552:
553: /**
554: * Updates the plot properties to match the properties defined on the panel.
555: *
556: * @param plot The plot.
557: */
558: public void updatePlotProperties(Plot plot) {
559:
560: // set the plot properties...
561: plot.setOutlinePaint(getOutlinePaint());
562: plot.setOutlineStroke(getOutlineStroke());
563: plot.setBackgroundPaint(getBackgroundPaint());
564: plot.setInsets(getPlotInsets());
565:
566: // then the axis properties...
567: if (this .domainAxisPropertyPanel != null) {
568: Axis domainAxis = null;
569: if (plot instanceof CategoryPlot) {
570: CategoryPlot p = (CategoryPlot) plot;
571: domainAxis = p.getDomainAxis();
572: } else if (plot instanceof XYPlot) {
573: XYPlot p = (XYPlot) plot;
574: domainAxis = p.getDomainAxis();
575: }
576: if (domainAxis != null) {
577: this .domainAxisPropertyPanel
578: .setAxisProperties(domainAxis);
579: }
580: }
581:
582: if (this .rangeAxisPropertyPanel != null) {
583: Axis rangeAxis = null;
584: if (plot instanceof CategoryPlot) {
585: CategoryPlot p = (CategoryPlot) plot;
586: rangeAxis = p.getRangeAxis();
587: } else if (plot instanceof XYPlot) {
588: XYPlot p = (XYPlot) plot;
589: rangeAxis = p.getRangeAxis();
590: }
591: if (rangeAxis != null) {
592: this .rangeAxisPropertyPanel
593: .setAxisProperties(rangeAxis);
594: }
595: }
596:
597: if (this .plotOrientation != null) {
598: if (plot instanceof CategoryPlot) {
599: CategoryPlot p = (CategoryPlot) plot;
600: p.setOrientation(this .plotOrientation);
601: } else if (plot instanceof XYPlot) {
602: XYPlot p = (XYPlot) plot;
603: p.setOrientation(this .plotOrientation);
604: }
605: }
606:
607: if (this .drawLines != null) {
608: if (plot instanceof CategoryPlot) {
609: CategoryPlot p = (CategoryPlot) plot;
610: CategoryItemRenderer r = p.getRenderer();
611: if (r instanceof LineAndShapeRenderer) {
612: ((LineAndShapeRenderer) r)
613: .setLinesVisible(this .drawLines
614: .booleanValue());
615: }
616: } else if (plot instanceof XYPlot) {
617: XYPlot p = (XYPlot) plot;
618: XYItemRenderer r = p.getRenderer();
619: if (r instanceof StandardXYItemRenderer) {
620: ((StandardXYItemRenderer) r)
621: .setPlotLines(this .drawLines.booleanValue());
622: }
623: }
624: }
625:
626: if (this .drawShapes != null) {
627: if (plot instanceof CategoryPlot) {
628: CategoryPlot p = (CategoryPlot) plot;
629: CategoryItemRenderer r = p.getRenderer();
630: if (r instanceof LineAndShapeRenderer) {
631: ((LineAndShapeRenderer) r)
632: .setShapesVisible(this .drawShapes
633: .booleanValue());
634: }
635: } else if (plot instanceof XYPlot) {
636: XYPlot p = (XYPlot) plot;
637: XYItemRenderer r = p.getRenderer();
638: if (r instanceof StandardXYItemRenderer) {
639: ((StandardXYItemRenderer) r)
640: .setBaseShapesVisible(this .drawShapes
641: .booleanValue());
642: }
643: }
644: }
645:
646: //dmo: added this panel for colorbar control. (start dmo additions)
647: if (this .colorBarAxisPropertyPanel != null) {
648: ColorBar colorBar = null;
649: if (plot instanceof ContourPlot) {
650: ContourPlot p = (ContourPlot) plot;
651: colorBar = p.getColorBar();
652: }
653: if (colorBar != null) {
654: this .colorBarAxisPropertyPanel
655: .setAxisProperties(colorBar);
656: }
657: }
658: //dmo: (end dmo additions)
659:
660: }
661:
662: }
|