1 package example;
2
3 import java.awt;
4 import java.awt.event;
5
6 import javax.swing.JPanel;
7 import javax.swing.border.EmptyBorder;
8 /**
9 * Source code for Tutorial 1.
10 * Simple arrow button that fires one event when first clicked, then sends a
11 * stream of events while held down.
12 */
13
14 public class ArrowButton extends JPanel {
15 /** Directions. */
16 public static final String
17 LEFT = "LEFT",
18 RIGHT = "RIGHT",
19 UP = "UP",
20 DOWN = "DOWN";
21
22 private String direction;
23 private String lastPaintedDirection;
24 private static ArrowRoller roller;
25 private boolean down;
26 private boolean in;
27 private ActionListener listeners;
28 private static final int SIZE = 12;
29 private static final int BORDER = 2;
30
31 private static class ArrowRoller extends Thread {
32 /** How long to wait before repeating. */
33 private static final int DELAY_MS = 400;
34 /** How long between repeated firings. */
35 private static final int REPEAT_MS = 100;
36 private boolean die = false;
37 private ArrowButton target;
38 private int state;
39
40 ArrowRoller () {
41 super ("ArrowRoller");
42 setDaemon(true);
43 }
44
45 synchronized void abort () {
46 die = true;
47 notify ();
48 target = null;
49 ++ state;
50 }
51
52 synchronized void addListener (ArrowButton t) {
53 target = t;
54 ++ state;
55 notify ();
56 }
57
58 synchronized void removeListener (ArrowButton t) {
59 if (target == t) {
60 target = null;
61 ++ state;
62 }
63 }
64
65 public void run () {
66 while (!die) {
67 try {
68 ArrowButton target;
69 int state;
70 synchronized (this) {
71 while ((target = this.target) == null)
72 wait ();
73 state = this.state;
74 }
75 sleep (DELAY_MS);
76 while (state == this.state) {
77 target.fireActionEvent ();
78 sleep (REPEAT_MS);
79 }
80 } catch (InterruptedException ex) {
81 }
82 }
83 }
84 }
85
86 public ArrowButton () {
87 this(LEFT);
88 }
89
90 public ArrowButton (String direction) {
91 enableEvents (AWTEvent.MOUSE_EVENT_MASK);
92 setBorder(new EmptyBorder(BORDER, BORDER, BORDER, BORDER));
93 lastPaintedDirection = direction;
94 setDirection(direction);
95 }
96
97 public void setDirection (String d) {
98 if (d.equals(LEFT))
99 direction = LEFT;
100 else if (d.equals(RIGHT))
101 direction = RIGHT;
102 else if (d.equals(UP))
103 direction = UP;
104 else
105 direction = DOWN;
106 repaint();
107 }
108
109 public String getDirection () {
110 return direction;
111 }
112
113 public Dimension getMinimumSize () {
114 return getPreferredSize ();
115 }
116
117 public Dimension getPreferredSize () {
118 return new Dimension (SIZE, SIZE);
119 }
120
121 public Dimension getMaximumSize () {
122 return getPreferredSize ();
123 }
124
125 public void update (Graphics g) {
126 if (lastPaintedDirection == direction) {
127 paint (g);
128 }
129 else {
130 super.update (g);
131 lastPaintedDirection = direction;
132 }
133 }
134
135 public void paint (Graphics g) {
136 super.paint(g);
137 int w = getSize ().width, h = getSize ().height;
138 g.setColor ((in && down) ? getBackground ().brighter () :
139 getBackground ().darker ());
140 if (direction == LEFT) {
141 g.drawLine (w - 2, 2, w - 2, h - 2);
142 g.drawLine (w - 2, h - 2, 2, (h - 2) / 2);
143 g.setColor ((in && down) ? getBackground ().darker () :
144 getBackground().brighter());
145 g.drawLine (2, (h - 2) / 2, w - 2, 2);
146 }
147 else if (direction == RIGHT) {
148 g.drawLine (2, 2, w - 2, (h - 2) / 2);
149 g.drawLine (2, h - 2, w - 2, (h - 2) / 2);
150 g.setColor ((in && down) ? getBackground ().darker () :
151 getBackground().brighter());
152 g.drawLine (2, 2, 2, h - 2);
153 }
154 else if (direction == UP){
155 g.drawLine (2, h - 2, w - 2, h - 2);
156 g.drawLine (w - 2, h - 2, (w - 2) / 2, 2);
157 g.setColor ((in && down) ? getBackground ().darker () :
158 getBackground().brighter());
159 g.drawLine (2, h - 2, (w - 2) / 2, 2);
160 }
161 else {
162 g.drawLine ((w - 2) / 2, h - 2, w - 2, 2);
163 g.setColor ((in && down) ? getBackground ().darker () :
164 getBackground().brighter());
165 g.drawLine (2, 2, (w - 2) / 2, h - 2);
166 g.drawLine (2, 2, w - 2, 2);
167 }
168 }
169
170 protected synchronized ArrowRoller getRoller () {
171 if (roller == null) {
172 roller = new ArrowRoller ();
173 roller.start();
174 }
175 return roller;
176 }
177
178 public synchronized void destroyRoller () {
179 roller.abort ();
180 roller = null;
181 }
182
183 protected void processMouseEvent(MouseEvent e) {
184 ArrowRoller roller = getRoller();
185 switch (e.getID ()) {
186 case MouseEvent.MOUSE_PRESSED:
187 fireActionEvent ();
188 roller.addListener (this);
189 down = in = true;
190 repaint ();
191 break;
192 case MouseEvent.MOUSE_RELEASED:
193 roller.removeListener (this);
194 down = in = false;
195 repaint ();
196 break;
197 case MouseEvent.MOUSE_ENTERED:
198 in = true;
199 if (down) {
200 roller.addListener (this);
201 repaint ();
202 }
203 break;
204 case MouseEvent.MOUSE_EXITED:
205 in = false;
206 if (down) {
207 roller.removeListener (this);
208 repaint ();
209 }
210 break;
211 }
212 super.processMouseEvent (e);
213 }
214
215 public void addActionListener (ActionListener l) {
216 listeners = AWTEventMulticaster.add (l, listeners);
217 }
218
219 public void removeActionListener (ActionListener l) {
220 listeners = AWTEventMulticaster.remove (l, listeners);
221 }
222
223 protected void fireActionEvent () {
224 if (listeners != null){
225 ActionEvent ev = new ActionEvent (this,
226 ActionEvent.ACTION_PERFORMED,
227 direction);
228 listeners.actionPerformed (ev);
229 }
230 }
231 }