View Javadoc

1   /**
2    * Copyright 2010 The Kuali Foundation Licensed under the
3    * Educational Community License, Version 2.0 (the "License"); you may
4    * not use this file except in compliance with the License. You may
5    * obtain a copy of the License at
6    *
7    * http://www.osedu.org/licenses/ECL-2.0
8    *
9    * Unless required by applicable law or agreed to in writing,
10   * software distributed under the License is distributed on an "AS IS"
11   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing
13   * permissions and limitations under the License.
14   */
15  
16  package org.kuali.student.common.ui.client.widgets.focus;
17  
18  import java.util.HashMap;
19  import java.util.Map;
20  
21  import com.google.gwt.event.dom.client.BlurEvent;
22  import com.google.gwt.event.dom.client.BlurHandler;
23  import com.google.gwt.event.dom.client.FocusEvent;
24  import com.google.gwt.event.dom.client.FocusHandler;
25  import com.google.gwt.event.dom.client.HasBlurHandlers;
26  import com.google.gwt.event.dom.client.HasFocusHandlers;
27  import com.google.gwt.event.shared.GwtEvent;
28  import com.google.gwt.event.shared.HandlerManager;
29  import com.google.gwt.event.shared.HandlerRegistration;
30  import com.google.gwt.event.shared.HasHandlers;
31  import com.google.gwt.user.client.Command;
32  import com.google.gwt.user.client.DeferredCommand;
33  import com.google.gwt.user.client.ui.Widget;
34  
35  public class FocusGroup implements HasBlurHandlers, HasFocusHandlers, HasHandlers {
36  	private static class SyntheticBlurEvent extends BlurEvent {
37  		public SyntheticBlurEvent() {
38  			// do nothing
39  		}
40  	}
41  
42  	private static class SyntheticFocusEvent extends FocusEvent {
43  		public SyntheticFocusEvent() {
44  			// do nothing
45  		}
46  	}
47  
48  	private final HandlerManager handlers;
49  	private final Map<Widget, Boolean> focusTrackers = new HashMap<Widget, Boolean>();
50  	private boolean focusEventPending = false;
51  	private boolean suppressed = false;
52  	
53  	private boolean focused = false;
54  
55  	private final Command checkFocusState = new Command() {
56  		@Override
57  		public void execute() {
58  			focusEventPending = false;
59  			boolean nowFocused = false;
60  			for (final Boolean b : focusTrackers.values()) {
61  				if (b) {
62  					nowFocused = true;
63  					break;
64  				}
65  			}
66  
67  			if (!suppressed && (focused ^ nowFocused)) {
68  				if (nowFocused) {
69  					// we weren't focused, but now we are
70  					//					FocusEvent.fireNativeEvent(lastFocusEvent, FocusGroup.this);
71  					handlers.fireEvent(new SyntheticFocusEvent());
72  				} else {
73  					// we were focused, now we aren't
74  					//					BlurEvent.fireNativeEvent(lastBlurEvent, FocusGroup.this);
75  					handlers.fireEvent(new SyntheticBlurEvent());
76  				}
77  			}
78  
79  			focused = nowFocused;
80  		}
81  	};
82  
83  	public FocusGroup(final Widget parentWidget) {
84  		this.handlers = new HandlerManager(parentWidget);
85  	}
86  
87  	@Override
88  	public HandlerRegistration addBlurHandler(final BlurHandler handler) {
89  		return handlers.addHandler(BlurEvent.getType(), handler);
90  	}
91  
92  	@Override
93  	public HandlerRegistration addFocusHandler(final FocusHandler handler) {
94  		return handlers.addHandler(FocusEvent.getType(), handler);
95  	}
96  
97  	public void addWidget(final Widget w) {
98  		if (w instanceof HasBlurHandlers) {
99  			((HasBlurHandlers) w).addBlurHandler(new BlurHandler() {
100 				@Override
101 				public void onBlur(final BlurEvent event) {
102 					focusTrackers.put(w, false);
103 					queueCheckFocusState();
104 				}
105 			});
106 		}
107 		if (w instanceof HasFocusHandlers) {
108 			((HasFocusHandlers) w).addFocusHandler(new FocusHandler() {
109 				@Override
110 				public void onFocus(final FocusEvent event) {
111 					focusTrackers.put(w, true);
112 					queueCheckFocusState();
113 				}
114 			});
115 		}
116 	}
117 
118 	@Override
119 	public void fireEvent(final GwtEvent<?> event) {
120 		handlers.fireEvent(event);
121 	}
122 
123 	private void queueCheckFocusState() {
124 		if (!focusEventPending) {
125 			focusEventPending = true;
126 			DeferredCommand.addCommand(checkFocusState);
127 		}
128 	}
129 
130 	public boolean isSuppressed() {
131 		return suppressed;
132 	}
133 
134 	public void setSuppressed(boolean suppressed) {
135 		this.suppressed = suppressed;
136 	}
137 	
138 	
139 }