001: /*
002: * Copyright (c) 2005-2008 Substance Kirill Grouchnikov. 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 Substance Kirill Grouchnikov 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: package org.jvnet.substance.watermark;
031:
032: import java.awt.*;
033: import java.awt.geom.GeneralPath;
034:
035: import org.jvnet.substance.SubstanceLookAndFeel;
036: import org.jvnet.substance.utils.SubstanceColorUtilities;
037: import org.jvnet.substance.utils.SubstanceCoreUtilities;
038:
039: /**
040: * Implementation of {@link org.jvnet.substance.watermark.SubstanceWatermark},
041: * drawing random bubbles as watermark. This class is part of officially
042: * supported API.
043: *
044: * @author Kirill Grouchnikov
045: * @author Chris Hall
046: */
047: public class SubstanceBubblesWatermark implements SubstanceWatermark {
048: /**
049: * Watermark image (screen-sized).
050: */
051: private static Image watermarkImage = null;
052:
053: /*
054: * (non-Javadoc)
055: *
056: * @see org.jvnet.substance.watermark.SubstanceWatermark#drawWatermarkImage(java.awt.Graphics,
057: * int, int, int, int)
058: */
059: public void drawWatermarkImage(Graphics graphics, Component c,
060: int x, int y, int width, int height) {
061: if (!c.isShowing())
062: return;
063: int dx = c.getLocationOnScreen().x;
064: int dy = c.getLocationOnScreen().y;
065: graphics.drawImage(SubstanceBubblesWatermark.watermarkImage, x,
066: y, x + width, y + height, x + dx, y + dy, x + dx
067: + width, y + dy + height, null);
068: }
069:
070: /*
071: * (non-Javadoc)
072: *
073: * @see org.jvnet.substance.watermark.SubstanceWatermark#updateWatermarkImage()
074: */
075: public boolean updateWatermarkImage() {
076: // fix by Chris for bug 67 - support for multiple screens
077: Rectangle virtualBounds = new Rectangle();
078: GraphicsEnvironment ge = GraphicsEnvironment
079: .getLocalGraphicsEnvironment();
080: GraphicsDevice[] gds = ge.getScreenDevices();
081: for (GraphicsDevice gd : gds) {
082: GraphicsConfiguration gc = gd.getDefaultConfiguration();
083: virtualBounds = virtualBounds.union(gc.getBounds());
084: }
085:
086: int screenWidth = virtualBounds.width;
087: int screenHeight = virtualBounds.height;
088: SubstanceBubblesWatermark.watermarkImage = SubstanceCoreUtilities
089: .getBlankImage(screenWidth, screenHeight);
090:
091: Graphics2D graphics = (Graphics2D) SubstanceBubblesWatermark.watermarkImage
092: .getGraphics().create();
093:
094: boolean status = this .drawWatermarkImage(graphics, 0, 0,
095: screenWidth, screenHeight, false);
096: graphics.dispose();
097: return status;
098: }
099:
100: /*
101: * (non-Javadoc)
102: *
103: * @see org.jvnet.substance.watermark.SubstanceWatermark#previewWatermark(java.awt.Graphics,
104: * int, int, int, int)
105: */
106: public void previewWatermark(Graphics g, int x, int y, int width,
107: int height) {
108: this .drawWatermarkImage((Graphics2D) g, x, y, width, height,
109: true);
110: }
111:
112: /**
113: * Draws the specified portion of the watermark image.
114: *
115: * @param graphics
116: * Graphic context.
117: * @param x
118: * the <i>x</i> coordinate of the watermark to be drawn.
119: * @param y
120: * The <i>y</i> coordinate of the watermark to be drawn.
121: * @param width
122: * The width of the watermark to be drawn.
123: * @param height
124: * The height of the watermark to be drawn.
125: * @param isPreview
126: * Indication whether the result is a preview image.
127: * @return Indication whether the draw succeeded.
128: */
129: private boolean drawWatermarkImage(Graphics2D graphics, int x,
130: int y, int width, int height, boolean isPreview) {
131: Color stampColor = null;
132: if (isPreview)
133: stampColor = SubstanceCoreUtilities
134: .isThemeDark(SubstanceLookAndFeel.getTheme()) ? Color.white
135: : Color.black;
136: else {
137: stampColor = SubstanceColorUtilities
138: .getWatermarkStampColor();
139: }
140: int minBubbleRadius = 10;
141: int maxBubbleRadius = 20;
142:
143: int cellSize = (minBubbleRadius + maxBubbleRadius);
144: int rowCount = height / cellSize;
145: int columnCount = width / cellSize;
146:
147: graphics.setColor(stampColor);
148: graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
149: RenderingHints.VALUE_ANTIALIAS_ON);
150: for (int col = 0; col <= columnCount; col++) {
151: for (int row = 0; row <= rowCount; row++) {
152: // location
153: double xval = isPreview ? Math.abs(Math
154: .sin((2.8 + col + columnCount * row))) : Math
155: .random();
156: int xc = x + (int) (col * cellSize + cellSize * xval);
157: double yval = isPreview ? Math.abs(Math
158: .sin((3.5 + col + columnCount * row))) : Math
159: .random();
160: int yc = y + (int) (row * cellSize + cellSize * yval);
161: double val = isPreview ? 0.1 * Math.abs(Math
162: .sin((1 + col + columnCount * row))) : Math
163: .random();
164: int r = minBubbleRadius
165: + (int) (val * (maxBubbleRadius - minBubbleRadius));
166: graphics.drawOval(xc - r, yc - r, 2 * r, 2 * r);
167:
168: GeneralPath shine = new GeneralPath();
169: shine.moveTo(xc - 0.2f * r, yc - 0.8f * r);
170: shine.quadTo(xc - 0.7f * r, yc - 0.6f * r, xc - 0.8f
171: * r, yc - 0.1f * r);
172: shine.lineTo(xc - 0.3f * r, yc + 0.2f * r);
173: shine.quadTo(xc - 0.3f * r, yc - 0.4f * r, xc, yc
174: - 0.6f * r);
175: shine.lineTo(xc - 0.2f * r, yc - 0.8f * r);
176: graphics.draw(shine);
177: // graphics.fill(shine);
178: }
179: }
180: return true;
181: }
182:
183: /*
184: * (non-Javadoc)
185: *
186: * @see org.jvnet.substance.watermark.SubstanceWatermark#getDisplayName()
187: */
188: public String getDisplayName() {
189: return SubstanceBubblesWatermark.getName();
190: }
191:
192: /**
193: * Returns the name of all watermarks of <code>this</code> class.
194: *
195: * @return The name of all watermarks of <code>this</code> class.
196: */
197: public static String getName() {
198: return "Bubbles";
199: }
200:
201: /*
202: * (non-Javadoc)
203: *
204: * @see org.jvnet.substance.watermark.SubstanceWatermark#isDependingOnTheme()
205: */
206: public boolean isDependingOnTheme() {
207: return true;
208: }
209:
210: /*
211: * (non-Javadoc)
212: *
213: * @see org.jvnet.substance.watermark.SubstanceWatermark#dispose()
214: */
215: public void dispose() {
216: watermarkImage = null;
217: }
218: }
|