1
2
3
4
5 package spellcast.ui;
6
7 import java.awt.*;
8 import java.awt.event.*;
9 import java.util.*;
10 import javax.swing.*;
11 import spellcast.gestures.*;
12 import ui.*;
13
14 /***
15 * A button that displays a gesture and can select a new gesture.
16 * The button can display either an image or the name of the gesture as a string.
17 * The button will display the correct handedness for the image of the gesture selected.
18 * When the button is pressed a popup will appear displaying the eight possible gestures.
19 * The popup will only disappear when the mouse is released over one of the gestures.
20 * The button will fire a <code>gestureSelected</code> event when the gesture is selected
21 * and the button will change its display to the newly selected gesture.
22 * <p>
23 * The handedness of the button is specifed by either <code>GestureIcon.LEFT_HANDED</code>
24 * or <code>GestureIcon.RIGHT_HANDED</code>.
25 *
26 * @author Barrie Treloar
27 */
28 public class GestureButton extends JButton
29 {
30 private GesturePopupMenu popup;
31 private ArrayList listeners = new ArrayList( 1 );
32 private Gesture currentGesture;
33 private boolean useImages;
34 private int hand;
35
36 /***
37 * Create a GestureButton with the specified handedness and displaying images.
38 *
39 * @param hand the handedness of the button. Either <code>GestureIcon.LEFT_HANDED</code>
40 * or <code>GestureIcon.RIGHT_HANDED</code>
41 */
42 public GestureButton( int hand )
43 {
44 this( hand, true );
45 }
46
47 /***
48 * Create a GestureButton with the specified handedness and displaying images or
49 * text depending.
50 *
51 * @param hand the handedness of the button. Either <code>GestureIcon.LEFT_HANDED</code>
52 * or <code>GestureIcon.RIGHT_HANDED</code>
53 * @param useImages if true the display images, otherwise display text.
54 */
55 public GestureButton( int hand, boolean useImages )
56 {
57 this.useImages = useImages;
58 this.hand = hand;
59 setGesture( GestureFactory.instance().getEmptyHand() );
60
61 setBackground( Color.white );
62 setBorder( null );
63 setBorderPainted( false );
64 setFocusPainted( false );
65 addMouseListener( new GestureButtonListener() );
66
67 if ( hand == GestureIcon.LEFT_HANDED )
68 {
69 popup = new LeftHandedGesturePopupMenu();
70 }
71 else if ( hand == GestureIcon.RIGHT_HANDED )
72 {
73 popup = new RightHandedGesturePopupMenu();
74 }
75 else
76 {
77 throw new RuntimeException( "Invalid Handedness specified: " + hand );
78 }
79
80 popup.addGestureListener( new GestureListener()
81 {
82 public void gestureSelected( Gesture g )
83 {
84 ArrayList copy;
85 synchronized ( listeners )
86 {
87 copy = new ArrayList( listeners );
88 }
89 Iterator i = copy.iterator();
90 while ( i.hasNext() )
91 {
92 GestureListener l = (GestureListener)i.next();
93 l.gestureSelected( g );
94 }
95 setGesture( g );
96 }
97 }
98 );
99 }
100
101 public Gesture getGesture()
102 {
103 return currentGesture;
104 }
105
106 public void setGesture( Gesture newGesture )
107 {
108 currentGesture = newGesture;
109 if ( useImages )
110 {
111 setIcon( GestureIcon.getIconForGesture( currentGesture, hand ) );
112 }
113 else
114 {
115 setText( currentGesture.getName() );
116 }
117
118 }
119
120 public synchronized void addGestureListener( GestureListener l )
121 {
122 if ( ! listeners.contains( l ) )
123 {
124 listeners.add( l );
125 }
126 }
127
128 public synchronized void removeGestureListener( GestureListener l )
129 {
130 listeners.remove( l );
131 }
132
133 class GestureButtonListener extends MouseAdapter
134 {
135 /***
136 * When the mouse is pressed in an enabled gesture button, the
137 * button becomes unpressed and disarmed. The Gesture Popup
138 * Menu is displayed centered on the button and the popup
139 * receives focus.
140 */
141 public void mousePressed( MouseEvent e )
142 {
143 JButton invoker = (JButton)e.getSource();
144 ButtonModel model = invoker.getModel();
145 if ( model.isEnabled() )
146 {
147 popup.setInvoker( invoker );
148 Point p = PointUtilities.centeredOnComponent( invoker, popup );
149 popup.setLocation( p.x, p.y );
150 popup.setVisible( true );
151 }
152 }
153 }
154 }
155