001/* ===========================================================
002 * JFreeChart : a free chart library for the Java(tm) platform
003 * ===========================================================
004 *
005 * (C) Copyright 2000-present, 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
029package org.jfree.chart.ui;
030
031import java.awt.Component;
032import java.awt.Dimension;
033import java.awt.Graphics;
034import java.awt.Graphics2D;
035import java.awt.Insets;
036import java.awt.RenderingHints;
037import java.awt.Stroke;
038import java.awt.geom.Ellipse2D;
039import java.awt.geom.Line2D;
040import java.awt.geom.Point2D;
041import javax.swing.JComponent;
042import javax.swing.JList;
043import javax.swing.ListCellRenderer;
044
045/**
046 * A panel that displays a stroke sample.
047 */
048public class StrokeSample extends JComponent implements ListCellRenderer {
049
050    /** The stroke being displayed (may be null). */
051    private Stroke stroke;
052
053    /** The preferred size of the component. */
054    private Dimension preferredSize;
055
056    /**
057     * Creates a StrokeSample for the specified stroke.
058     *
059     * @param stroke  the sample stroke ({@code null} permitted).
060     */
061    public StrokeSample(Stroke stroke) {
062        this.stroke = stroke;
063        this.preferredSize = new Dimension(80, 18);
064        setPreferredSize(this.preferredSize);
065    }
066
067    /**
068     * Returns the current Stroke object being displayed.
069     *
070     * @return The stroke (possibly {@code null}).
071     */
072    public Stroke getStroke() {
073        return this.stroke;
074    }
075
076    /**
077     * Sets the stroke object being displayed and repaints the component.
078     *
079     * @param stroke  the stroke ({@code null} permitted).
080     */
081    public void setStroke(Stroke stroke) {
082        this.stroke = stroke;
083        repaint();
084    }
085
086    /**
087     * Returns the preferred size of the component.
088     *
089     * @return the preferred size of the component.
090     */
091    @Override
092    public Dimension getPreferredSize() {
093        return this.preferredSize;
094    }
095
096    /**
097     * Draws a line using the sample stroke.
098     *
099     * @param g  the graphics device.
100     */
101    @Override
102    public void paintComponent(Graphics g) {
103
104        Graphics2D g2 = (Graphics2D) g;
105        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
106                RenderingHints.VALUE_ANTIALIAS_ON);
107        Dimension size = getSize();
108        Insets insets = getInsets();
109        double xx = insets.left;
110        double yy = insets.top;
111        double ww = size.getWidth() - insets.left - insets.right;
112        double hh = size.getHeight() - insets.top - insets.bottom;
113
114        // calculate point one
115        Point2D one =  new Point2D.Double(xx + 6, yy + hh / 2);
116        // calculate point two
117        Point2D two =  new Point2D.Double(xx + ww - 6, yy + hh / 2);
118        // draw a circle at point one
119        Ellipse2D circle1 = new Ellipse2D.Double(one.getX() - 5,
120                one.getY() - 5, 10, 10);
121        Ellipse2D circle2 = new Ellipse2D.Double(two.getX() - 6,
122                two.getY() - 5, 10, 10);
123
124        // draw a circle at point two
125        g2.draw(circle1);
126        g2.fill(circle1);
127        g2.draw(circle2);
128        g2.fill(circle2);
129
130        // draw a line connecting the points
131        Line2D line = new Line2D.Double(one, two);
132        if (this.stroke != null) {
133            g2.setStroke(this.stroke);
134            g2.draw(line);
135        }
136
137    }
138
139    /**
140     * Returns a list cell renderer for the stroke, so the sample can be
141     * displayed in a list or combo.
142     *
143     * @param list  the list.
144     * @param value  the value.
145     * @param index  the index.
146     * @param isSelected  selected?
147     * @param cellHasFocus  focussed?
148     *
149     * @return the component for rendering.
150     */
151    @Override
152    public Component getListCellRendererComponent(JList list, Object value,
153            int index, boolean isSelected, boolean cellHasFocus) {
154        if (value instanceof Stroke) {
155            setStroke((Stroke) value);
156        }
157        else {
158            setStroke(null);
159        }
160        return this;
161    }
162
163}