001/*
002 * Copyright (c) 2002-2007 JGoodies Karsten Lentzsch. All Rights Reserved.
003 *
004 * Redistribution and use in source and binary forms, with or without
005 * modification, are permitted provided that the following conditions are met:
006 *
007 *  o Redistributions of source code must retain the above copyright notice,
008 *    this list of conditions and the following disclaimer.
009 *
010 *  o Redistributions in binary form must reproduce the above copyright notice,
011 *    this list of conditions and the following disclaimer in the documentation
012 *    and/or other materials provided with the distribution.
013 *
014 *  o Neither the name of JGoodies Karsten Lentzsch nor the names of
015 *    its contributors may be used to endorse or promote products derived
016 *    from this software without specific prior written permission.
017 *
018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030
031package com.jgoodies.forms.debug;
032
033import java.awt.Color;
034import java.awt.Graphics;
035
036import javax.swing.JPanel;
037
038import com.jgoodies.forms.layout.FormLayout;
039
040/**
041 * A panel that paints grid bounds if and only if the panel's layout manager
042 * is a {@link FormLayout}. You can tweak the debug paint process by setting
043 * a custom grid color, painting optional diagonals and painting the grid
044 * in the background or foreground.<p>
045 *
046 * This class is not intended to be extended. However, it is not
047 * marked as <code>final</code> to allow users to subclass it for
048 * debugging purposes. In general it is recommended to <em>use</em> JPanel
049 * instances, not <em>extend</em> them. You can see this implementation style
050 * in the Forms tutorial classes. Rarely there's a need to extend JPanel;
051 * for example if you provide a custom behavior for
052 * <code>#paintComponent</code> or <code>#updateUI</code>.
053 *
054 * @author  Karsten Lentzsch
055 * @version $Revision$
056 *
057 * @see     FormDebugUtils
058 */
059@SuppressWarnings("serial")
060public class FormDebugPanel extends JPanel {
061
062    /**
063     * The default color used to paint the form's debug grid.
064     */
065    private static final Color DEFAULT_GRID_COLOR = Color.red;
066
067    /**
068     * Specifies whether the grid shall be painted in the background.
069     * Is off by default and so the grid is painted in the foreground.
070     */
071    private boolean paintInBackground;
072
073    /**
074     * Specifies whether the container's diagonals should be painted.
075     */
076    private boolean paintDiagonals;
077
078    /**
079     * Holds the color used to paint the debug grid.
080     */
081    private Color gridColor = DEFAULT_GRID_COLOR;
082
083    // Instance Creation ****************************************************
084
085    /**
086     * Constructs a FormDebugPanel with all options turned off.
087     */
088    public FormDebugPanel() {
089        this(null);
090    }
091
092    /**
093     * Constructs a FormDebugPanel on the given FormLayout instance
094     * that paints the grid in the foreground and paints no diagonals.
095     *
096     * @param layout  the panel's FormLayout instance
097     */
098    public FormDebugPanel(FormLayout layout) {
099        this(layout, false, false);
100    }
101
102    /**
103     * Constructs a FormDebugPanel on the given FormLayout
104     * using the specified settings that are otherwise turned off.
105     *
106     * @param paintInBackground
107     *     true to paint grid lines in the background,
108     *     false to paint the grid in the foreground
109     * @param paintDiagonals
110     *     true to paint diagonals,
111     *     false to not paint them
112     */
113    public FormDebugPanel(boolean paintInBackground, boolean paintDiagonals) {
114        this(null, paintInBackground, paintDiagonals);
115    }
116
117    /**
118     * Constructs a FormDebugPanel on the given FormLayout using
119     * the specified settings that are otherwise turned off.
120     *
121     * @param layout
122     *     the panel's FormLayout instance
123     * @param paintInBackground
124     *     true to paint grid lines in the background,
125     *     false to paint the grid in the foreground
126     * @param paintDiagonals
127     *     true to paint diagonals,
128     *     false to not paint them
129     */
130    public FormDebugPanel(FormLayout layout, boolean paintInBackground,
131            boolean paintDiagonals) {
132        super(layout);
133        setPaintInBackground(paintInBackground);
134        setPaintDiagonals(paintDiagonals);
135        setGridColor(DEFAULT_GRID_COLOR);
136    }
137
138    // Accessors ************************************************************
139
140    /**
141     * Specifies to paint in background or foreground.
142     *
143     * @param b    true to paint in the background, false for the foreground
144     */
145    public void setPaintInBackground(boolean b) {
146        paintInBackground = b;
147    }
148
149    /**
150     * Enables or disables to paint the panel's diagonals.
151     *
152     * @param b    true to paint diagonals, false to not paint them
153     */
154    public void setPaintDiagonals(boolean b) {
155        paintDiagonals = b;
156    }
157
158    /**
159     * Sets the debug grid's color.
160     *
161     * @param color  the color used to paint the debug grid
162     */
163    public void setGridColor(Color color) {
164        gridColor = color;
165    }
166
167    // Painting *************************************************************
168
169    /**
170     * Paints the component and - if background painting is enabled - the grid.
171     * If foreground painting is enabled, the grid will be painted in
172     * <code>#paint</code>.
173     *
174     * @param g   the Graphics object to paint on
175     *
176     * @see #paint(Graphics)
177     */
178    @Override
179    protected void paintComponent(Graphics g) {
180        super.paintComponent(g);
181        if (paintInBackground) {
182            paintGrid(g);
183        }
184    }
185
186    /**
187     * Paints the panel. If the panel's layout manager is a FormLayout
188     * and foreground painting is enabled, it paints the form's grid lines.
189     * If the grid shall be painted in the background, the grid will be
190     * painted in <code>#paintComponent</code>.
191     *
192     * @param g   the Graphics object to paint on
193     *
194     * @see #paintComponent(Graphics)
195     */
196    @Override
197    public void paint(Graphics g) {
198        super.paint(g);
199        if (!paintInBackground) {
200            paintGrid(g);
201        }
202    }
203
204    /**
205     * Paints the form's grid lines and diagonals.
206     *
207     * @param g    the Graphics object used to paint
208     */
209    private void paintGrid(Graphics g) {
210        if (!(getLayout() instanceof FormLayout)) {
211            return;
212        }
213        FormLayout.LayoutInfo layoutInfo = FormDebugUtils.getLayoutInfo(this);
214        int left = layoutInfo.getX();
215        int top = layoutInfo.getY();
216        int width = layoutInfo.getWidth();
217        int height = layoutInfo.getHeight();
218
219        g.setColor(gridColor);
220        // Paint the column bounds.
221        for (int columnOrigin : layoutInfo.columnOrigins) {
222            g.fillRect(columnOrigin, top, 1, height);
223        }
224
225        // Paint the row bounds.
226        for (int rowOrigin : layoutInfo.rowOrigins) {
227            g.fillRect(left, rowOrigin, width, 1);
228        }
229
230        if (paintDiagonals) {
231            g.drawLine(left, top, left + width, top + height);
232            g.drawLine(left, top + height, left + width, top);
233        }
234    }
235
236}