001: /*
002: * Copyright (C) 2004 NNL Technology AB
003: * Visit www.infonode.net for information about InfoNode(R)
004: * products and how to contact NNL Technology AB.
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
019: * MA 02111-1307, USA.
020: */
021:
022: // $Id: ShapedPanel.java,v 1.32 2005/12/04 13:46:04 jesper Exp $
023: package net.infonode.gui.shaped.panel;
024:
025: import net.infonode.gui.BackgroundPainter;
026: import net.infonode.gui.InsetsUtil;
027: import net.infonode.gui.componentpainter.ComponentPainter;
028: import net.infonode.gui.panel.BaseContainer;
029: import net.infonode.gui.shaped.border.ShapedBorder;
030: import net.infonode.util.Direction;
031:
032: import javax.swing.border.Border;
033: import javax.swing.border.CompoundBorder;
034: import java.awt.*;
035:
036: /**
037: * <p>
038: * A panel that has support for a {@link ComponentPainter} and a {@link ShapedBorder}.
039: * The background of the panel is painted as normal and then the {@link ComponentPainter}
040: * paints the area inside the {@link ShapedBorder} or the complete component area if the
041: * its border isn't a {@link ShapedBorder}.
042: * </p>
043: *
044: * <p>
045: * If a {@link ShapedBorder} is applied to this panel, mouse events etc. are only triggered
046: * for this panel if the point is inside the {@link Shape} of the {@link ShapedBorder}. Child
047: * components of this panel can optionally be clipped using the {@link Shape}.
048: * </p>
049: *
050: * <p>
051: * A {@link ShapedBorder} wrapped inside {@link CompoundBorder}'s will be used by the ShapedPanel,
052: * but a {@link ShapedBorder} wrapped inside other border types can't be found and is hence not
053: * used by the panel.
054: * </p>
055: *
056: * @author johan
057: */
058: public class ShapedPanel extends BaseContainer implements
059: BackgroundPainter {
060: private Direction direction = Direction.RIGHT;
061: private boolean horizontalFlip;
062: private boolean verticalFlip;
063: private boolean clipChildren;
064: private ComponentPainter painter;
065: private ShapedBorder shapedBorder;
066: private Insets shapedInsets;
067:
068: public ShapedPanel() {
069: super ();
070: }
071:
072: public ShapedPanel(LayoutManager l) {
073: super (l);
074: }
075:
076: public ShapedPanel(ComponentPainter painter) {
077: this ();
078: this .painter = painter;
079: }
080:
081: public ShapedPanel(ComponentPainter painter, Border border) {
082: this (painter);
083: setBorder(border);
084: }
085:
086: public ShapedPanel(Component component) {
087: this ();
088: add(component, BorderLayout.CENTER);
089: }
090:
091: public Shape getShape() {
092: ShapedBorder b = getShapedBorder();
093: return b == null ? null : b.getShape(this , shapedInsets.left,
094: shapedInsets.top, getWidth() - shapedInsets.left
095: - shapedInsets.right, getHeight()
096: - shapedInsets.top - shapedInsets.bottom);
097: }
098:
099: public ComponentPainter getComponentPainter() {
100: return painter;
101: }
102:
103: public void setComponentPainter(ComponentPainter painter) {
104: if (this .painter != painter) {
105: this .painter = painter;
106:
107: repaint();
108: }
109: }
110:
111: public Direction getDirection() {
112: return direction;
113: }
114:
115: public boolean isHorizontalFlip() {
116: return horizontalFlip;
117: }
118:
119: public void setHorizontalFlip(boolean horizontalFlip) {
120: if (this .horizontalFlip != horizontalFlip) {
121: this .horizontalFlip = horizontalFlip;
122: revalidate();
123: }
124: }
125:
126: public boolean isVerticalFlip() {
127: return verticalFlip;
128: }
129:
130: public void setVerticalFlip(boolean verticalFlip) {
131: if (this .verticalFlip != verticalFlip) {
132: this .verticalFlip = verticalFlip;
133: revalidate();
134: }
135: }
136:
137: public void setDirection(Direction direction) {
138: if (this .direction != direction) {
139: this .direction = direction;
140: revalidate();
141:
142: repaint();
143: }
144: }
145:
146: public boolean isClipChildren() {
147: return clipChildren;
148: }
149:
150: public void setClipChildren(boolean clipChildren) {
151: this .clipChildren = clipChildren;
152: }
153:
154: public ShapedBorder getShapedBorder() {
155: return shapedBorder;
156: }
157:
158: public void setBorder(Border border) {
159: super .setBorder(border);
160: shapedBorder = null;
161: findShapedBorder(getBorder(), new Insets(0, 0, 0, 0));
162: }
163:
164: protected void paintChildren(Graphics g) {
165: if (clipChildren) {
166: Shape shape = getShape();
167:
168: if (shape != null) {
169: Graphics2D g2 = (Graphics2D) g;
170: Shape clip = g2.getClip();
171: g2.clip(shape);
172: super .paintChildren(g);
173: g2.setClip(clip);
174:
175: /* ShapedBorder sb = getShapedBorder();
176:
177: if (sb != null)
178: sb.paintBorder(this, g, shapedInsets.left, shapedInsets.top, getWidth() - shapedInsets.left -shapedInsets.right, getHeight() - shapedInsets.top - shapedInsets.bottom);
179: */
180: return;
181: }
182: }
183:
184: super .paintChildren(g);
185: }
186:
187: protected void paintComponent(Graphics g) {
188: super .paintComponent(g);
189:
190: if (painter != null) {
191: Shape shape = getShape();
192:
193: if (shape != null) {
194: Shape clip = g.getClip();
195: g.clipRect(shapedInsets.left, shapedInsets.top,
196: getWidth() - shapedInsets.left
197: - shapedInsets.right, getHeight()
198: - shapedInsets.top
199: - shapedInsets.bottom);
200: ((Graphics2D) g).clip(shape);
201: painter.paint(this , g, 0, 0, getWidth(), getHeight(),
202: direction, horizontalFlip, verticalFlip);
203: g.setClip(clip);
204: } else
205: painter.paint(this , g, 0, 0, getWidth(), getHeight(),
206: direction, horizontalFlip, verticalFlip);
207: }
208: }
209:
210: public boolean contains(int x, int y) {
211: if (x < 0 || y < 0 || x >= getWidth() || y >= getHeight())
212: return false;
213:
214: Shape shape = getShape();
215: return shape == null ? super .contains(x, y) : shape.contains(x,
216: y);
217: }
218:
219: public boolean inside(int x, int y) {
220: if (x < 0 || y < 0 || x >= getWidth() || y >= getHeight())
221: return false;
222:
223: Shape shape = getShape();
224: return shape == null ? super .inside(x, y) : shape
225: .contains(x, y);
226: }
227:
228: private boolean findShapedBorder(Border border, Insets i) {
229: if (border == null)
230: return false;
231: else if (border instanceof ShapedBorder) {
232: shapedBorder = (ShapedBorder) border;
233: shapedInsets = i;
234: return true;
235: } else if (border instanceof CompoundBorder) {
236: CompoundBorder c = (CompoundBorder) border;
237:
238: if (findShapedBorder(c.getOutsideBorder(), i))
239: return true;
240:
241: return findShapedBorder(c.getInsideBorder(), InsetsUtil
242: .add(c.getOutsideBorder().getBorderInsets(this ), i));
243: } else
244: return false;
245: }
246: }
|