KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > forms > widgets > AbstractHyperlink


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.forms.widgets;
12
13 import org.eclipse.core.runtime.ListenerList;
14 import org.eclipse.swt.SWT;
15 import org.eclipse.swt.accessibility.ACC;
16 import org.eclipse.swt.events.PaintEvent;
17 import org.eclipse.swt.events.PaintListener;
18 import org.eclipse.swt.graphics.GC;
19 import org.eclipse.swt.graphics.Point;
20 import org.eclipse.swt.graphics.Rectangle;
21 import org.eclipse.swt.widgets.Canvas;
22 import org.eclipse.swt.widgets.Composite;
23 import org.eclipse.swt.widgets.Event;
24 import org.eclipse.swt.widgets.Listener;
25 import org.eclipse.ui.forms.events.HyperlinkEvent;
26 import org.eclipse.ui.forms.events.IHyperlinkListener;
27 import org.eclipse.ui.internal.forms.widgets.FormsResources;
28
29 /**
30  * This is the base class for custom hyperlink widget. It is responsible for
31  * processing mouse and keyboard events, and converting them into unified
32  * hyperlink events. Subclasses are responsible for rendering the hyperlink in
33  * the client area.
34  *
35  * @since 3.0
36  */

37 public abstract class AbstractHyperlink extends Canvas {
38     private boolean hasFocus;
39     boolean paintFocus=true;
40
41     /*
42      * Armed link is one that will activate on a mouse up event, i.e.
43      * it has received a mouse down and mouse still on top of it.
44      */

45     private boolean armed;
46
47     private ListenerList listeners;
48
49     /**
50      * Amount of the margin width around the hyperlink (default is 1).
51      */

52     protected int marginWidth = 1;
53
54     /**
55      * Amount of the margin height around the hyperlink (default is 1).
56      */

57     protected int marginHeight = 1;
58
59     /**
60      * Creates a new hyperlink in the provided parent.
61      *
62      * @param parent
63      * the control parent
64      * @param style
65      * the widget style
66      */

67     public AbstractHyperlink(Composite parent, int style) {
68         super(parent, style);
69         addListener(SWT.KeyDown, new Listener() {
70             public void handleEvent(Event e) {
71                 if (e.character == '\r') {
72                     handleActivate(e);
73                 }
74             }
75         });
76         addPaintListener(new PaintListener() {
77             public void paintControl(PaintEvent e) {
78                 paint(e);
79             }
80         });
81         addListener(SWT.Traverse, new Listener() {
82             public void handleEvent(Event e) {
83                 switch (e.detail) {
84                 case SWT.TRAVERSE_PAGE_NEXT:
85                 case SWT.TRAVERSE_PAGE_PREVIOUS:
86                 case SWT.TRAVERSE_ARROW_NEXT:
87                 case SWT.TRAVERSE_ARROW_PREVIOUS:
88                 case SWT.TRAVERSE_RETURN:
89                     e.doit = false;
90                     return;
91                 }
92                 e.doit = true;
93             }
94         });
95         Listener listener = new Listener() {
96             public void handleEvent(Event e) {
97                 switch (e.type) {
98                 case SWT.FocusIn:
99                     hasFocus = true;
100                     handleEnter(e);
101                     break;
102                 case SWT.FocusOut:
103                     hasFocus = false;
104                     handleExit(e);
105                     break;
106                 case SWT.DefaultSelection:
107                     handleActivate(e);
108                     break;
109                 case SWT.MouseEnter:
110                     handleEnter(e);
111                     break;
112                 case SWT.MouseExit:
113                     handleExit(e);
114                     break;
115                 case SWT.MouseDown:
116                     handleMouseDown(e);
117                     break;
118                 case SWT.MouseUp:
119                     handleMouseUp(e);
120                     break;
121                 case SWT.MouseMove:
122                     handleMouseMove(e);
123                     break;
124                 }
125             }
126         };
127         addListener(SWT.MouseEnter, listener);
128         addListener(SWT.MouseExit, listener);
129         addListener(SWT.MouseDown, listener);
130         addListener(SWT.MouseUp, listener);
131         addListener(SWT.MouseMove, listener);
132         addListener(SWT.FocusIn, listener);
133         addListener(SWT.FocusOut, listener);
134         setCursor(FormsResources.getHandCursor());
135     }
136
137     /**
138      * Adds the event listener to this hyperlink.
139      *
140      * @param listener
141      * the event listener to add
142      */

143     public void addHyperlinkListener(IHyperlinkListener listener) {
144         if (listeners == null)
145             listeners = new ListenerList();
146         listeners.add(listener);
147     }
148
149     /**
150      * Removes the event listener from this hyperlink.
151      *
152      * @param listener
153      * the event listener to remove
154      */

155     public void removeHyperlinkListener(IHyperlinkListener listener) {
156         if (listeners == null)
157             return;
158         listeners.remove(listener);
159     }
160
161     /**
162      * Returns the selection state of the control. When focus is gained, the
163      * state will be <samp>true </samp>; it will switch to <samp>false </samp>
164      * when the control looses focus.
165      *
166      * @return <code>true</code> if the widget has focus, <code>false</code>
167      * otherwise.
168      */

169     public boolean getSelection() {
170         return hasFocus;
171     }
172
173     /**
174      * Called when hyperlink is entered. Subclasses that override this method
175      * must call 'super'.
176      */

177     protected void handleEnter(Event e) {
178         redraw();
179         if (listeners == null)
180             return;
181         int size = listeners.size();
182         HyperlinkEvent he = new HyperlinkEvent(this, getHref(), getText(),
183                 e.stateMask);
184         Object JavaDoc[] listenerList = listeners.getListeners();
185         for (int i = 0; i < size; i++) {
186             IHyperlinkListener listener = (IHyperlinkListener) listenerList[i];
187             listener.linkEntered(he);
188         }
189     }
190
191     /**
192      * Called when hyperlink is exited. Subclasses that override this method
193      * must call 'super'.
194      */

195     protected void handleExit(Event e) {
196         // disarm the link; won't activate on mouseup
197
armed = false;
198         redraw();
199         if (listeners == null)
200             return;
201         int size = listeners.size();
202         HyperlinkEvent he = new HyperlinkEvent(this, getHref(), getText(),
203                 e.stateMask);
204         Object JavaDoc[] listenerList = listeners.getListeners();
205         for (int i = 0; i < size; i++) {
206             IHyperlinkListener listener = (IHyperlinkListener) listenerList[i];
207             listener.linkExited(he);
208         }
209     }
210
211     /**
212      * Called when hyperlink has been activated. Subclasses that override this
213      * method must call 'super'.
214      */

215     protected void handleActivate(Event e) {
216         // disarm link, back to normal state
217
armed = false;
218         getAccessible().setFocus(ACC.CHILDID_SELF);
219         if (listeners == null)
220             return;
221         int size = listeners.size();
222         setCursor(FormsResources.getBusyCursor());
223         HyperlinkEvent he = new HyperlinkEvent(this, getHref(), getText(),
224                 e.stateMask);
225         Object JavaDoc[] listenerList = listeners.getListeners();
226         for (int i = 0; i < size; i++) {
227             IHyperlinkListener listener = (IHyperlinkListener) listenerList[i];
228             listener.linkActivated(he);
229         }
230         if (!isDisposed())
231             setCursor(FormsResources.getHandCursor());
232     }
233
234     /**
235      * Sets the object associated with this hyperlink. Concrete implementation
236      * of this class can use if to store text, URLs or model objects that need
237      * to be processed on hyperlink events.
238      *
239      * @param href
240      * the hyperlink object reference
241      */

242     public void setHref(Object JavaDoc href) {
243         setData("href", href); //$NON-NLS-1$
244
}
245
246     /**
247      * Returns the object associated with this hyperlink.
248      *
249      * @see #setHref
250      * @return the hyperlink object reference
251      */

252     public Object JavaDoc getHref() {
253         return getData("href"); //$NON-NLS-1$
254
}
255
256     /**
257      * Returns the textual representation of this hyperlink suitable for showing
258      * in tool tips or on the status line.
259      *
260      * @return the hyperlink text
261      */

262     public String JavaDoc getText() {
263         return getToolTipText();
264     }
265
266     /**
267      * Paints the hyperlink as a reaction to the provided paint event.
268      *
269      * @param gc
270      * graphic context
271      */

272     protected abstract void paintHyperlink(GC gc);
273
274     /**
275      * Paints the control as a reaction to the provided paint event.
276      *
277      * @param e
278      * the paint event
279      */

280     protected void paint(PaintEvent e) {
281         GC gc = e.gc;
282         Rectangle clientArea = getClientArea();
283         if (clientArea.width == 0 || clientArea.height == 0)
284             return;
285         paintHyperlink(gc);
286         if (paintFocus && hasFocus) {
287             Rectangle carea = getClientArea();
288             gc.setForeground(getForeground());
289             gc.drawFocus(0, 0, carea.width, carea.height);
290         }
291     }
292
293     private void handleMouseDown(Event e) {
294         if (e.button != 1)
295             return;
296         // armed and ready to activate on mouseup
297
armed = true;
298     }
299
300     private void handleMouseUp(Event e) {
301         if (!armed || e.button != 1)
302             return;
303         Point size = getSize();
304         // Filter out mouse up events outside
305
// the link. This can happen when mouse is
306
// clicked, dragged outside the link, then
307
// released.
308
if (e.x < 0)
309             return;
310         if (e.y < 0)
311             return;
312         if (e.x >= size.x)
313             return;
314         if (e.y >= size.y)
315             return;
316         handleActivate(e);
317     }
318
319     private void handleMouseMove(Event e) {
320         // disarm link if we move out of bounds
321
if (armed) {
322             Point size = getSize();
323             armed = (e.x >= 0 && e.y >= 0 && e.x < size.x && e.y < size.y);
324         }
325     }
326     
327     /*
328      * (non-Javadoc)
329      * @see org.eclipse.swt.widgets.Control#setEnabled(boolean)
330      */

331
332     public void setEnabled (boolean enabled) {
333         super.setEnabled(enabled);
334         redraw();
335     }
336 }
337
Popular Tags