Crossfire JXClient, Trunk  R20561
KeyHandler.java
Go to the documentation of this file.
1 /*
2  * This file is part of JXClient, the Fullscreen Java Crossfire Client.
3  *
4  * JXClient is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * JXClient is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with JXClient; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  * Copyright (C) 2005-2008 Yann Chachkoff.
19  * Copyright (C) 2006-2011 Andreas Kirschbaum.
20  */
21 
22 package com.realtime.crossfire.jxclient.window;
23 
30 import java.awt.event.KeyEvent;
31 import java.io.IOException;
32 import java.io.Writer;
33 import java.text.DateFormat;
34 import java.text.SimpleDateFormat;
35 import java.util.Date;
36 import org.jetbrains.annotations.NotNull;
37 import org.jetbrains.annotations.Nullable;
38 
44 public class KeyHandler {
45 
50  @Nullable
51  private final Writer debugKeyboard;
52 
56  @NotNull
58 
62  @NotNull
63  private final CommandQueue commandQueue;
64 
68  @NotNull
70 
74  @NotNull
76 
80  @NotNull
81  private final DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS ");
82 
87  @Nullable
89 
98  public KeyHandler(@Nullable final Writer debugKeyboard, @NotNull final KeybindingsManager keybindingsManager, @NotNull final CommandQueue commandQueue, @NotNull final JXCWindowRenderer windowRenderer, @NotNull final KeyHandlerListener keyHandlerListener) {
99  this.debugKeyboard = debugKeyboard;
100  this.keybindingsManager = keybindingsManager;
101  this.commandQueue = commandQueue;
102  this.windowRenderer = windowRenderer;
103  this.keyHandlerListener = keyHandlerListener;
104  }
105 
110  @SuppressWarnings("NullableProblems")
111  public void setKeyBindings(@NotNull final KeyBindings keyBindings) {
112  this.keyBindings = keyBindings;
113  }
114 
119  private void handleKeyPress(@NotNull final KeyEvent2 e) {
120  updateModifiers(e);
121 
122  switch (e.getKeyCode()) {
123  case KeyEvent.VK_ALT:
124  case KeyEvent.VK_ALT_GRAPH:
125  case KeyEvent.VK_SHIFT:
126  case KeyEvent.VK_CONTROL:
127  debugKeyboardWrite("keyPressed: ignoring modifier key");
128  return;
129  }
130 
131  if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
132  debugKeyboardWrite("keyPressed: ESC");
134  return;
135  }
136 
138  debugKeyboardWrite("keyPressed: keybindingsManager consumed key");
139  return;
140  }
141 
142  for (final Gui dialog : windowRenderer.getOpenDialogs()) {
143  if (!dialog.isHidden(windowRenderer.getGuiState())) {
144  if (dialog.handleKeyPress(e)) {
145  debugKeyboardWrite("keyPressed: dialog "+dialog+" consumed key");
146  return;
147  }
148  if (dialog.isModal()) {
149  debugKeyboardWrite("keyPressed: dialog "+dialog+" is modal");
150  return;
151  }
152  debugKeyboardWrite("keyPressed: dialog "+dialog+" didn't consume key");
153  }
154  }
155 
157  debugKeyboardWrite("keyPressed: main gui consumed key");
158  return;
159  }
160 
162  debugKeyboardWrite("keyPressed: keybindingsManager consumed key");
163  return;
164  }
165 
166  if (keyBindings != null && keyBindings.handleKeyPress(e)) {
167  debugKeyboardWrite("keyPressed: skin default key bindings consumed key");
168  return;
169  }
170 
171  if (e.getModifiers() == KeyEvent2.NONE) {
172  switch (e.getKeyCode()) {
173  case KeyEvent.VK_0:
174  debugKeyboardWrite("keyPressed: number key");
176  break;
177 
178  case KeyEvent.VK_1:
179  debugKeyboardWrite("keyPressed: number key");
181  break;
182 
183  case KeyEvent.VK_2:
184  debugKeyboardWrite("keyPressed: number key");
186  break;
187 
188  case KeyEvent.VK_3:
189  debugKeyboardWrite("keyPressed: number key");
191  break;
192 
193  case KeyEvent.VK_4:
194  debugKeyboardWrite("keyPressed: number key");
196  break;
197 
198  case KeyEvent.VK_5:
199  debugKeyboardWrite("keyPressed: number key");
201  break;
202 
203  case KeyEvent.VK_6:
204  debugKeyboardWrite("keyPressed: number key");
206  break;
207 
208  case KeyEvent.VK_7:
209  debugKeyboardWrite("keyPressed: number key");
211  break;
212 
213  case KeyEvent.VK_8:
214  debugKeyboardWrite("keyPressed: number key");
216  break;
217 
218  case KeyEvent.VK_9:
219  debugKeyboardWrite("keyPressed: number key");
221  break;
222 
223  default:
224  debugKeyboardWrite("keyPressed: ignoring key");
225  break;
226  }
227  return;
228  }
229 
230  debugKeyboardWrite("keyPressed: ignoring key because modifiers != 0");
231  }
232 
237  private void handleKeyRelease(@NotNull final KeyEvent2 e) {
238  updateModifiers(e);
239 
240  switch (e.getKeyCode()) {
241  case KeyEvent.VK_ALT:
242  case KeyEvent.VK_ALT_GRAPH:
243  case KeyEvent.VK_SHIFT:
244  case KeyEvent.VK_CONTROL:
245  debugKeyboardWrite("keyReleased: ignoring modifier key");
246  return;
247  }
248 
249  if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
250  debugKeyboardWrite("keyReleased: ignoring ESC");
251  return;
252  }
253 
255  debugKeyboardWrite("keyReleased: keybindingsManager consumed key");
257  return;
258  }
259 
260  debugKeyboardWrite("keyReleased: ignoring key");
261  }
262 
267  public void keyPressed(@NotNull final KeyEvent e) {
268  final KeyEvent2 keyEvent = new KeyEvent2(e.getKeyCode(), e.getKeyChar(), e.getModifiers());
269  debugKeyboardWrite("pressed", e, keyEvent);
270  try {
271  handleKeyPress(keyEvent);
272  } finally {
273  debugKeyboardWrite("");
274  }
275  }
276 
281  public void keyReleased(@NotNull final KeyEvent e) {
282  final KeyEvent2 keyEvent = new KeyEvent2(e.getKeyCode(), e.getKeyChar(), e.getModifiers());
283  debugKeyboardWrite("released", e, keyEvent);
284  try {
285  handleKeyRelease(keyEvent);
286  } finally {
287  debugKeyboardWrite("");
288  }
289  }
290 
295  private void updateModifiers(@NotNull final KeyEvent2 keyEvent) {
296  if ((keyEvent.getModifiers()&KeyEvent2.CTRL) == 0 && commandQueue.stopRunning()) {
297  debugKeyboardWrite("updateModifiers: stopping run");
298  }
299  }
300 
307  private void debugKeyboardWrite(@NotNull final String type, @NotNull final KeyEvent keyEvent, @NotNull final KeyEvent2 keyEvent2) {
308  if (debugKeyboard == null) {
309  return;
310  }
311 
312  debugKeyboardWrite(type+" "+keyEvent2+" "+keyEvent);
313  }
314 
319  private void debugKeyboardWrite(@NotNull final CharSequence message) {
320  if (debugKeyboard == null) {
321  return;
322  }
323 
324  try {
325  debugKeyboard.append(simpleDateFormat.format(new Date()));
326  debugKeyboard.append(message);
327  debugKeyboard.append("\n");
328  debugKeyboard.flush();
329  } catch (final IOException ex) {
330  System.err.println("Cannot write keyboard debug: "+ex.getMessage());
331  System.exit(1);
332  throw new AssertionError(ex);
333  }
334  }
335 
336 }
void setKeyBindings(@NotNull final KeyBindings keyBindings)
Sets the active KeyBindings.
Combines a list of GUIElements to for a gui.
Definition: Gui.java:43
Interface for listeners interested in pressed ESC keys.
void keyPressed(@NotNull final KeyEvent e)
Handles a "key pressed" event.
void handleKeyRelease(@NotNull final KeyEvent2 e)
Handles a "key released" event.
final KeybindingsManager keybindingsManager
The KeybindingsManager to use.
Definition: KeyHandler.java:57
boolean stopRunning()
Tells the server to stop running.
void escPressed()
The ESC key has been pressed.
void keyReleased()
A key (but not ESC) has been released.
Iterable< Gui > getOpenDialogs()
Returns all open dialogs in reverse painting order; the first element is the top-most dialog...
RendererGuiState getGuiState()
Returns the current gui state.
final CommandQueue commandQueue
The CommandQueue to use.
Definition: KeyHandler.java:63
KeyBindings keyBindings
The active KeyBindings.
Definition: KeyHandler.java:88
Represents a pressed or released key.
Definition: KeyEvent2.java:33
void debugKeyboardWrite(@NotNull final CharSequence message)
Writes a message to the keyboard debug.
boolean handleKeyPress(@NotNull final KeyEvent2 e)
Processes a key pressed event.
boolean handleKeyPress(@NotNull final KeyEvent2 e)
Dispatches a key press KeyEvent.
void addToRepeatCount(final int digit)
Adds a digit to the current repeat count.
void debugKeyboardWrite(@NotNull final String type, @NotNull final KeyEvent keyEvent, @NotNull final KeyEvent2 keyEvent2)
Writes a KeyEvent to the keyboard debug.
Handles keyboard input processing.
Definition: KeyHandler.java:44
void handleKeyPress(@NotNull final KeyEvent2 e)
Handles a "key pressed" event.
void updateModifiers(@NotNull final KeyEvent2 keyEvent)
Updates the saved modifier state from a key event.
static final int CTRL
The mask for "ctrl".
Definition: KeyEvent2.java:53
final Writer debugKeyboard
The Writer for logging keyboard debug output.
Definition: KeyHandler.java:51
static final int NONE
The mask for "no modifier".
Definition: KeyEvent2.java:38
Maintains the pending (ncom) commands sent to the server.
KeyHandler(@Nullable final Writer debugKeyboard, @NotNull final KeybindingsManager keybindingsManager, @NotNull final CommandQueue commandQueue, @NotNull final JXCWindowRenderer windowRenderer, @NotNull final KeyHandlerListener keyHandlerListener)
Creates a new instance.
Definition: KeyHandler.java:98
boolean keyPressed(@NotNull final KeyEvent2 keyEvent)
Processes a key pressed event.
final KeyHandlerListener keyHandlerListener
The KeyHandlerListener to notify.
Definition: KeyHandler.java:75
final DateFormat simpleDateFormat
A formatter for timestamps.
Definition: KeyHandler.java:81
final JXCWindowRenderer windowRenderer
The JXCWindowRenderer to use.
Definition: KeyHandler.java:69
void keyReleased(@NotNull final KeyEvent e)
Handles a "key released" event.
boolean handleKeyPress(@NotNull final KeyEvent2 e)
Executes a "key press" event.