001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Dmitry A. Durnev
019: * @version $Revision$
020: */package org.apache.harmony.awt;
021:
022: import java.awt.Component;
023: import java.awt.event.FocusEvent;
024: import java.awt.event.FocusListener;
025: import java.awt.event.KeyEvent;
026: import java.awt.event.KeyListener;
027: import java.awt.event.MouseEvent;
028: import java.awt.event.MouseListener;
029:
030: import org.apache.harmony.awt.internal.nls.Messages;
031:
032: /**
033: * ButtonStateController.
034: * Changes Component state and fires [action] events in response to
035: * user input(key, mouse, focus events) and current state.
036: * Repaints component when necessary.
037: * Is typically used by Components such as Button, Checkbox, etc
038: * as input event listener. Such components also query their state
039: * properties, which are not stored in the Component-derived class,
040: * for example isPressed(), with state controller.
041: */
042: public abstract class ButtonStateController implements MouseListener,
043: FocusListener, KeyListener {
044:
045: private static Component activeComponent;
046:
047: private boolean mousePressed = false;
048: private boolean keyPressed = false;
049: private boolean mouseInside = false;
050: private boolean focused = false;
051: private final Component component;
052:
053: /**
054: * Store input event properties
055: * to be able to retrieve them later
056: * inside fireEvent() implementation
057: * which typically uses them to
058: * fire action/item event
059: */
060: private long when;
061: private int mod;
062:
063: public ButtonStateController(Component comp) {
064: component = comp;
065: }
066:
067: public boolean isPressed() {
068: return ((mousePressed && mouseInside) || keyPressed);
069: }
070:
071: public void mousePressed(MouseEvent me) {
072: if (mousePressed || keyPressed
073: || (me.getButton() != MouseEvent.BUTTON1) || !lock()) {
074: return;
075: }
076:
077: mousePressed = true;
078:
079: if (mouseInside) {
080: component.repaint();
081: }
082:
083: if (component.isFocusable()) {
084: component.requestFocus();
085: }
086: }
087:
088: public void mouseReleased(MouseEvent me) {
089: if (!mousePressed || (me.getButton() != MouseEvent.BUTTON1)
090: || !unlock()) {
091: return;
092: }
093:
094: mousePressed = false;
095: component.repaint();
096:
097: if (mouseInside) {
098: when = me.getWhen();
099: mod = me.getModifiers();
100: fireEvent();
101: }
102: }
103:
104: public void keyPressed(KeyEvent ke) {
105: // awt.54=Key event for unfocused component
106: assert focused == true : Messages.getString("awt.54"); //$NON-NLS-1$
107:
108: if (mousePressed || keyPressed
109: || (ke.getKeyCode() != KeyEvent.VK_SPACE) || !lock()) {
110: return;
111: }
112:
113: keyPressed = true;
114: component.repaint();
115: }
116:
117: public void keyReleased(KeyEvent ke) {
118: // awt.54=Key event for unfocused component
119: assert focused == true : Messages.getString("awt.54"); //$NON-NLS-1$
120:
121: if (!keyPressed || (ke.getKeyCode() != KeyEvent.VK_SPACE)
122: || !unlock()) {
123: return;
124: }
125:
126: keyPressed = false;
127: component.repaint();
128: when = ke.getWhen();
129: mod = ke.getModifiers();
130: fireEvent();
131: }
132:
133: public void mouseEntered(MouseEvent me) {
134: // awt.55=Double mouse enter event for component
135: assert mouseInside == false : Messages.getString("awt.55"); //$NON-NLS-1$
136: mouseCrossed(true);
137: }
138:
139: public void mouseExited(MouseEvent me) {
140: // awt.56=Double mouse exit event for component
141: assert mouseInside == true : Messages.getString("awt.56"); //$NON-NLS-1$
142: mouseCrossed(false);
143: }
144:
145: public void focusGained(FocusEvent fe) {
146: // awt.57=Double focus gained event for component
147: assert focused == false : Messages.getString("awt.57"); //$NON-NLS-1$
148:
149: focused = true;
150: component.repaint();
151: }
152:
153: public void focusLost(FocusEvent fe) {
154: // awt.58=Double focus lost event for component
155: assert focused == true : Messages.getString("awt.58"); //$NON-NLS-1$
156:
157: unlock();
158: focused = false;
159: keyPressed = false;
160: mousePressed = false;
161: component.repaint();
162: }
163:
164: //Ignored
165: public void keyTyped(KeyEvent ke) {
166: }
167:
168: public void mouseClicked(MouseEvent me) {
169: }
170:
171: private void mouseCrossed(boolean inside) {
172: mouseInside = inside;
173: if (mousePressed && focused) {
174: component.repaint();
175: }
176: }
177:
178: public final long getWhen() {
179: return when;
180: }
181:
182: public final int getMod() {
183: return mod;
184: }
185:
186: protected abstract void fireEvent();
187:
188: /**
189: * Acquires the lock for this button. If the lock is acquired no other
190: * buttons could be pressed until the lock is released.
191: *
192: * @return true if the lock has been successfully acquired, otherwise
193: * returns false.
194: */
195: private boolean lock() {
196: if (activeComponent != null) {
197: return false;
198: }
199:
200: activeComponent = component;
201: return true;
202: }
203:
204: /**
205: * Releases the lock.
206: *
207: * @return true if the lock has been released, otherwise returns false.
208: */
209: private boolean unlock() {
210: if (activeComponent != component) {
211: return false;
212: }
213:
214: activeComponent = null;
215: return true;
216: }
217: }
|