001: /*
002: * Javu WingS - Lightweight Java Component Set
003: * Copyright (c) 2005-2007 Krzysztof A. Sadlocha
004: * e-mail: ksadlocha@programics.com
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020:
021: package com.javujavu.javux.wings;
022:
023: import java.awt.AWTEvent;
024: import java.awt.Dimension;
025: import java.awt.Point;
026: import java.awt.event.ActionEvent;
027: import java.awt.event.FocusEvent;
028: import java.awt.event.KeyEvent;
029: import java.awt.event.MouseEvent;
030:
031: /**
032: * An implementation of a button.<br>
033: * <br>
034: * <b>This class is thread safe.</b>
035: **/
036: public class WingButton extends WingLabel implements Shortcut {
037: protected Style stPressed;
038: protected Style stFocused;
039: protected Style stHover;
040:
041: protected boolean hover;
042: protected boolean focused;
043: protected boolean pressed;
044: protected boolean keyPressed;
045: protected boolean repeat;
046: protected boolean fast;
047: protected WingTimer timer;
048:
049: protected int shortcutCode = KeyEvent.VK_UNDEFINED;
050: protected int shortcutModifiers;
051:
052: /**
053: * Creates a button with no label.
054: */
055: public WingButton() {
056: this (null);
057: }
058:
059: /**
060: * Creates a button with label.<br>
061: * Label is an object that can be rendered by the current renderer,<br>
062: * usually String, WingImage or class implementing ItemRenderer
063: * @see com.javujavu.javux.wings.item.ItemRenderer
064: * @see com.javujavu.javux.wings.item.DefaultItemRenderer
065: *
066: * @param label the label of the button
067: */
068: public WingButton(Object label) {
069: super (label, CENTER);
070:
071: setWingFocusable(true);
072:
073: WingToolkit.the().addHierarchyListener(this );
074:
075: enableEvents(AWTEvent.MOUSE_EVENT_MASK
076: | AWTEvent.MOUSE_MOTION_EVENT_MASK
077: | AWTEvent.FOCUS_EVENT_MASK | AWTEvent.KEY_EVENT_MASK);
078: }
079:
080: /**
081: * Loads skin resources.<br>
082: * <pre>
083: * styles:
084: * [optional styleID.]button.normal
085: * [optional styleID.]button.pressed
086: * [optional styleID.]button.focused
087: * [optional styleID.]button.hover
088: * [optional styleID.]button.disabled
089: * </pre>
090: * @see Style
091: * @see WingSkin
092: */
093: public void loadSkin() {
094: stNormal = WingSkin.getStyle(styleId, "button", NORMAL, null);
095: stPressed = WingSkin.getStyle(styleId, "button", PRESSED,
096: stNormal).merge(stTop);
097: stFocused = WingSkin.getStyle(styleId, "button", FOCUSED,
098: stNormal).merge(stTop);
099: stHover = WingSkin.getStyle(styleId, "button", HOVER, stNormal)
100: .merge(stTop);
101: stDisabled = WingSkin.getStyle(styleId, "button", DISABLED,
102: stNormal).merge(stTop);
103: stNormal = stNormal.merge(stTop);
104: }
105:
106: /**
107: * Returns the style representing current button state
108: * @return current style representing button state
109: */
110: public Style getStyle() {
111: return (!isEnabled()) ? stDisabled
112: : ((pressed && hover) || keyPressed) ? stPressed
113: : (hover) ? stHover : (focused) ? stFocused
114: : stNormal;
115: }
116:
117: /**
118: * Set auto-repeat mode.
119: *
120: * @param repeat auto-repeat mode
121: */
122: public void setRepeat(boolean repeat) {
123: this .repeat = repeat;
124: }
125:
126: /**
127: * Set fastAction mode.
128: * <br>in this mode action is fired when button is pressed.
129: * @param fastAction fast action mode
130: */
131: public void setFastAction(boolean fastAction) {
132: this .fast = fastAction;
133: }
134:
135: /**
136: * Enables or disables this component, depending on the value of the
137: * parameter <code>enabled</code>.
138: * @param enabled
139: */
140: public void setEnabled(boolean enabled) {
141: if (!enabled && timer != null)
142: timer.stop();
143: super .setEnabled(enabled);
144: }
145:
146: /**
147: * Returns shortcut key code of this button
148: * @return shortcut key code of this button
149: * @see Shortcut#getShortcutCode()
150: */
151: public int getShortcutCode() {
152: return shortcutCode;
153: }
154:
155: /**
156: * Returns shortcut key modifiers of this button
157: * @return shortcut key modifiers of this button
158: * @see Shortcut#getShortcutModifiers()
159: */
160: public int getShortcutModifiers() {
161: return shortcutModifiers;
162: }
163:
164: /**
165: * Set shortcut of this button
166: * @see Shortcut
167: * @param keyCode shortcut key code of this button
168: * @param modifiers shortcut key modifiers of this button
169: */
170: public void setShortcut(int keyCode, int modifiers) {
171: WingRootPane rp = getRootPane();
172: if (rp != null && shortcutCode != KeyEvent.VK_UNDEFINED) {
173: rp.removeShortcut(this );
174: }
175: shortcutCode = keyCode;
176: shortcutModifiers = modifiers;
177: if (rp != null && shortcutCode != KeyEvent.VK_UNDEFINED) {
178: rp.addShortcut(this );
179: }
180: }
181:
182: public void wingHierarchyChanged(boolean showing) {
183: if (!showing) {
184: hover = false;
185: focused = false;
186: keyPressed = false;
187: spin(false);
188: }
189: }
190:
191: /**
192: * @see WingComponent#wingProcessMouseEvent(java.awt.event.MouseEvent)
193: */
194: protected void wingProcessMouseEvent(MouseEvent e) {
195: boolean enabled = isEnabled();
196:
197: int id = e.getID();
198: if (id == MouseEvent.MOUSE_ENTERED) {
199: if ((e.getModifiers() & (MouseEvent.BUTTON1_MASK
200: | MouseEvent.BUTTON2_MASK | MouseEvent.BUTTON3_MASK)) == 0) {
201: hover = true;
202: repaint();
203: }
204: } else if (id == MouseEvent.MOUSE_EXITED) {
205: if (hover) {
206: hover = false;
207: repaint();
208: }
209: } else if (id == MouseEvent.MOUSE_PRESSED && enabled) {
210: if (wingFocusable && !focused)
211: requestFocus(); //wingRequestFocusInWindow();
212: hover = true;
213: pressed = true;
214: repaint();
215: if (repeat)
216: spin(true);
217: else if (fast)
218: buttonAction(e.getModifiers());
219: } else if (id == MouseEvent.MOUSE_RELEASED) {
220: pressed = false;
221: repaint();
222: if (!repeat) {
223: if (hover && enabled && !fast)
224: buttonAction(e.getModifiers());
225: } else
226: spin(false);
227: } else if (id == MouseEvent.MOUSE_DRAGGED) {
228: Point p = e.getPoint();
229: Dimension d = getSize();
230: boolean on = p.x >= 0 && p.y >= 0 && p.x < d.width
231: && p.y < d.height;
232: if (on != hover) {
233: hover = on;
234: repaint();
235: }
236: }
237: }
238:
239: private void spin(boolean start) {
240: if (start) {
241: buttonAction(0);
242: if (timer == null) {
243: timer = new WingTimer(500, true, this );
244: }
245: timer.setDelay(500);
246: timer.start();
247: } else {
248: if (timer != null)
249: timer.stop();
250: }
251: }
252:
253: /**
254: * @see com.javujavu.javux.wings.WingComponent#wingProcessActionEvent(java.awt.event.ActionEvent)
255: */
256: public void wingProcessActionEvent(ActionEvent e) {
257: if (e.getSource() == timer) {
258: if (hover || keyPressed)
259: buttonAction(0);
260: timer.setDelay(100);
261: // timer.start();
262: } else
263: super .wingProcessActionEvent(e);
264: }
265:
266: /**
267: * @see WingComponent#wingProcessKeyEvent(java.awt.event.KeyEvent, com.javujavu.javux.wings.WingComponent)
268: */
269: protected void wingProcessKeyEvent(KeyEvent e,
270: WingComponent redirecting) {
271: int id = e.getID();
272: if ((id == KeyEvent.KEY_PRESSED || id == KeyEvent.KEY_RELEASED)
273: && e.getKeyCode() == KeyEvent.VK_SPACE
274: && e.getModifiers() == 0) {
275: processShortcut(e);
276: }
277: super .wingProcessKeyEvent(e, redirecting);
278: }
279:
280: /**
281: * @see Shortcut#processShortcut(java.awt.event.KeyEvent)
282: */
283: public void processShortcut(KeyEvent e) {
284: if (!isShowing() || !isEnabled())
285: return;
286: e.consume();
287: if (e.getID() == KeyEvent.KEY_PRESSED) {
288: if (!keyPressed) {
289: keyPressed = true;
290: repaint();
291: if (repeat)
292: spin(true);
293: else if (fast)
294: buttonAction(e.getModifiers());
295: }
296: } else if (keyPressed) {
297: keyPressed = false;
298: repaint();
299: if (!repeat) {
300: if (!fast)
301: buttonAction(e.getModifiers());
302: } else
303: spin(false);
304: }
305: }
306:
307: protected void processFocusEvent(FocusEvent e) {
308: int id = e.getID();
309: if (id == FocusEvent.FOCUS_GAINED) {
310: focused = true;
311: repaint();
312: } else if (id == FocusEvent.FOCUS_LOST) {
313: focused = false;
314: repaint();
315:
316: keyPressed = false;
317: if (repeat)
318: spin(false);
319: }
320: super .processFocusEvent(e);
321: }
322:
323: protected void buttonAction(int eventModifiers) {
324: Object label = this .label;
325: wingProcessActionEvent(new ActionEvent(this,
326: ActionEvent.ACTION_PERFORMED, (label == null) ? null
327: : label.toString(), eventModifiers));
328: }
329: }
|