View Javadoc

1   /*
2    * Copyright (c) 2003-2008 by Cosylab d. d.
3    *
4    * This file is part of CosyBeans-Common.
5    *
6    * CosyBeans-Common is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation, either version 3 of the License, or
9    * (at your option) any later version.
10   *
11   * CosyBeans-Common is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with CosyBeans-Common.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  package com.cosylab.gui.components;
21  
22  import com.cosylab.gui.components.util.ColorHelper;
23  import com.cosylab.gui.components.util.CosyUIElements;
24  
25  import java.awt.Color;
26  import java.awt.Container;
27  import java.awt.Graphics;
28  import java.awt.GridLayout;
29  import java.awt.event.ActionEvent;
30  import java.awt.event.ActionListener;
31  import java.awt.event.KeyAdapter;
32  import java.awt.event.KeyEvent;
33  import java.awt.event.MouseAdapter;
34  import java.awt.event.MouseEvent;
35  import java.awt.event.MouseListener;
36  import java.awt.event.WindowAdapter;
37  import java.awt.event.WindowEvent;
38  
39  import java.util.Timer;
40  import java.util.TimerTask;
41  
42  import javax.swing.Icon;
43  import javax.swing.JApplet;
44  import javax.swing.JFrame;
45  import javax.swing.JLabel;
46  import javax.swing.JPanel;
47  import javax.swing.SwingUtilities;
48  import javax.swing.border.Border;
49  import javax.swing.event.EventListenerList;
50  import javax.swing.plaf.metal.MetalBorders;
51  
52  
53  /**
54   * A very simple implementation of a button. It supports three action modes
55   * identified by:
56   * <ul> 
57   * <li><code>FAST_ACTION_MODE</code> - the button fires one event when
58   * the user clicks (presses and releases) the left mouse button inside the
59   * area of the button. </li>
60   * <li><code>CHAIN_ACTION_MODE</code> - the button fires one event
61   * when the user presses the left mouse button inside the area of the
62   * button and continues firing events at a constant rate until the user
63   * releases the button or moves outside the button area.</li> 
64   * <li><code>NULL_ACTION_MODE</code> - the button fires no events at all.
65   * </li></ul>
66   *
67   * @author <a href="mailto:jernej.kamenik@cosylab.com">Jernej Kamenik</a>
68   * @version $id$
69   *
70   * @see com.cosylab.gui.components.GradientLabel
71   */
72  public class SimpleButton extends GradientLabel
73  {
74  	private static final long serialVersionUID = 1L;
75  	private static Timer actionTimer = null;
76  	protected static final String MOUSE_PRESSED = new String("mousePressed");
77  	protected static final String MOUSE_CLICKED = new String("mouseClicked");
78  	protected static final String MOUSE_RELEASED = new String("mouseReleased");
79  	protected static final String MOUSE_CHAIN = new String("mouseChain");
80  
81  	/** No events are fired. */
82  	public static final int NULL_ACTION_MODE = 0;
83  
84  	/** One event is fired for one click. */
85  	public static final int DEFAULT_ACTION_MODE = 1;
86  
87  	/** Events are fired continuously until mouse button is released. */
88  	public static final int CHAIN_ACTION_MODE = 2;
89  
90  	/** One event is fired for one click. */
91  	public static final int FAST_ACTION_MODE = 3;
92  	private boolean pressed;
93  	private boolean rollover;
94  	private boolean rolloverEnabled;
95  	private EventListenerList listenerList = null;
96  	private int fireRate;
97  	private int actionMode;
98  	private MouseListener mouseListener = null;
99  	private boolean painting;
100 	private Color pressedBackground;
101 	private Color pressedForeground;
102 	private Color pressedBackgroundStart;
103 	private Color rolloverBackground;
104 	private Color rolloverForeground;
105 	private Color rolloverBackgroundStart;
106 	private Color background;
107 	private Color foreground;
108 	private Color backgroundStart;
109 	private Border pressedBorder;
110 	private Border border;
111 	private Border rolloverBorder;
112 
113 	/**
114 	 * Creates a simple button with text.
115 	 *
116 	 * @param text java.lang.String to be displayed on the button.
117 	 */
118 	public SimpleButton(String text)
119 	{
120 		super(text);
121 		init();
122 	}
123 
124 	/**
125 	 * Creates a simple button with Icon.
126 	 *
127 	 * @param icon javax.swing.Icon to be displayed on the button.
128 	 */
129 	public SimpleButton(Icon icon)
130 	{
131 		super(icon);
132 		init();
133 	}
134 
135 	/**
136 	 * Creates a simple button without text .
137 	 */
138 	public SimpleButton()
139 	{
140 		this("");
141 	}
142 
143 	private void init()
144 	{
145 		listenerList = new EventListenerList();
146 		addMouseListener(new DisplayMouseListener());
147 		addKeyListener(new SimpleKeyListener());
148 		setActionMode(DEFAULT_ACTION_MODE);
149 		background = ColorHelper.getControl();
150 		foreground = ColorHelper.getControlText();
151 		backgroundStart = ColorHelper.getControlShadow();
152 		border = new MetalBorders.Flush3DBorder();
153 		rolloverBackground = ColorHelper.getControl();
154 		rolloverForeground = ColorHelper.getControlText();
155 		rolloverBackgroundStart = ColorHelper.getControlShadow();
156 		rolloverBorder = new MetalBorders.Flush3DBorder();
157 		pressedBackground = ColorHelper.getControlShadow();
158 		pressedForeground = ColorHelper.getControlText();
159 		pressedBackgroundStart = ColorHelper.getControlDarkShadow();
160 		pressedBorder = CosyUIElements.getPlainBorder(false);
161 		fireRate = 20;
162 
163 		setHorizontalAlignment(JLabel.CENTER);
164 		setHorizontalTextPosition(JLabel.CENTER);
165 		setVerticalAlignment(JLabel.CENTER);
166 		setVerticalTextPosition(JLabel.CENTER);
167 		setGradientEnabled(false);
168 		setFocusable(true);
169 		setEnabled(true);
170 		setOpaque(true);
171 		setVisible(true);
172 		setRequestFocusEnabled(true);
173 	}
174 
175 	/**
176 	 * Sets the action mode of the SimpleButton. DEFAULT_ACTION_MODE fires
177 	 * ActionEvent when left mouse button is clicked. CHAIN_ACTION_MODE fires
178 	 * a series of ActionEvent while left mouse button is being pressed at the
179 	 * <code>fireRate</code>. FAST_ACTION_MODE fires ActionEvent when left
180 	 * mouse button is pressed. NULL_ACTION_MODE fires no ActionEvents on
181 	 * mouse actions but pressing the ENTER key still triggers ActionEvents.
182 	 *
183 	 * @param newMode to be set.
184 	 *
185 	 * @throws IllegalArgumentException if the value entered is not one of
186 	 *         DEFAULT_ACTION_MODE, CHAIN_ACTION_MODE, FAST_ACTION_MODE or
187 	 *         NULL_ACTION_MODE.
188 	 */
189 	public void setActionMode(int newMode)
190 	{
191 		if (newMode == actionMode) {
192 			return;
193 		}
194 
195 		if (mouseListener != null) {
196 			removeMouseListener(mouseListener);
197 		}
198 
199 		int oldMode = actionMode;
200 
201 		switch (newMode) {
202 		case DEFAULT_ACTION_MODE:
203 			mouseListener = new DefaultMouseListener();
204 
205 			break;
206 
207 		case CHAIN_ACTION_MODE:
208 			mouseListener = new ChainMouseListener();
209 
210 			break;
211 
212 		case FAST_ACTION_MODE:
213 			mouseListener = new FastMouseListener();
214 
215 			break;
216 
217 		case NULL_ACTION_MODE:
218 			mouseListener = null;
219 
220 			break;
221 
222 		default:
223 			throw new IllegalArgumentException("actionMode");
224 		}
225 
226 		if (mouseListener != null) {
227 			addMouseListener(mouseListener);
228 		}
229 
230 		actionMode = newMode;
231 		firePropertyChange("actionMode", oldMode, newMode);
232 	}
233 
234 	/**
235 	 * Returns the currently set action mode.
236 	 *
237 	 * @return int used action mode.
238 	 */
239 	public int getActionMode()
240 	{
241 		if (mouseListener == null) {
242 			return NULL_ACTION_MODE;
243 		}
244 
245 		if (mouseListener.getClass() == DefaultMouseListener.class) {
246 			return DEFAULT_ACTION_MODE;
247 		}
248 
249 		if (mouseListener.getClass() == ChainMouseListener.class) {
250 			return CHAIN_ACTION_MODE;
251 		}
252 
253 		if (mouseListener.getClass() == FastMouseListener.class) {
254 			return FAST_ACTION_MODE;
255 		}
256 
257 		return NULL_ACTION_MODE;
258 	}
259 
260 	/*
261 	 * (non-Javadoc)
262 	 * @see com.cosylab.gui.components.GradientLabel#setBackground(java.awt.Color)
263 	 */
264 	public void setBackground(Color newColor)
265 	{
266 		if (newColor == background) {
267 			return;
268 		}
269 
270 		super.setBackground(newColor);
271 		background = newColor;
272 	}
273 
274 	/*
275 	 * (non-Javadoc)
276 	 * @see java.awt.Component#getBackground()
277 	 */
278 	public Color getBackground()
279 	{
280 		if (painting && pressed) {
281 			return pressedBackground;
282 		} else if (painting && rollover) {
283 			return rolloverBackground;
284 		} else {
285 			return background;
286 		}
287 	}
288 
289 	/*
290 	 * (non-Javadoc)
291 	 * @see javax.swing.JComponent#setForeground(java.awt.Color)
292 	 */
293 	public void setForeground(Color newColor)
294 	{
295 		if (foreground == newColor) {
296 			return;
297 		}
298 
299 		super.setForeground(newColor);
300 		foreground = newColor;
301 	}
302 
303 	/*
304 	 * (non-Javadoc)
305 	 * @see java.awt.Component#getForeground()
306 	 */
307 	public Color getForeground()
308 	{
309 		if (painting && pressed) {
310 			return pressedForeground;
311 		} else if (painting && rollover) {
312 			return rolloverForeground;
313 		} else {
314 			return foreground;
315 		}
316 	}
317 
318 	/*
319 	 * (non-Javadoc)
320 	 * @see com.cosylab.gui.components.GradientLabel#getBackgroundStart()
321 	 */
322 	public Color getBackgroundStart()
323 	{
324 		if (painting && pressed) {
325 			return pressedBackgroundStart;
326 		} else if (painting && rollover) {
327 			return rolloverBackgroundStart;
328 		} else {
329 			return backgroundStart;
330 		}
331 	}
332 
333 	/*
334 	 * (non-Javadoc)
335 	 * @see com.cosylab.gui.components.GradientLabel#setBackgroundStart(java.awt.Color)
336 	 */
337 	public void setBackgroundStart(Color newColor)
338 	{
339 		if (backgroundStart == newColor) {
340 			return;
341 		}
342 
343 		super.setBackgroundStart(newColor);
344 		backgroundStart = newColor;
345 	}
346 
347 	/*
348 	 * (non-Javadoc)
349 	 * @see javax.swing.JComponent#setBorder(javax.swing.border.Border)
350 	 */
351 	public void setBorder(Border newBorder)
352 	{
353 		if (border == newBorder) {
354 			return;
355 		}
356 
357 		super.setBorder(newBorder);
358 		border = newBorder;
359 	}
360 
361 	/*
362 	 * (non-Javadoc)
363 	 * @see javax.swing.JComponent#getBorder()
364 	 */
365 	public Border getBorder()
366 	{
367 		if (painting && pressed) {
368 			return pressedBorder;
369 		} else if (painting && rollover) {
370 			return rolloverBorder;
371 		} else {
372 			return border;
373 		}
374 	}
375 
376 	/**
377 	 * Returns the background color displayed when the button  is pressed.
378 	 *
379 	 * @return Color
380 	 */
381 	public Color getPressedBackground()
382 	{
383 		return pressedBackground;
384 	}
385 
386 	/**
387 	 * Sets the background color displayed when the button  is pressed.
388 	 *
389 	 * @param newColor Color
390 	 */
391 	public void setPressedBackground(Color newColor)
392 	{
393 		Color oldColor = pressedBackground;
394 
395 		if (oldColor == newColor) {
396 			return;
397 		}
398 
399 		pressedBackground = newColor;
400 		firePropertyChange("pressedBackground", oldColor, newColor);
401 		repaint();
402 	}
403 
404 	/**
405 	 * Returns the foreground color displayed when the button  is pressed.
406 	 *
407 	 * @return Color
408 	 */
409 	public Color getPressedForeground()
410 	{
411 		return pressedForeground;
412 	}
413 
414 	/**
415 	 * Sets the foreground color displayed when the button  is pressed.
416 	 *
417 	 * @param newColor Color
418 	 */
419 	public void setPressedForeground(Color newColor)
420 	{
421 		Color oldColor = pressedForeground;
422 
423 		if (oldColor == newColor) {
424 			return;
425 		}
426 
427 		pressedForeground = newColor;
428 		firePropertyChange("pressedForeground", oldColor, newColor);
429 		repaint();
430 	}
431 
432 	/**
433 	 * Returns the starting background gradient color displayed  when the button
434 	 * is pressed.
435 	 *
436 	 * @return Color
437 	 */
438 	public Color getPressedBackgroundStart()
439 	{
440 		return pressedBackgroundStart;
441 	}
442 
443 	/**
444 	 * Sets the starting background gradient color displayed  when the button
445 	 * is pressed.
446 	 *
447 	 * @param newColor Color
448 	 */
449 	public void setPressedBackgroundStart(Color newColor)
450 	{
451 		Color oldColor = pressedBackgroundStart;
452 
453 		if (oldColor == newColor) {
454 			return;
455 		}
456 
457 		pressedBackgroundStart = newColor;
458 		firePropertyChange("pressedBackgroundStart", oldColor, newColor);
459 		repaint();
460 	}
461 
462 	/**
463 	 * Returns the border displayed when the button is pressed.
464 	 *
465 	 * @return Border
466 	 */
467 	public Border getPressedBorder()
468 	{
469 		return pressedBorder;
470 	}
471 
472 	/**
473 	 * Sets the border displayed when the button is pressed.
474 	 *
475 	 * @param newBorder Border
476 	 */
477 	public void setPressedBorder(Border newBorder)
478 	{
479 		Border oldBorder = pressedBorder;
480 
481 		if (oldBorder == newBorder) {
482 			return;
483 		}
484 
485 		pressedBorder = newBorder;
486 		firePropertyChange("pressedBorder", oldBorder, newBorder);
487 		repaint();
488 	}
489 
490 	/**
491 	 * Returns the background color displayed when the mouse  cursor is over the
492 	 * button and rollover is enabled.
493 	 *
494 	 * @return Color
495 	 */
496 	public Color getRolloverBackground()
497 	{
498 		return rolloverBackground;
499 	}
500 
501 	/**
502 	 * Sets the background color displayed when the mouse  cursor is over the
503 	 * button and rollover is enabled.
504 	 *
505 	 * @param newColor Color
506 	 */
507 	public void setRolloverBackground(Color newColor)
508 	{
509 		Color oldColor = rolloverBackground;
510 
511 		if (oldColor == newColor) {
512 			return;
513 		}
514 
515 		rolloverBackground = newColor;
516 		firePropertyChange("rolloverBackground", oldColor, newColor);
517 		repaint();
518 	}
519 
520 	/**
521 	 * Returns the foreground color displayed when the mouse  cursor is over the
522 	 * button and rollover is enabled.
523 	 *
524 	 * @return Color
525 	 */
526 	public Color getRolloverForeground()
527 	{
528 		return rolloverForeground;
529 	}
530 
531 	/**
532 	 * Sets the foreground color displayed when the mouse  cursor is over the
533 	 * button and rollover is enabled.
534 	 *
535 	 * @param newColor Color
536 	 */
537 	public void setRolloverForeground(Color newColor)
538 	{
539 		Color oldColor = rolloverForeground;
540 
541 		if (oldColor == newColor) {
542 			return;
543 		}
544 
545 		rolloverForeground = newColor;
546 		firePropertyChange("rolloverForeground", oldColor, newColor);
547 		repaint();
548 	}
549 
550 	/**
551 	 * Returns the start of background gradient color displayed  when the mouse
552 	 * cursor is over the button and rollover is enabled.
553 	 *
554 	 * @return Color
555 	 */
556 	public Color getRolloverBackgroundStart()
557 	{
558 		return rolloverBackgroundStart;
559 	}
560 
561 	/**
562 	 * Sets the start of background gradient color displayed  when the mouse
563 	 * cursor is over the button and rollover is enabled.
564 	 *
565 	 * @param newColor Color
566 	 */
567 	public void setRolloverBackgroundStart(Color newColor)
568 	{
569 		Color oldColor = rolloverBackgroundStart;
570 
571 		if (oldColor == newColor) {
572 			return;
573 		}
574 
575 		rolloverBackgroundStart = newColor;
576 		firePropertyChange("rolloverBackgroundStart", oldColor, newColor);
577 		repaint();
578 	}
579 
580 	/**
581 	 * Returns the border displayed when the mouse cursor is over the  button and
582 	 * rollover is enabled.
583 	 *
584 	 * @return Border
585 	 */
586 	public Border getRolloverBorder()
587 	{
588 		return rolloverBorder;
589 	}
590 
591 	/**
592 	 * Sets the border displayed when the mouse cursor is over the  button and
593 	 * rollover is enabled.
594 	 *
595 	 * @param newBorder Border
596 	 */
597 	public void setRolloverBorder(Border newBorder)
598 	{
599 		Border oldBorder = rolloverBorder;
600 
601 		if (oldBorder == newBorder) {
602 			return;
603 		}
604 
605 		rolloverBorder = newBorder;
606 		firePropertyChange("rolloverBorder", oldBorder, newBorder);
607 		repaint();
608 	}
609 
610 	/**
611 	 * Enables or disables visual indication when mouse is over this
612 	 * SimpleButton.
613 	 *
614 	 * @param enabled boolean whether this SimpleButton should indicate when
615 	 *        mouse is over it.
616 	 */
617 	public void setRolloverEnabled(boolean enabled)
618 	{
619 		boolean oldEnabled = rolloverEnabled;
620 
621 		if (oldEnabled == enabled) {
622 			return;
623 		}
624 
625 		rolloverEnabled = enabled;
626 		firePropertyChange("rolloverEnabled", oldEnabled, enabled);
627 
628 		if (rollover && !enabled) {
629 			rollover = false;
630 			repaint();
631 		}
632 	}
633 
634 	/**
635 	 * Returns wether this SimpleButton visually indicates when mouse is over
636 	 * it.
637 	 *
638 	 * @return boolean true if rollover indication is enabled, false otherwise.
639 	 */
640 	public boolean isRolloverEnabled()
641 	{
642 		return rolloverEnabled;
643 	}
644 
645 	/**
646 	 * Sets the rate of event firing in the CHAIN_MODE
647 	 *
648 	 * @param newRate int time in miliseconds between successive events are
649 	 *        fired.
650 	 */
651 	public void setFireRate(int newRate)
652 	{
653 		int oldRate = fireRate;
654 
655 		if (oldRate == newRate) {
656 			return;
657 		}
658 
659 		fireRate = newRate;
660 		firePropertyChange("fireRate", oldRate, newRate);
661 	}
662 
663 	/**
664 	 * Gets the rate of event firing in the CHAIN_MODE
665 	 *
666 	 * @return int
667 	 */
668 	public int getFireRate()
669 	{
670 		return fireRate;
671 	}
672 
673 	/**
674 	 * Gets the property specifiing whether the button is being pressed.
675 	 *
676 	 * @return boolean
677 	 */
678 	public boolean isPressed()
679 	{
680 		return pressed;
681 	}
682 
683 	/**
684 	 * Returns the property specifiing whether the button is being pressed.
685 	 *
686 	 * @param newPressed boolean
687 	 */
688 	protected void setPressed(boolean newPressed)
689 	{
690 		boolean oldPressed = pressed;
691 
692 		if (oldPressed == newPressed) {
693 			return;
694 		}
695 
696 		pressed = newPressed;
697 		firePropertyChange("pressed", oldPressed, newPressed);
698 
699 		if (pressed) {
700 			requestFocus();
701 		}
702 
703 		revalidate();
704 		repaint();
705 	}
706 
707 	/**
708 	 * Gets the property specifiing whether the mouse is being moved over the
709 	 * button.
710 	 *
711 	 * @return boolean
712 	 */
713 	public boolean isRollover()
714 	{
715 		return rollover;
716 	}
717 
718 	/**
719 	 * Sets the property specifiing whether the mouse is being moved over the
720 	 * button.
721 	 *
722 	 * @param newRollover boolean
723 	 */
724 	protected void setRollover(boolean newRollover)
725 	{
726 		if (rolloverEnabled) {
727 			boolean oldRollover = rollover;
728 
729 			if (oldRollover == newRollover) {
730 				return;
731 			}
732 
733 			rollover = newRollover;
734 			firePropertyChange("rollover", oldRollover, newRollover);
735 			revalidate();
736 			repaint();
737 		}
738 	}
739 
740 	/**
741 	 * Fires an action event to all its listeners
742 	 *
743 	 * @param e ActionEvent
744 	 */
745 	protected void fireActionPerformed(ActionEvent e)
746 	{
747 		Object[] listeners = listenerList.getListenerList();
748 
749 		for (int i = listeners.length - 2; i >= 0; i -= 2) {
750 			if (listeners[i] == ActionListener.class) {
751 				((ActionListener)listeners[i + 1]).actionPerformed(e);
752 			}
753 		}
754 	}
755 
756 	/**
757 	 * Adds an action listener to the list of registered  listeners for this
758 	 * button.
759 	 *
760 	 * @param l ActionListener
761 	 */
762 	public void addActionListener(ActionListener l)
763 	{
764 		listenerList.add(ActionListener.class, l);
765 	}
766 
767 	/**
768 	 * Removes an action listener from the list of registered  listeners for
769 	 * this button.
770 	 *
771 	 * @param l ActionListener
772 	 */
773 	public void removeActionListener(ActionListener l)
774 	{
775 		listenerList.remove(ActionListener.class, l);
776 	}
777 
778 	/**
779 	 * This method was overloaded to enable advanced  graphical features of the
780 	 * SimpleButton
781 	 *
782 	 * @param g Graphics
783 	 *
784 	 * @see com.cosylab.gui.components.GradientLabel#paintComponent(Graphics)
785 	 */
786 	public void paintComponent(Graphics g)
787 	{
788 		painting = true;
789 		super.paintComponent(g);
790 		painting = false;
791 	}
792 
793 	/**
794 	 * This method was overloaded to enable advanced  graphical features of the
795 	 * SimpleButton
796 	 *
797 	 * @param g Graphics
798 	 *
799 	 * @see javax.swing.JComponent#paintBorder(Graphics)
800 	 */
801 	protected void paintBorder(Graphics g)
802 	{
803 		painting = true;
804 		super.paintBorder(g);
805 		painting = false;
806 	}
807 	
808 	/*
809 	 * (non-Javadoc)
810 	 * @see com.cosylab.gui.components.ResizableTextLabel#addNotify()
811 	 */
812 	public void addNotify()
813 	{
814 		setRollover(false);
815 		setPressed(false);
816 		super.addNotify();
817 	}
818 
819 	/*
820 	 * (non-Javadoc)
821 	 * @see javax.swing.JComponent#removeNotify()
822 	 */
823 	public void removeNotify()
824 	{
825 		setRollover(false);
826 		setPressed(false);
827 		super.removeNotify();
828 	}
829 
830 	/*
831 	 * (non-Javadoc)
832 	 * @see javax.swing.JComponent#setVisible(boolean)
833 	 */
834 	public void setVisible(boolean visible)
835 	{
836 		if (isVisible() != visible) {
837 			setRollover(false);
838 			setPressed(false);
839 			super.setVisible(visible);
840 		}
841 	}
842 
843 
844 	/*
845 	 *
846 	 * @author jkamenik
847 	 *
848 	 *        Listens for key events, updates this SimpleButton and fires ActionEvents when
849 	 * ENTER is pressed.
850 	 */
851 	private class SimpleKeyListener extends KeyAdapter
852 	{
853 		/**
854 		 * Updates this SimpleButton and fires ActionPerformed event when ENTER
855 		 * is pressed.
856 		 *
857 		 * @param e KeyEvent
858 		 *
859 		 * @see java.awt.event.KeyListener#keyPressed(KeyEvent)
860 		 */
861 		public void keyPressed(KeyEvent e)
862 		{
863 			//Debug.out("keypressed");
864 			if (e.getKeyCode() == KeyEvent.VK_ENTER) {
865 				if (!pressed) {
866 					setPressed(true);
867 				}
868 
869 				fireActionPerformed(new ActionEvent(SimpleButton.this,
870 				        ActionEvent.ACTION_PERFORMED, MOUSE_PRESSED));
871 			}
872 		}
873 	}
874 
875 	/*
876 	 *
877 	 * @author jkamenik
878 	 *
879 	 *        Listens for MouseEvents and updates the visualization of this SimpleButton.
880 	 */
881 	private class DisplayMouseListener extends MouseAdapter
882 	{
883 		/**
884 		 * Updates the visualisation of this SimpleButton when left mouse
885 		 * button is pressed.
886 		 *
887 		 * @param e MouseEvent
888 		 *
889 		 * @see java.awt.event.MouseListener#mousePressed(MouseEvent)
890 		 */
891 		public void mousePressed(MouseEvent e)
892 		{
893 			if (SwingUtilities.isLeftMouseButton(e) && isEnabled()) {
894 				setPressed(true);
895 			}
896 		}
897 
898 		/**
899 		 * Updates the visualisation of this SimpleButton when mouse button is
900 		 * released.
901 		 *
902 		 * @param e MouseEvent
903 		 *
904 		 * @see java.awt.event.MouseListener#mouseReleased(MouseEvent)
905 		 */
906 		public void mouseReleased(MouseEvent e)
907 		{
908 			if (isPressed()) {
909 				setPressed(false);
910 			}
911 		}
912 
913 		/**
914 		 * Updates the visualisation of this SimpleButton when mouse enters.
915 		 *
916 		 * @param e MouseEvent
917 		 *
918 		 * @see java.awt.event.MouseListener#mouseEntered(MouseEvent)
919 		 */
920 		public void mouseEntered(MouseEvent e)
921 		{
922 			if (isEnabled()) {
923 				setRollover(true);
924 			}
925 		}
926 
927 		/**
928 		 * Updates the visualisation of this SimpleButton when mouse exits.
929 		 *
930 		 * @param e MouseEvent
931 		 *
932 		 * @see java.awt.event.MouseListener#mouseExited(MouseEvent)
933 		 */
934 		public void mouseExited(MouseEvent e)
935 		{
936 			if (isPressed()) {
937 				setPressed(false);
938 			}
939 
940 			if (isRollover()) {
941 				setRollover(false);
942 			}
943 		}
944 	}
945 
946 	/*
947 	 *
948 	 * @author jkamenik
949 	 *
950 	 * Listens for mouse events and fires ActionEvents when mouse is clicked.
951 	 */
952 	private class DefaultMouseListener extends MouseAdapter
953 	{
954 		/**
955 		 * Fires ActionEvents when left mouse button is clicked.
956 		 *
957 		 * @param e MouseEvent
958 		 *
959 		 * @see java.awt.event.MouseListener#mouseClicked(MouseEvent)
960 		 */
961 		public void mouseClicked(MouseEvent e)
962 		{
963 			if (!isEnabled()) {
964 				return;
965 			}
966 
967 			if (SwingUtilities.isLeftMouseButton(e)) {
968 				fireActionPerformed(new ActionEvent(SimpleButton.this,
969 				        ActionEvent.ACTION_PERFORMED, MOUSE_CLICKED));
970 			}
971 		}
972 	}
973 
974 	/*
975 	 *
976 	 * @author jkamenik
977 	 *
978 	 * Listens for mouse events and fires a series of ActionEvents while mouse is pressed.
979 	 */
980 	private class ChainMouseListener extends MouseAdapter
981 	{
982 		/**
983 		 * Starts firing EctionEvents when left mouse button is pressed.
984 		 *
985 		 * @param e MouseEvent
986 		 *
987 		 * @see java.awt.event.MouseListener#mousePressed(MouseEvent)
988 		 */
989 		public void mousePressed(MouseEvent e)
990 		{
991 			if (!isEnabled()) {
992 				return;
993 			}
994 
995 			if (SwingUtilities.isLeftMouseButton(e)) {
996 				fireActionPerformed(new ActionEvent(SimpleButton.this,
997 				        ActionEvent.ACTION_PERFORMED, MOUSE_PRESSED));
998 				actionTimer = new Timer();
999 				actionTimer.schedule(new TimerTask() {
1000 						public void run()
1001 						{
1002 							fireActionPerformed(new ActionEvent(
1003 							        SimpleButton.this,
1004 							        ActionEvent.ACTION_PERFORMED, MOUSE_CHAIN));
1005 						}
1006 					}, 500, fireRate);
1007 			}
1008 		}
1009 
1010 		/**
1011 		 * Stops firing ActionEvents when mouseButton is released.
1012 		 *
1013 		 * @param e MouseEvent
1014 		 *
1015 		 * @see java.awt.event.MouseListener#mouseReleased(MouseEvent)
1016 		 */
1017 		public void mouseReleased(MouseEvent e)
1018 		{
1019 			if (actionTimer != null) {
1020 				actionTimer.cancel();
1021 				actionTimer = null;
1022 			}
1023 		}
1024 
1025 		/**
1026 		 * Stops firing ActionEvents when mouse exits.
1027 		 *
1028 		 * @param e MouseEvent
1029 		 *
1030 		 * @see java.awt.event.MouseListener#mouseExited(MouseEvent)
1031 		 */
1032 		public void mouseExited(MouseEvent e)
1033 		{
1034 			if (actionTimer != null) {
1035 				actionTimer.cancel();
1036 				actionTimer = null;
1037 			}
1038 		}
1039 	}
1040 
1041 	/*
1042 	 *
1043 	 * @author jkamenik
1044 	 *
1045 	 * Listens for mouse events and fires ActionEvents when mouse is pressed.
1046 	 */
1047 	private class FastMouseListener extends MouseAdapter
1048 	{
1049 		/**
1050 		 * Fires an ActionEvent when left mouse button is pressed.
1051 		 *
1052 		 * @param e MouseEvent
1053 		 *
1054 		 * @see java.awt.event.MouseListener#mouseClicked(MouseEvent)
1055 		 */
1056 		public void mousePressed(MouseEvent e)
1057 		{
1058 			if (!isEnabled()) {
1059 				return;
1060 			}
1061 
1062 			if (SwingUtilities.isLeftMouseButton(e)) {
1063 				fireActionPerformed(new ActionEvent(SimpleButton.this,
1064 				        ActionEvent.ACTION_PERFORMED, MOUSE_PRESSED));
1065 			}
1066 		}
1067 	}
1068 	
1069 	/**
1070 	 * Run test applet.
1071 	 *
1072 	 * @param args command line parameters
1073 	 */
1074 	public static void main(String[] args)
1075 	{
1076 		JApplet applet = new JApplet() {
1077 			private static final long serialVersionUID = 1L;
1078 
1079 				public void init()
1080 				{
1081 					Container cp = this.getContentPane();
1082 					JPanel panel = new JPanel();
1083 					SimpleButton button = new SimpleButton("SimpleButton");
1084 					button.setGradientEnabled(true);
1085 					button.setBorder(null);
1086 					button.setEnabled(true);
1087 					button.setRolloverEnabled(true);
1088 					button.setRolloverBorder(CosyUIElements.getPlainBorder(true));
1089 					button.setPressedBorder(CosyUIElements.getPlainBorder(false));
1090 					panel.setLayout(new GridLayout(1, 0));
1091 					panel.add(button);
1092 					cp.add(panel);
1093 				}
1094 			};
1095 
1096 		JFrame frame = new JFrame("Arrow Button Demo");
1097 		frame.getContentPane().add(applet);
1098 		frame.setSize(300, 400);
1099 		frame.addWindowListener(new WindowAdapter() {
1100 				public void windowClosing(WindowEvent e)
1101 				{
1102 					System.exit(0);
1103 				}
1104 			});
1105 		applet.init();
1106 		applet.start();
1107 		frame.setVisible(true);
1108 	}
1109 }
1110 
1111 /* __oOo__ */