1 /*
2 * Copyright 2006-2016 The JGUIraffe Team.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License")
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package net.sf.jguiraffe.gui.builder.event;
17
18 import java.util.Collection;
19 import java.util.Collections;
20 import java.util.EnumSet;
21 import java.util.Set;
22
23 import net.sf.jguiraffe.gui.forms.ComponentHandler;
24
25 import org.apache.commons.lang.builder.EqualsBuilder;
26 import org.apache.commons.lang.builder.HashCodeBuilder;
27
28 /**
29 * <p>
30 * A specialized event class for reporting events related to mouse actions.
31 * </p>
32 * <p>
33 * Events of this type are passed to components that have registered themselves
34 * as mouse listeners at input components. This way listeners get notified, for
35 * instance, if the mouse is clicked, released, or moved within an input
36 * components. The {@code type} property can be queried to find out which mouse
37 * action was performed. The coordinates of the mouse cursor (relative to the
38 * origin of the source component) are also available. Further, the affected
39 * mouse button and the status of special modifier keys (like <em>SHIFT</em> or
40 * <em>ALT</em>) are available.
41 * </p>
42 * <p>
43 * Mouse events are more low-level. In typical controller classes for input
44 * forms it is rarely necessary to react on specific mouse actions. In most
45 * cases action or change events are more appropriate. An exception can be
46 * double-click events, which are only available through a mouse listener.
47 * </p>
48 * <p>
49 * {@code FormMouseEvent} is derived from {@code FormEvent} and thus provides
50 * access to the {@link ComponentHandler} and the name of the component that
51 * triggered this event. Nevertheless, it is possible to register a mouse
52 * listener at non-input components, e.g. windows. In this case, the {@code
53 * handler} and {@code name} properties are undefined.
54 * </p>
55 *
56 * @author Oliver Heger
57 * @version $Id: FormMouseEvent.java 205 2012-01-29 18:29:57Z oheger $
58 */
59 public class FormMouseEvent extends FormEvent
60 {
61 /**
62 * Constant for the mouse button 1. This is the left button. The return
63 * value of {@link #getButton()} can be checked with this constant.
64 */
65 public static final int BUTTON1 = 1;
66
67 /**
68 * Constant for the mouse button 2. This is the middle mouse button. The
69 * return value of {@link #getButton()} can be checked with this constant.
70 */
71 public static final int BUTTON2 = 2;
72
73 /**
74 * Constant for the mouse button 3. This is the right mouse button. The
75 * return value of {@link #getButton()} can be checked with this constant.
76 */
77 public static final int BUTTON3 = 3;
78
79 /**
80 * Constant for an undefined mouse button. This value is returned by
81 * {@link #getButton()} if the event is not related to a button.
82 */
83 public static final int NO_BUTTON = 0;
84
85 /** Constant for the pattern for creating the string representation. */
86 private static final String TO_STRING_PATTERN = "FormMouseEvent [ componentName = %s, "
87 + "TYPE = %s, X = %d, Y = %d, BUTTON = %d, MODIFIERS = %s ]";
88
89 /**
90 * The serial version UID.
91 */
92 private static final long serialVersionUID = 20090915L;
93
94 /** The type of this event. */
95 private final Type type;
96
97 /** The X position of the mouse cursor. */
98 private final int x;
99
100 /** The Y position of the mouse cursor. */
101 private final int y;
102
103 /** The button that was pressed. */
104 private final int button;
105
106 /** A set with modifier keys. */
107 private final Set<Modifiers> modifiers;
108
109 /**
110 * Creates a new instance of {@code FormMouseEvent} and initializes all its
111 * properties.
112 *
113 * @param source the source of this event (this is typically the original,
114 * platform-specific event this object was created from)
115 * @param handler the {@code ComponentHandler} of the input component that
116 * caused this event
117 * @param name the name of the input component that caused this event
118 * @param t the type of this event (must not be <b>null</b>)
119 * @param xp the x position of the mouse cursor
120 * @param yp the y position of the mouse cursor
121 * @param btn the index of the affected button
122 * @param mods a set with modifier keys (may be empty or <b>null</b>)
123 * @throws IllegalArgumentException if a required parameter is missing
124 */
125 public FormMouseEvent(Object source, ComponentHandler<?> handler,
126 String name, Type t, int xp, int yp, int btn,
127 Collection<Modifiers> mods)
128 {
129 super(source, handler, name);
130 if (t == null)
131 {
132 throw new IllegalArgumentException("Event type must not be null!");
133 }
134
135 type = t;
136 x = xp;
137 y = yp;
138 button = btn;
139
140 if (mods == null || mods.isEmpty())
141 {
142 modifiers = Collections.emptySet();
143 }
144 else
145 {
146 modifiers = Collections.unmodifiableSet(EnumSet.copyOf(mods));
147 }
148 }
149
150 /**
151 * Returns the type of this event. The type provides information about which
152 * mouse action has actually happened.
153 *
154 * @return the type of this event
155 */
156 public Type getType()
157 {
158 return type;
159 }
160
161 /**
162 * Returns the X position of the mouse relative to the origin of the
163 * component that caused this event.
164 *
165 * @return the X position of the mouse cursor
166 */
167 public int getX()
168 {
169 return x;
170 }
171
172 /**
173 * Returns the Y position of the mouse relative to the origin of the
174 * component that caused this event.
175 *
176 * @return the Y position of the mouse cursor
177 */
178 public int getY()
179 {
180 return y;
181 }
182
183 /**
184 * Returns the index of the mouse button affected by this event. The return
185 * value is one of the {@code BUTTONx} constants. It indicates which button
186 * was pressed or released. If the event is not related to a mouse button,
187 * result is {@link #NO_BUTTON}.
188 *
189 * @return the index of the mouse button affected by this event
190 */
191 public int getButton()
192 {
193 return button;
194 }
195
196 /**
197 * Returns a set with {@code Modifiers} representing the special modifier
198 * keys that were pressed when the mouse event occurred. This information
199 * can be used to distinguish enhanced mouse gestures, e.g. SHIFT+CLICK for
200 * text selection. The set returned by this method cannot be modified.
201 *
202 * @return a set with the active modifier keys
203 */
204 public Set<Modifiers> getModifiers()
205 {
206 return modifiers;
207 }
208
209 /**
210 * Returns a string representation of this object. This string contains the
211 * most important properties that have a meaningful string representation.
212 *
213 * @return a string for this object
214 */
215 @Override
216 public String toString()
217 {
218 return String.format(TO_STRING_PATTERN, getName(), getType().name(),
219 getX(), getY(), getButton(), getModifiers().toString());
220 }
221
222 /**
223 * {@inheritDoc} This implementation takes the additional fields into
224 * account declared by this class.
225 *
226 * @since 1.3
227 */
228 @Override
229 public int hashCode()
230 {
231 return new HashCodeBuilder().appendSuper(super.hashCode())
232 .append(getType()).append(getX()).append(getY())
233 .append(getButton()).append(getModifiers()).toHashCode();
234 }
235
236 /**
237 * {@inheritDoc} This implementation checks the additional fields declared
238 * by this class.
239 *
240 * @since 1.3
241 */
242 @Override
243 public boolean equals(Object obj)
244 {
245 if (super.equals(obj))
246 {
247 FormMouseEvent c = (FormMouseEvent) obj;
248 return new EqualsBuilder().append(getType(), c.getType())
249 .append(getX(), c.getX()).append(getY(), c.getY())
250 .append(getButton(), c.getButton())
251 .append(getModifiers(), c.getModifiers()).isEquals();
252 }
253 return false;
254 }
255
256 /**
257 * An enumeration class defining constants for the possible mouse actions
258 * that can trigger a {@code FormMouseEvent}. Each {@code FormMouseEvent} is
259 * associated with such a type constant, so that it is possible to find out
260 * what exactly has happened.
261 *
262 * @author Oliver Heger
263 * @version $Id: FormMouseEvent.java 205 2012-01-29 18:29:57Z oheger $
264 */
265 public static enum Type
266 {
267 /**
268 * A mouse button was pressed.
269 */
270 MOUSE_PRESSED,
271
272 /**
273 * A mouse button was released.
274 */
275 MOUSE_RELEASED,
276
277 /**
278 * A mouse button was clicked. This means the button was pressed and
279 * released.
280 */
281 MOUSE_CLICKED,
282
283 /**
284 * A double click with a mouse button was performed. This means the
285 * button was clicked twice during an OS-specific interval.
286 */
287 MOUSE_DOUBLE_CLICKED,
288
289 /**
290 * The mouse cursor entered the monitored component.
291 */
292 MOUSE_ENTERED,
293
294 /**
295 * The mouse cursor exited the monitored component.
296 */
297 MOUSE_EXITED
298 }
299 }