001    /*
002     * $Id: CompoundPainter.java,v 1.3 2006/03/26 00:45:10 rbair Exp $
003     *
004     * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005     * Santa Clara, California 95054, U.S.A. All rights reserved.
006     *
007     * This library is free software; you can redistribute it and/or
008     * modify it under the terms of the GNU Lesser General Public
009     * License as published by the Free Software Foundation; either
010     * version 2.1 of the License, or (at your option) any later version.
011     * 
012     * This library is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015     * Lesser General Public License for more details.
016     * 
017     * You should have received a copy of the GNU Lesser General Public
018     * License along with this library; if not, write to the Free Software
019     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
020     */
021    
022    package org.jdesktop.swingx.painter;
023    
024    import java.awt.Graphics2D;
025    import javax.swing.JComponent;
026    import org.jdesktop.swingx.JavaBean;
027    
028    /**
029     * <p>A Painter implemention that contains an array of Painters, and executes them
030     * in order. This allows you to create a layered series of painters, similar to
031     * the layer design style in Photoshop or other image processing software.</p>
032     *
033     * <p>For example, if I want to create a CompoundPainter that started with a blue
034     * background, had pinstripes on it running at a 45 degree angle, and those
035     * pinstripes appeared to "fade in" from left to right, I would write the following:
036     * <pre><code>
037     *  Color blue = new Color(0x417DDD);
038     *  Color translucent = new Color(blue.getRed(), blue.getGreen(), blue.getBlue(), 0);
039     *  panel.setBackground(blue);
040     *  panel.setForeground(Color.LIGHT_GRAY);
041     *  GradientPaint blueToTranslucent = new GradientPaint(
042     *    new Point2D.Double(.4, 0),
043     *    blue,
044     *    new Point2D.Double(1, 0),
045     *    translucent);
046     *  Painter veil =  new BasicGradientPainter(blueToTranslucent);
047     *  Painter pinstripes = new PinstripePainter(45);
048     *  Painter backgroundPainter = new BackgroundPainter();
049     *  Painter p = new CompoundPainter(backgroundPainter, pinstripes, veil);
050     *  panel.setBackgroundPainter(p);
051     * </code></pre></p>
052     *
053     * @author rbair
054     */
055    public class CompoundPainter extends AbstractPainter {
056        private Painter[] painters = new Painter[0];
057        
058        /** Creates a new instance of CompoundPainter */
059        public CompoundPainter() {
060        }
061        
062        /**
063         * Convenience constructor for creating a CompoundPainter for an array
064         * of painters. A defensive copy of the given array is made, so that future
065         * modification to the array does not result in changes to the CompoundPainter.
066         *
067         * @param painters array of painters, which will be painted in order
068         */
069        public CompoundPainter(Painter... painters) {
070            this.painters = new Painter[painters == null ? 0 : painters.length];
071            if (painters != null) {
072                System.arraycopy(painters, 0, this.painters, 0, painters.length);
073            }
074        }
075        
076        /**
077         * Sets the array of Painters to use. These painters will be executed in
078         * order. A null value will be treated as an empty array.
079         *
080         * @param painters array of painters, which will be painted in order
081         */
082        public void setPainters(Painter... painters) {
083            Painter[] old = getPainters();
084            this.painters = new Painter[painters == null ? 0 : painters.length];
085            if (painters != null) {
086                System.arraycopy(painters, 0, this.painters, 0, painters.length);
087            }
088            firePropertyChange("painters", old, getPainters());
089        }
090        
091        /**
092         * @return a defensive copy of the painters used by this CompoundPainter.
093         *         This will never be null.
094         */
095        public Painter[] getPainters() {
096            Painter[] results = new Painter[painters.length];
097            System.arraycopy(painters, 0, results, 0, results.length);
098            return results;
099        }
100    
101        /**
102         * @inheritDoc
103         */
104        public void paintBackground(Graphics2D g, JComponent component) {
105            for (Painter p : getPainters()) {
106                p.paint(g, component);
107            }
108        }
109    }