001: package org.acm.seguin.pmd.swingui;
002:
003: import org.acm.seguin.pmd.swingui.event.ListenerList;
004: import org.acm.seguin.pmd.swingui.event.StatusBarEvent;
005: import org.acm.seguin.pmd.swingui.event.StatusBarEventListener;
006:
007: import javax.swing.JLabel;
008: import javax.swing.JPanel;
009: import javax.swing.SwingUtilities;
010: import javax.swing.UIManager;
011: import javax.swing.border.BevelBorder;
012: import javax.swing.border.EmptyBorder;
013: import java.awt.BorderLayout;
014: import java.awt.Color;
015: import java.awt.Component;
016: import java.awt.Dimension;
017: import java.awt.Font;
018: import java.awt.Graphics;
019: import java.awt.Insets;
020: import java.awt.Rectangle;
021:
022: /**
023: *
024: * @author Donald A. Leckie
025: * @since January 6, 2003
026: * @version $Revision: 1.1 $, $Date: 2003/07/29 20:51:59 $
027: */
028: class StatusBar extends JPanel {
029: private JLabel m_message;
030: private String m_defaultMessage;
031: private StatusArea m_statusArea;
032:
033: /**
034: ****************************************************************************
035: *
036: * @param border
037: */
038: protected StatusBar(String defaultMessage) {
039: super (new BorderLayout());
040:
041: m_defaultMessage = defaultMessage;
042:
043: //
044: // Status Indicator
045: //
046: m_statusArea = new StatusArea();
047: add(m_statusArea, BorderLayout.WEST);
048:
049: //
050: // Message
051: //
052: m_message = new JLabel();
053: m_message.setFont(new Font("Dialog", Font.BOLD, 12));
054: m_message.setBackground(UIManager
055: .getColor("pmdMessageAreaBackground"));
056: m_message.setForeground(UIManager.getColor("pmdBlue"));
057: m_message.setBorder(new EmptyBorder(0, 5, 0, 0));
058: setDefaultMessage();
059: add(m_message, BorderLayout.CENTER);
060:
061: ListenerList
062: .addListener((StatusBarEventListener) new StatusBarEventHandler());
063: }
064:
065: /**
066: *********************************************************************************
067: *
068: */
069: protected void setDefaultMessage() {
070: setMessage(m_defaultMessage);
071: }
072:
073: /**
074: *********************************************************************************
075: *
076: * @param message The message to be displayed in the status area.
077: */
078: protected void setMessage(String message) {
079: if (message == null) {
080: message = "";
081: }
082:
083: m_message.setText(message);
084: }
085:
086: /**
087: *********************************************************************************
088: *********************************************************************************
089: *********************************************************************************
090: */
091: private class StatusArea extends JPanel {
092: private StatusActionThread m_actionThread;
093: private Color m_inactiveBackground;
094: private Color m_activeBackground;
095: private Color m_actionColor;
096: private int m_direction;
097: private int m_indicatorCurrentPosition;
098: private final int POSITION_INCREMENT = 5;
099: private final int START_MOVING = 0;
100: private final int MOVE_FORWARD = 1;
101: private final int MOVE_BACKWARD = 2;
102:
103: /**
104: ****************************************************************************
105: *
106: * @param border
107: */
108: private StatusArea() {
109: super (null);
110:
111: m_inactiveBackground = Color.gray;
112: m_activeBackground = UIManager
113: .getColor("pmdStatusAreaBackground");
114: m_actionColor = Color.red;
115:
116: setOpaque(true);
117: setBackground(m_inactiveBackground);
118: setBorder(new BevelBorder(BevelBorder.LOWERED));
119:
120: Dimension size = new Dimension(160, 12);
121:
122: setMinimumSize(size);
123: setMaximumSize(size);
124: setSize(size);
125: setPreferredSize(size);
126: }
127:
128: /**
129: ****************************************************************************
130: *
131: */
132: private void startAction() {
133: if (m_actionThread == null) {
134: setBackground(m_activeBackground);
135: m_direction = START_MOVING;
136: m_actionThread = new StatusActionThread(this );
137: m_actionThread.start();
138: }
139: }
140:
141: /**
142: ****************************************************************************
143: *
144: */
145: private void stopAction() {
146: if (m_actionThread != null) {
147: m_actionThread.stopAction();
148: m_actionThread = null;
149: setBackground(m_inactiveBackground);
150: repaint();
151: }
152: }
153:
154: /**
155: ****************************************************************************
156: *
157: * @param graphics
158: */
159: public void paint(Graphics graphics) {
160: super .paint(graphics);
161:
162: if (getBackground() == m_activeBackground) {
163: Rectangle totalArea;
164: Insets insets;
165: int indicatorWidth;
166: int indicatorHeight;
167: int indicatorY;
168: int indicatorX;
169: int totalAreaRight;
170:
171: totalArea = getBounds();
172: insets = getInsets();
173: totalArea.x += insets.left;
174: totalArea.y += insets.top;
175: totalArea.width -= (insets.left + insets.right);
176: totalArea.height -= (insets.top + insets.bottom);
177: totalAreaRight = totalArea.x + totalArea.width;
178: indicatorWidth = totalArea.width / 3;
179: indicatorHeight = totalArea.height;
180: indicatorY = totalArea.y;
181:
182: if (m_direction == MOVE_FORWARD) {
183: m_indicatorCurrentPosition += POSITION_INCREMENT;
184:
185: if (m_indicatorCurrentPosition >= totalAreaRight) {
186: m_indicatorCurrentPosition = totalAreaRight
187: - POSITION_INCREMENT;
188: m_direction = MOVE_BACKWARD;
189: }
190: } else if (m_direction == MOVE_BACKWARD) {
191: m_indicatorCurrentPosition -= POSITION_INCREMENT;
192:
193: if (m_indicatorCurrentPosition < totalArea.x) {
194: m_indicatorCurrentPosition = totalArea.x
195: + POSITION_INCREMENT;
196: m_direction = MOVE_FORWARD;
197: }
198: } else {
199: m_indicatorCurrentPosition = totalArea.x
200: + POSITION_INCREMENT;
201: m_direction = MOVE_FORWARD;
202: }
203:
204: indicatorX = m_indicatorCurrentPosition;
205:
206: Rectangle oldClip = graphics.getClipBounds();
207: Color oldColor = graphics.getColor();
208:
209: graphics.setColor(m_activeBackground);
210: graphics.setClip(totalArea.x, totalArea.y,
211: totalArea.width, totalArea.height);
212: graphics.clipRect(totalArea.x, totalArea.y,
213: totalArea.width, totalArea.height);
214: graphics.fillRect(totalArea.x, totalArea.y,
215: totalArea.width, totalArea.height);
216:
217: if (m_direction == MOVE_FORWARD) {
218: int stopX = indicatorX - indicatorWidth;
219:
220: if (stopX < totalArea.x) {
221: stopX = totalArea.x;
222: }
223:
224: int y1 = indicatorY;
225: int y2 = y1 + indicatorHeight;
226: Color color = m_actionColor;
227:
228: for (int x = indicatorX; x > stopX; x--) {
229: graphics.setColor(color);
230: graphics.drawLine(x, y1, x, y2);
231: color = brighter(color);
232: }
233: } else {
234: int stopX = indicatorX + indicatorWidth;
235:
236: if (stopX > totalAreaRight) {
237: stopX = totalAreaRight;
238: }
239:
240: int y1 = indicatorY;
241: int y2 = indicatorY + indicatorHeight;
242: Color color = m_actionColor;
243:
244: for (int x = indicatorX; x < stopX; x++) {
245: graphics.setColor(color);
246: graphics.drawLine(x, y1, x, y2);
247: color = brighter(color);
248: }
249: }
250:
251: graphics.setColor(oldColor);
252:
253: if (oldClip != null) {
254: graphics.clipRect(oldClip.x, oldClip.y,
255: oldClip.width, oldClip.height);
256: graphics.setClip(oldClip.x, oldClip.y,
257: oldClip.width, oldClip.height);
258: }
259: }
260: }
261:
262: /**
263: ****************************************************************************
264: *
265: * @param color
266: *
267: * @return
268: */
269: private Color brighter(Color color) {
270: int red;
271: int green;
272: int blue;
273:
274: red = color.getRed() + 5;
275: green = color.getGreen() + 5;
276: blue = color.getBlue() + 5;
277:
278: if (red > 255) {
279: red = 255;
280: }
281:
282: if (green > 255) {
283: green = 255;
284: }
285:
286: if (blue > 255) {
287: blue = 255;
288: }
289:
290: return new Color(red, green, blue);
291: }
292: }
293:
294: /**
295: *********************************************************************************
296: *********************************************************************************
297: *********************************************************************************
298: */
299: private class StatusActionThread extends Thread {
300: private StatusArea m_statusArea;
301: private boolean m_stopAction;
302: private int m_doNothing;
303: private final long ELAPSED_TIME = 25;
304:
305: /**
306: ****************************************************************************
307: *
308: * @param statusArea
309: */
310: private StatusActionThread(StatusArea statusArea) {
311: super ("Status Action");
312:
313: m_statusArea = statusArea;
314: }
315:
316: /**
317: ****************************************************************************
318: *
319: */
320: public void run() {
321: while (m_stopAction == false) {
322: m_statusArea.repaint();
323:
324: try {
325: sleep(ELAPSED_TIME);
326: } catch (InterruptedException exception) {
327: m_doNothing++;
328: }
329: }
330: }
331:
332: /**
333: ****************************************************************************
334: *
335: */
336: private void stopAction() {
337: m_stopAction = true;
338: }
339: }
340:
341: /**
342: *********************************************************************************
343: *********************************************************************************
344: *********************************************************************************
345: */
346: private class StatusBarEventHandler implements
347: StatusBarEventListener {
348:
349: /**
350: *****************************************************************************
351: *
352: * @param event
353: */
354: public void startAnimation(StatusBarEvent event) {
355: m_statusArea.startAction();
356: m_message.setText("");
357: SwingUtilities.invokeLater(new Repaint(m_message));
358: }
359:
360: /**
361: *****************************************************************************
362: *
363: * @param event
364: */
365: public void showMessage(StatusBarEvent event) {
366: m_message.setText(event.getMessage());
367: SwingUtilities.invokeLater(new Repaint(m_message));
368: }
369:
370: /**
371: *****************************************************************************
372: *
373: * @param event
374: */
375: public void stopAnimation(StatusBarEvent event) {
376: setDefaultMessage();
377: SwingUtilities.invokeLater(new Repaint(m_message));
378: m_statusArea.stopAction();
379: }
380: }
381:
382: /**
383: *********************************************************************************
384: *********************************************************************************
385: *********************************************************************************
386: */
387: private class Repaint implements Runnable {
388: private Component m_component;
389:
390: /**
391: *****************************************************************************
392: *
393: * @param component
394: */
395: private Repaint(Component component) {
396: m_component = component;
397: }
398:
399: /**
400: *****************************************************************************
401: *
402: */
403: public void run() {
404: m_component.repaint();
405: }
406: }
407: }
|