001    /* ===========================================================
002     * JFreeChart : a free chart library for the Java(tm) platform
003     * ===========================================================
004     *
005     * (C) Copyright 2000-2007, 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     * LineBorder.java
029     * ---------------
030     * (C) Copyright 2007, by Christo Zietsman and Contributors.
031     *
032     * Original Author:  Christo Zietsman;
033     * Contributor(s):   David Gilbert (for Object Refinery Limited);
034     *
035     * $Id: LineBorder.java,v 1.1.2.1 2007/03/16 15:26:15 mungady Exp $
036     *
037     * Changes:
038     * --------
039     * 16-Mar-2007 : Version 1, contributed by Christo Zietsman with
040     *               modifications by DG (DG);
041     * 
042     */
043    
044    package org.jfree.chart.block;
045    
046    import java.awt.BasicStroke;
047    import java.awt.Color;
048    import java.awt.Graphics2D;
049    import java.awt.Paint;
050    import java.awt.Stroke;
051    import java.awt.geom.Line2D;
052    import java.awt.geom.Rectangle2D;
053    import java.io.IOException;
054    import java.io.ObjectInputStream;
055    import java.io.ObjectOutputStream;
056    import java.io.Serializable;
057    
058    import org.jfree.io.SerialUtilities;
059    import org.jfree.ui.RectangleInsets;
060    import org.jfree.util.ObjectUtilities;
061    import org.jfree.util.PaintUtilities;
062    
063    /**
064     * A line border for any {@link AbstractBlock}. 
065     * 
066     * @since 1.0.5
067     */
068    public class LineBorder implements BlockFrame, Serializable {
069    
070        /** The line color. */
071        private transient Paint paint;
072        
073        /** The line stroke. */
074        private transient Stroke stroke;
075        
076        /** The insets. */
077        private RectangleInsets insets;
078        
079        /**
080         * Creates a default border.
081         */
082        public LineBorder() {
083            this(Color.black, new BasicStroke(1.0f), new RectangleInsets(1.0, 1.0, 
084                    1.0, 1.0));
085        }
086        
087        /**
088         * Creates a new border with the specified color.
089         * 
090         * @param paint  the color (<code>null</code> not permitted).
091         * @param stroke  the border stroke (<code>null</code> not permitted).
092         * @param insets  the insets (<code>null</code> not permitted).
093         */    
094        public LineBorder(Paint paint, Stroke stroke, RectangleInsets insets) {
095            if (paint == null) {
096                throw new IllegalArgumentException("Null 'paint' argument.");
097            }
098            if (stroke == null) {
099                throw new IllegalArgumentException("Null 'stroke' argument.");
100            }
101            if (insets == null) {
102                throw new IllegalArgumentException("Null 'insets' argument.");
103            }
104            this.paint = paint;
105            this.stroke = stroke;
106            this.insets = insets;
107        }  
108        
109        /**
110         * Returns the paint.
111         * 
112         * @return The paint (never <code>null</code>).
113         */
114        public Paint getPaint() {
115            return this.paint;
116        }
117        
118        /**
119         * Returns the insets.
120         * 
121         * @return The insets (never <code>null</code>).
122         */
123        public RectangleInsets getInsets() {
124            return this.insets;
125        }
126    
127        /**
128         * Returns the stroke.
129         * 
130         * @return The stroke (never <code>null</code>).
131         */
132        public Stroke getStroke() {
133            return this.stroke;
134        }
135        
136        /**
137         * Draws the border by filling in the reserved space (in black).
138         * 
139         * @param g2  the graphics device.
140         * @param area  the area.
141         */
142        public void draw(Graphics2D g2, Rectangle2D area) {
143            double w = area.getWidth();
144            double h = area.getHeight();
145            double t = this.insets.calculateTopInset(h);
146            double b = this.insets.calculateBottomInset(h);
147            double l = this.insets.calculateLeftInset(w);
148            double r = this.insets.calculateRightInset(w);
149            double x = area.getX();
150            double y = area.getY();
151            double x0 = x + l / 2.0;
152            double x1 = x + w - r / 2.0;
153            double y0 = y + h - b / 2.0;
154            double y1 = y + t / 2.0;
155            g2.setPaint(getPaint());
156            g2.setStroke(getStroke());
157            Line2D line = new Line2D.Double();
158            if (t > 0.0) {
159                line.setLine(x0, y1, x1, y1);
160                g2.draw(line);
161            }
162            if (b > 0.0) {
163                line.setLine(x0, y0, x1, y0);
164                g2.draw(line);
165            }
166            if (l > 0.0) {
167                line.setLine(x0, y0, x0, y1);
168                g2.draw(line);
169            }
170            if (r > 0.0) {
171                line.setLine(x1, y0, x1, y1);
172                g2.draw(line);
173            }        
174        }    
175    
176        /**
177         * Tests this border for equality with an arbitrary instance.
178         * 
179         * @param obj  the object (<code>null</code> permitted).
180         * 
181         * @return A boolean.
182         */
183        public boolean equals(Object obj) {
184            if (obj == this) {
185                return true;   
186            }
187            if (!(obj instanceof LineBorder)) {
188                return false;   
189            }
190            LineBorder that = (LineBorder) obj;
191            if (!PaintUtilities.equal(this.paint, that.paint)) {
192                return false;
193            }
194            if (!ObjectUtilities.equal(this.stroke, that.stroke)){
195                return false;
196            }
197            if (!this.insets.equals(that.insets)) {
198                return false;
199            }
200            return true;
201        }    
202    
203        /**
204         * Provides serialization support.
205         *
206         * @param stream  the output stream.
207         *
208         * @throws IOException  if there is an I/O error.
209         */
210        private void writeObject(ObjectOutputStream stream) throws IOException {
211            stream.defaultWriteObject();
212            SerialUtilities.writePaint(this.paint, stream);
213            SerialUtilities.writeStroke(this.stroke, stream);
214        }
215    
216        /**
217         * Provides serialization support.
218         *
219         * @param stream  the input stream.
220         *
221         * @throws IOException  if there is an I/O error.
222         * @throws ClassNotFoundException  if there is a classpath problem.
223         */
224        private void readObject(ObjectInputStream stream) 
225            throws IOException, ClassNotFoundException {
226            stream.defaultReadObject();
227            this.paint = SerialUtilities.readPaint(stream);
228            this.stroke = SerialUtilities.readStroke(stream);
229        }    
230    }
231    
232