001: package snow.utils.gui;
002:
003: import java.util.*;
004: import java.awt.*;
005: import java.awt.geom.*;
006: import javax.swing.*;
007:
008: public class SnowBackgroundPanel extends JPanel {
009: final SnowIcon snowIcon = new SnowIcon(55, 55); //not 1
010: int numberOfFlocks = 5;
011: double[] posX, posY, sizes;
012:
013: public boolean highContrast = false;
014:
015: public SnowBackgroundPanel() {
016: this (new BorderLayout());
017: }
018:
019: public SnowBackgroundPanel(LayoutManager lm) {
020: super (lm);
021: }
022:
023: // indicate for which width the flocks were computed
024: int widthForFlocks = 0;
025:
026: private void createFlocksPositions() {
027: posX = new double[numberOfFlocks];
028: posY = new double[numberOfFlocks];
029: sizes = new double[numberOfFlocks];
030: widthForFlocks = this .getWidth();
031:
032: for (int i = 0; i < this .numberOfFlocks; i++) {
033: sizes[i] = Math.random()
034: * Math.max(widthForFlocks, getHeight()) / 3.7
035: + 0.01;
036:
037: posX[i] = Math.random() * widthForFlocks - sizes[i] / 2;
038: posY[i] = Math.random() * getHeight() - sizes[i] / 2;
039: }
040:
041: }
042:
043: long calls = 0;
044:
045: /** call to shift flocks on y
046: call this in the EDT !!
047: */
048: private void letSnowFall() {
049: if (!SwingUtilities.isEventDispatchThread()) {
050: throw new RuntimeException("Must be called in the EDT");
051: }
052: calls++;
053:
054: widthForFlocks = this .getWidth();
055: if (widthForFlocks != this .getWidth() || posX == null) {
056: createFlocksPositions();
057: }
058: // so we're sure that the flocks are made
059:
060: for (int i = 0; i < this .numberOfFlocks; i++) {
061:
062: posX[i] += widthForFlocks * 0.0008 * Math.random();
063: posY[i] += widthForFlocks * 0.0009 * Math.random();
064:
065: if (calls % 500 > 250) {
066: sizes[i] += (Math.random()) * widthForFlocks / 480.0;
067: } else {
068: sizes[i] -= (Math.random()) * widthForFlocks / 480.0;
069: }
070:
071: if (sizes[i] < widthForFlocks / 100) {
072: sizes[i] = widthForFlocks / 100;
073: }
074:
075: if (sizes[i] > widthForFlocks / 2) {
076: sizes[i] = widthForFlocks / 2;
077: }
078:
079: if ((posX[i] - sizes[i]) > widthForFlocks) {
080: posX[i] = -sizes[i];
081: }
082:
083: if ((posY[i] - sizes[i]) > this .getHeight()) {
084: posY[i] = -sizes[i];
085: }
086:
087: }
088:
089: }
090:
091: /**
092: * Overwritten paint method to have a slight color gradient.
093: */
094: @Override
095: public void paint(Graphics g) {
096: // cool animation when the mouse drag, ...
097: // letSnowFall(); // not nice in transp trees and tables
098:
099: Graphics2D graphics2D = (Graphics2D) g;
100: final Paint savePaint = graphics2D.getPaint();
101:
102: int width = getWidth();
103: int height = getHeight();
104:
105: if (width == 0)
106: width = 1;
107: if (height == 0)
108: height = 1;
109:
110: int max = Math.max(width, height);
111:
112: Color bgColor = UIManager.getColor("Panel.background");
113: Color destColor = null;
114:
115: if (this .highContrast) {
116: destColor = SnowBackgroundPanel
117: .createMediumLighterOrDarkerColor(bgColor);
118: } else {
119: destColor = SnowBackgroundPanel
120: .createSmallLighterOrDarkerColor(bgColor);
121: }
122:
123: GradientPaint upperLeftGradientPaint = new GradientPaint(0f,
124: 0f, bgColor, (float) max * 3.2f, (float) max * 3.2f,
125: destColor);
126: graphics2D.setPaint(upperLeftGradientPaint);
127:
128: graphics2D.fill(graphics2D.getClip());
129:
130: if (widthForFlocks != this .getWidth()) {
131: createFlocksPositions();
132: }
133:
134: if (posX != null) {
135: for (int i = 0; i < posX.length; i++) {
136: snowIcon.paintSnowFlake(graphics2D, bgColor, destColor,
137: posX[i], posY[i], sizes[i]);
138: }
139: }
140:
141: graphics2D.setPaint(savePaint);
142: super .paintChildren(graphics2D);
143: } // paint
144:
145: /**
146: * Overwitten, so it doesnt clear all, but
147: * one has to call super, so children are properly rendered.
148: */
149: @Override
150: public void update(Graphics g) {
151: //super.update(g);
152: paint(g);
153: }
154:
155: Animator animator = null;
156:
157: /** important: CALL stopAnimation() when you're disposing this...
158: */
159: public void startAnimation() {
160: if (animator == null) {
161: animator = new Animator();
162: animator.setPriority(Thread.MIN_PRIORITY);
163: animator.start();
164: }
165: }
166:
167: public void stopAnimation() {
168: if (animator != null) {
169: animator.stop = true;
170: animator = null;
171: }
172: }
173:
174: class Animator extends Thread {
175: public boolean stop;
176:
177: @Override
178: public void run() {
179: while (!stop) {
180: try {
181: Thread.sleep(150);
182: } catch (Exception e) {
183: }
184:
185: EventQueue.invokeLater(new Runnable() {
186: public void run() {
187: letSnowFall();
188: repaint();
189: }
190: });
191: }
192: }
193: }
194:
195: public static Color createSmallLighterOrDarkerColor(Color bgColor) {
196: int r = bgColor.getRed();
197: int g = bgColor.getGreen();
198: int b = bgColor.getBlue();
199:
200: if (r > 245 && g > 245 && b > 245) {
201: r -= 20;
202: g -= 20;
203: b -= 15; // keep blue
204: } else {
205: r += 15;
206: g += 15;
207: b += 20; // give blue
208: }
209: if (r > 255)
210: r = 255;
211: if (g > 255)
212: g = 255;
213: if (b > 255)
214: b = 255;
215:
216: if (r < 0)
217: r = 0;
218: if (g < 0)
219: g = 0;
220: if (b < 0)
221: b = 0;
222:
223: return new Color(r, g, b);
224: }
225:
226: public static Color createMediumLighterOrDarkerColor(Color bgColor) {
227: int r = bgColor.getRed();
228: int g = bgColor.getGreen();
229: int b = bgColor.getBlue();
230:
231: if (r > 225 && g > 225 && b > 225) {
232: r -= 50;
233: g -= 50;
234: b -= 25; // keep blue
235: } else {
236: r += 50;
237: g += 50;
238: b += 25; // give blue
239: }
240: if (r > 255)
241: r = 255;
242: if (g > 255)
243: g = 255;
244: if (b > 255)
245: b = 255;
246:
247: if (r < 0)
248: r = 0;
249: if (g < 0)
250: g = 0;
251: if (b < 0)
252: b = 0;
253:
254: return new Color(r, g, b);
255: }
256:
257: /*test
258: public static void main(String[] aa)
259: {
260: JFrame frame = new JFrame();
261: frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
262: frame.setLayout(new BorderLayout());
263: SnowBackgroundPanel snowBack = new SnowBackgroundPanel();
264: frame.add(snowBack, BorderLayout.CENTER);
265: frame.setSize(200,200);
266: frame.setVisible(true);
267:
268: snowBack.startAnimation();
269:
270: }*/
271:
272: }
|