KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > core > windows > view > ui > slides > SlideGestureRecognizer


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.core.windows.view.ui.slides;
21
22 import java.awt.AWTEvent JavaDoc;
23 import java.awt.Component JavaDoc;
24 import java.awt.Point JavaDoc;
25 import java.awt.Rectangle JavaDoc;
26 import java.awt.Toolkit JavaDoc;
27 import java.awt.Window JavaDoc;
28 import java.awt.event.AWTEventListener JavaDoc;
29 import java.awt.event.ActionEvent JavaDoc;
30 import java.awt.event.ActionListener JavaDoc;
31 import java.awt.event.MouseAdapter JavaDoc;
32 import java.awt.event.MouseEvent JavaDoc;
33 import java.awt.event.MouseListener JavaDoc;
34 import java.awt.event.MouseMotionListener JavaDoc;
35 import java.beans.PropertyChangeEvent JavaDoc;
36 import java.beans.PropertyChangeListener JavaDoc;
37 import java.util.List JavaDoc;
38 import javax.swing.AbstractButton JavaDoc;
39 import javax.swing.SwingUtilities JavaDoc;
40 import javax.swing.Timer JavaDoc;
41 import org.netbeans.swing.tabcontrol.SlideBarDataModel;
42 import org.openide.util.WeakListeners;
43 import org.openide.windows.TopComponent;
44
45 /* Listens to user actions that trigger sliding operation such as slide in
46  * slide out or popup menu action to be invoked.
47  *
48  * @author Dafe Simonek
49  */

50 final class SlideGestureRecognizer implements ActionListener JavaDoc, MouseListener JavaDoc, MouseMotionListener JavaDoc {
51     /** container of sliding buttons */
52     private SlideBar slideBar;
53     /** button in which area mouse pointer is or null */
54     private Component JavaDoc mouseInButton = null;
55     /** current location of mouse pointer */
56     private int curMouseLocX, curMouseLocY;
57     
58     /** Listsner to timer notifications */
59     private AutoSlideTrigger autoSlideTrigger = new AutoSlideTrigger();
60     private ResizeGestureRecognizer resizer;
61     private boolean pressingButton = false;
62
63     SlideGestureRecognizer(SlideBar slideBar, ResizeGestureRecognizer resize) {
64         this.slideBar = slideBar;
65         resizer = resize;
66     }
67
68     /** Attaches given button to this recognizer, it means starts listening
69      * on its various mouse and action events
70      */

71     public void attachButton (AbstractButton JavaDoc button) {
72         button.addActionListener(this);
73         button.addMouseListener(this);
74         button.addMouseMotionListener(this);
75     }
76     
77     /** Detaches given button from this recognizer, it means stops listening
78      * on its various mouse and action events
79      */

80     public void detachButton (AbstractButton JavaDoc button) {
81         button.removeActionListener(this);
82         button.removeMouseListener(this);
83         button.addMouseMotionListener(this);
84     }
85
86     /** Reaction to user press on some of the slide buttons */
87     public void actionPerformed(ActionEvent JavaDoc e) {
88         slideBar.userClickedSlidingButton((Component JavaDoc)e.getSource());
89     }
90
91     /** Tracks mouse pointer location */
92     public void mouseMoved(MouseEvent JavaDoc e) {
93         if (autoSlideTrigger.isEnabled()) {
94             curMouseLocX = e.getX();
95             curMouseLocY = e.getY();
96         }
97         // #54764 - start
98
if (pressingButton && (e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == 0) {
99             pressingButton = false;
100             autoSlideTrigger.activateAutoSlideInGesture();
101         }
102         // #54764 - end
103
}
104
105     /** Activates automatic slide in system */
106     public void mouseEntered(MouseEvent JavaDoc e) {
107         if (!slideBar.isHoveringAllowed()) {
108             // don't even try to trigger automatic sliding when focused slide is active
109
return;
110         }
111         mouseInButton = (Component JavaDoc)e.getSource();
112         curMouseLocX = e.getX();
113         curMouseLocY = e.getY();
114         pressingButton =false;
115         // #54764 - start
116
if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == MouseEvent.BUTTON1_DOWN_MASK) {
117             pressingButton = true;
118             return;
119         }
120         // #54764 - end
121
autoSlideTrigger.activateAutoSlideInGesture();
122     }
123
124     /** Deactivates automatic slide in listening */
125     public void mouseExited(MouseEvent JavaDoc e) {
126         mouseInButton = null;
127         pressingButton = false;
128         autoSlideTrigger.deactivateAutoSlideInGesture();
129     }
130     
131     /** Reacts to popup triggers on sliding buttons */
132     public void mousePressed(MouseEvent JavaDoc e) {
133         autoSlideTrigger.deactivateAutoSlideInGesture();
134         handlePopupRequests(e);
135     }
136     
137     /** Reacts to popup triggers on sliding buttons */
138     public void mouseReleased(MouseEvent JavaDoc e) {
139         autoSlideTrigger.deactivateAutoSlideInGesture();
140         handlePopupRequests(e);
141     }
142     
143     public void mouseDragged(MouseEvent JavaDoc e) {
144         // no operation
145
}
146     
147     public void mouseClicked(MouseEvent JavaDoc e) {
148         // no operation
149
}
150     
151     /** Sends message to show popup menu on button if conditions are met */
152     private void handlePopupRequests (MouseEvent JavaDoc e) {
153         // don't react on popup triggers on whole bar
154
if (e.getSource().equals(slideBar)) {
155             return;
156         }
157         
158         if (e.isPopupTrigger()) {
159             slideBar.userTriggeredPopup(e, (Component JavaDoc)e.getSource());
160         }
161     }
162
163     /** Listen to timer notifications and mouse AWT events to start/stop
164      * auto slide in/slide out operation */

165     private final class AutoSlideTrigger implements ActionListener JavaDoc, AWTEventListener JavaDoc {
166         
167         /** timer for triggering slide in after mouse stops for a while */
168         private Timer JavaDoc slideInTimer;
169         /** location of mouse pointer in last timer cycle */
170         private int initialX, initialY;
171         /** true when auto slide-in was performed and is visible, false ootherwise */
172         private boolean autoSlideActive = false;
173         /** union of slide bar and slided component bounds;
174          escape of mouse pointer from this area means auto slide out to be triggered */

175         private Rectangle JavaDoc activeArea;
176         
177         AutoSlideTrigger() {
178             super();
179             slideInTimer = new Timer JavaDoc(200, this);
180             slideInTimer.setRepeats(true);
181             slideInTimer.setCoalesce(true);
182         }
183
184         /** Starts listening to user events that may lead to automatic slide in */
185         public void activateAutoSlideInGesture() {
186             initialX = curMouseLocX;
187             initialY = curMouseLocY;
188             slideInTimer.start();
189         }
190         
191         /** Stops listening to user events that may lead to automatic slide in */
192         public void deactivateAutoSlideInGesture() {
193             slideInTimer.stop();
194         }
195
196         /** @return true when auto slide system is listening and active, false ootherwise */
197         public boolean isEnabled() {
198             return autoSlideActive || slideInTimer.isRunning();
199         }
200
201         /** Action listener implementation - reacts to timer notification, which
202          * means we should check conditions and perform auto slide in if appropriate
203          */

204         public void actionPerformed(ActionEvent JavaDoc evt) {
205             if (isSlideInGesture()) {
206                 slideInTimer.stop();
207                 // multiple auto slide in requests, get rid of old one first
208
if (autoSlideActive) {
209                     autoSlideOut();
210                 }
211                 autoSlideActive = true;
212                 // #45494 - rarely, mouseInButton value can be out of sync
213
// with SlideBar buttons array, and we don't slide in in such case
214
if (slideBar.userTriggeredAutoSlideIn(mouseInButton)) {
215                     Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.MOUSE_MOTION_EVENT_MASK);
216                 } else {
217                     autoSlideActive = false;
218                 }
219             } else {
220                 initialX = curMouseLocX;
221                 initialY = curMouseLocY;
222             }
223         }
224
225         /** AWTEventListener implementation. Analyzes incoming mouse motion
226          * and initiates automatic slide out when needed.
227          */

228         public void eventDispatched(AWTEvent JavaDoc event) {
229             autoSlideOutIfNeeded((MouseEvent JavaDoc)event);
230         }
231         
232         /** Checks conditions and runs auto slide out if needed.
233          */

234         private void autoSlideOutIfNeeded(MouseEvent JavaDoc evt) {
235             if (!autoSlideActive) {
236                 // ignore pending events that came later after cleanup
237
return;
238             }
239             if (slideBar.isActive()) {
240                 // if slide bar is active (focused), we should do no more automatic things
241
cleanup();
242                 return;
243             }
244             if (isSlideOutGesture(evt)) {
245                 cleanup();
246                 autoSlideOut();
247             }
248         }
249
250         /** Actually performs slide out by notifying slide bar */
251         private void autoSlideOut() {
252             slideBar.userTriggeredAutoSlideOut();
253         }
254
255         /** Removea all attached listeners and generally stops to try run
256          * sliding automatically */

257         private void cleanup() {
258             Toolkit.getDefaultToolkit().removeAWTEventListener(this);
259             autoSlideActive = false;
260             activeArea = null;
261         }
262         
263         /** @return true when conditions for auto slide IN were met, false otherwise */
264         private boolean isSlideInGesture () {
265             if (mouseInButton == null) {
266                 return false;
267             }
268             
269             int diffX = Math.abs(initialX - curMouseLocX);
270             int diffY = Math.abs(initialY - curMouseLocY);
271             
272             return (diffX <= 2) && (diffY <= 2);
273         }
274         
275         /** @return true when conditions for auto slide OUT were met, false otherwise */
276         private boolean isSlideOutGesture(MouseEvent JavaDoc evt) {
277             if (resizer.isDragging()) {
278                 activeArea = null;
279                 return false;
280             }
281             if (activeArea == null) {
282                 activeArea = computeActiveArea();
283                 // comps are not yet ready, so do nothing
284
if (activeArea == null) {
285                     return false;
286                 }
287             }
288             Point JavaDoc mouseLoc = evt.getPoint();
289             SwingUtilities.convertPointToScreen(mouseLoc, (Component JavaDoc)evt.getSource());
290
291             return !activeArea.contains(mouseLoc);
292         }
293
294         /** @return Area in which automatic slide in is preserved. Can return
295          * null signalizing that components making active area bounds are not yet
296          * ready or showing.
297          */

298         private Rectangle JavaDoc computeActiveArea() {
299             Component JavaDoc slidedComp = slideBar.getSlidedComp();
300             if (slidedComp == null || !slidedComp.isShowing()) {
301                 return null;
302             }
303             
304             Point JavaDoc slideBarLoc = slideBar.getLocationOnScreen();
305             Rectangle JavaDoc actArea = new Rectangle JavaDoc(slideBarLoc.x - 1, slideBarLoc.y - 1,
306                                     slideBar.getWidth() - 1, slideBar.getHeight() - 1);
307             
308             Point JavaDoc slidedCompLoc = slidedComp.getLocationOnScreen();
309             
310             int slidex = slidedCompLoc.x;
311             int slidey = slidedCompLoc.y;
312             int slideh = slidedComp.getHeight();
313             int slidew = slidedComp.getWidth();
314             int orientation = slideBar.getModel().getOrientation();
315             if (orientation == SlideBarDataModel.WEST) {
316                 slidew = slidew + ResizeGestureRecognizer.RESIZE_BUFFER;
317             }
318             if (orientation == SlideBarDataModel.EAST) {
319                 slidew = slidew + ResizeGestureRecognizer.RESIZE_BUFFER;
320                 slidex = slidex - ResizeGestureRecognizer.RESIZE_BUFFER;
321             }
322             if (orientation == SlideBarDataModel.SOUTH) {
323                 slideh = slideh + ResizeGestureRecognizer.RESIZE_BUFFER;
324                 slidey = slidey - ResizeGestureRecognizer.RESIZE_BUFFER;
325             }
326             actArea = SwingUtilities.computeUnion(
327                 slidex, slidey, slidew,
328                 slideh, actArea);
329             
330             return actArea;
331         }
332         
333         
334     } // AutoSlideTrigger
335

336 }
Popular Tags