001: package com.xoetrope.event;
002:
003: import java.awt.AWTEventMulticaster;
004: import java.awt.Component;
005: import java.awt.Point;
006: import java.awt.event.ActionEvent;
007: import java.awt.event.ActionListener;
008: import java.awt.event.MouseEvent;
009: import java.awt.event.MouseListener;
010: import java.awt.event.MouseMotionListener;
011:
012: /**
013: * Adds mouse support for clickable controls/regions
014: *
015: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
016: * the GNU Public License (GPL), please see license.txt for more details. If
017: * you make commercial use of this software you must purchase a commercial
018: * license from Xoetrope.</p>
019: * <p> $Revision: 1.6 $</p>
020: */
021: public class XClickListener implements MouseListener,
022: MouseMotionListener {
023: private Component owner;
024: private XStateListener stateListener;
025: private boolean isSelected = false;
026: private boolean isEntered = false;
027: private Point clickLocation;
028: private boolean responseInvoked = false;
029: private boolean cancelOnDrag = false;
030: private int offset;
031: private volatile int activeResponse = -1;
032: private volatile int selectedResponse = -1;
033:
034: private transient ActionListener actionListener;
035:
036: /**
037: * Constructs a simple listener that tracks the state of a check mark
038: * @param ownr The component to which this listener listens
039: */
040: public XClickListener(Component ownr) {
041: owner = ownr;
042: stateListener = null;
043: }
044:
045: /**
046: * Resets the listener's state
047: */
048: public void reset() {
049: activeResponse = -1;
050: selectedResponse = -1;
051: }
052:
053: /**
054: * Constructs a listener that can track the state of multiple checkmarks.
055: * @param ownr The component to which this listener listens
056: * @param startPos The offset to the first check mark
057: */
058: public XClickListener(Component ownr, int startPos) {
059: owner = ownr;
060: stateListener = (XStateListener) ownr;
061: offset = startPos;
062: }
063:
064: /**
065: * Calls the owner's parent responsToEvent method with BUTTON_CLCIKED as the event id
066: * @param e
067: */
068: public void mouseClicked(MouseEvent e) {
069: owner.repaint();
070: clickLocation = e.getPoint();
071: if (!responseInvoked) {
072: fireActionEvent();
073: if (stateListener != null) {
074: stateListener.setState(e.getX() - offset, e.getY(),
075: activeResponse);
076: selectedResponse = activeResponse;
077: stateListener.paintStates();
078: }
079: }
080: }
081:
082: /**
083: * Tracks the entered state of the owner control
084: * @param e
085: */
086: public void mouseEntered(MouseEvent e) {
087: isEntered = true;
088: if (stateListener != null)
089: stateListener.setState(e.getX() - offset, e.getY(),
090: selectedResponse);
091: else
092: owner.repaint();
093:
094: activeResponse = -1;
095: }
096:
097: /**
098: * Tracks the entered state of the owner control
099: * @param e
100: */
101: public void mouseExited(MouseEvent e) {
102: isEntered = false;
103: if (stateListener != null)
104: stateListener.paintStates();
105: else
106: owner.repaint();
107: }
108:
109: /**
110: * Tracks the mouse pressed state of the owner control
111: * @param e
112: */
113: public void mousePressed(MouseEvent e) {
114: e.consume();
115: isSelected = true;
116: clickLocation = e.getPoint();
117: responseInvoked = false;
118: if (stateListener != null)
119: stateListener.paintStates();
120: else
121: owner.repaint();
122: }
123:
124: /**
125: * Tracks the mouse pressed state of the owner control
126: * @param e
127: */
128: public void mouseReleased(MouseEvent e) {
129: e.consume();
130: Point currentPoint = e.getPoint();
131: if (clickLocation != null) {
132: if ((stateListener != null)
133: && (stateListener.findCurrentResponse(
134: currentPoint.x, currentPoint.y) == activeResponse))
135: stateListener.setState(e.getX() - offset, e.getY(),
136: activeResponse);
137:
138: selectedResponse = activeResponse;
139: responseInvoked = true;
140: fireActionEvent();
141: }
142:
143: clickLocation = null;
144: isSelected = false;
145: if (stateListener != null)
146: stateListener.paintStates();
147: else
148: owner.repaint();
149: }
150:
151: /**
152: * Tracks the mouse position of the owner control
153: * @param e
154: */
155: public void mouseMoved(MouseEvent e) {
156: if (clickLocation == null) {
157: clickLocation = e.getPoint();
158: if (stateListener != null)
159: stateListener.paintStates();
160: isEntered = true;
161: }
162:
163: if ((stateListener != null)
164: && stateListener.setState(e.getX() - offset, e.getY(),
165: activeResponse))
166: stateListener.paintStates();
167: }
168:
169: /**
170: * Tracks the mouse position of the owner control
171: * @param e
172: */
173: public void mouseDragged(MouseEvent e) {
174: if (cancelOnDrag)
175: isEntered = isSelected = false;
176: mouseMoved(e);
177: }
178:
179: /**
180: * Fire an action event
181: */
182: private void fireActionEvent() {
183: processActionEvent(new ActionEvent(this ,
184: ActionEvent.ACTION_PERFORMED, ""));
185: if (stateListener != null)
186: stateListener.updateSelectedState();
187: }
188:
189: /**
190: * Sets the offset to the first check mark
191: * @param off
192: */
193: public void setOffset(int off) {
194: offset = off;
195: }
196:
197: /**
198: * Gets the entered state of the owner control
199: * @return the entered state of the owner control
200: */
201: public boolean getIsEntered() {
202: return isEntered;
203: }
204:
205: /**
206: * Gets the selected state of the owner control
207: * @return the selected state of the owner control
208: */
209: public boolean getIsSelected() {
210: return isSelected && isEntered;
211: }
212:
213: /**
214: * Sets the selected state of the owner control
215: * @param selected the new state of the owner control
216: */
217: public void setIsSelected(boolean selected) {
218: isSelected = selected;
219: }
220:
221: /**
222: * Gets the active response for a listener tracking multiple check marks. The
223: * active response is the one under the mouse
224: * @return the active response
225: */
226: public int getActiveResponse() {
227: return activeResponse;
228: }
229:
230: /**
231: * Set the active response
232: * @param resp the new active response
233: */
234: public void setActiveResponse(int resp) {
235: activeResponse = resp;
236: }
237:
238: /**
239: * Gets the selected response for a listener tracking multiple check marks.
240: * The selected response is the one that has been checked or clicked.
241: * @return the selected response or -1 if nothing is selected
242: */
243: public int getSelectedResponse() {
244: return selectedResponse;
245: }
246:
247: /**
248: * Sets the selected response
249: * @param resp the new selection
250: */
251: public void setSelectedResponse(int resp) {
252: selectedResponse = resp;
253: }
254:
255: /**
256: * Set the cancelOnDrag flag. If true the selected state of the listener is
257: * reset upon a drag operation
258: * @param state true to reset the state
259: */
260: public void setCancelOnDrag(boolean state) {
261: cancelOnDrag = state;
262: }
263:
264: /**
265: * Get the location of the mouse click
266: * @return the location of the mouse click
267: */
268: public Point getClickLocation() {
269: return clickLocation;
270: }
271:
272: /**
273: * Adds the specified action listener to receive action events from
274: * this button. Action events occur when a user presses or releases
275: * the mouse over this button.
276: * If l is null, no exception is thrown and no action is performed.
277: *
278: * @param l the action listener
279: * @see #removeActionListener
280: * @see #getActionListeners
281: * @see java.awt.event.ActionListener
282: * @since JDK1.1
283: */
284: public synchronized void addActionListener(ActionListener l) {
285: if (l == null)
286: return;
287:
288: actionListener = AWTEventMulticaster.add(actionListener, l);
289: }
290:
291: /**
292: * Removes the specified action listener so that it no longer
293: * receives action events from this button. Action events occur
294: * when a user presses or releases the mouse over this button.
295: * If l is null, no exception is thrown and no action is performed.
296: *
297: * @param l the action listener
298: * @see #addActionListener
299: * @see #getActionListeners
300: * @see java.awt.event.ActionListener
301: * @since JDK1.1
302: */
303: public synchronized void removeActionListener(ActionListener l) {
304: if (l == null)
305: return;
306:
307: actionListener = AWTEventMulticaster.remove(actionListener, l);
308: }
309:
310: /**
311: * Processes action events occurring on this button
312: * by dispatching them to any registered
313: * <code>ActionListener</code> objects.
314: * <p>
315: * This method is not called unless action events are
316: * enabled for this button. Action events are enabled
317: * when one of the following occurs:
318: * <p><ul>
319: * <li>An <code>ActionListener</code> object is registered
320: * via <code>addActionListener</code>.
321: * <li>Action events are enabled via <code>enableEvents</code>.
322: * </ul>
323: * <p>Note that if the event parameter is <code>null</code>
324: * the behavior is unspecified and may result in an
325: * exception.
326: *
327: * @param e the action event
328: * @see java.awt.event.ActionListener
329: * @see java.awt.Button#addActionListener
330: * @see java.awt.Component#enableEvents
331: * @since JDK1.1
332: */
333: protected void processActionEvent(ActionEvent e) {
334: if (actionListener != null)
335: actionListener.actionPerformed(e);
336: }
337: }
|