Crossfire JXClient, Trunk
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-2017,2019-2023 Andreas Kirschbaum
20  * Copyright (C) 2010-2012,2014-2018,2020-2023 Nicolas Weeger
21  */
22 
23 package com.realtime.crossfire.jxclient.window;
24 
31 import java.awt.event.KeyEvent;
32 import java.io.IOException;
33 import java.io.Writer;
34 import java.time.LocalDateTime;
35 import java.time.format.DateTimeFormatter;
36 import java.util.Locale;
37 import org.jetbrains.annotations.NotNull;
38 import org.jetbrains.annotations.Nullable;
39 
45 public class KeyHandler {
46 
51  @Nullable
52  private final Writer debugKeyboard;
53 
57  @NotNull
59 
63  @NotNull
64  private final CommandQueue commandQueue;
65 
69  @NotNull
71 
75  @NotNull
77 
81  @NotNull
82  private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss,SSS ", Locale.ENGLISH);
83 
87  private boolean isRunningUsingCtrl;
88 
97  public KeyHandler(@Nullable final Writer debugKeyboard, @NotNull final KeybindingsManager keybindingsManager, @NotNull final CommandQueue commandQueue, @NotNull final JXCWindowRenderer windowRenderer, @NotNull final KeyHandlerListener keyHandlerListener) {
98  this.debugKeyboard = debugKeyboard;
99  this.keybindingsManager = keybindingsManager;
100  this.commandQueue = commandQueue;
101  this.windowRenderer = windowRenderer;
102  this.keyHandlerListener = keyHandlerListener;
103  }
104 
109  public void setDefaultKeyBindings(@NotNull final KeyBindings defaultKeyBindings) {
110  keybindingsManager.setDefaultKeyBindings(defaultKeyBindings);
111  }
112 
117  private void handleKeyPress(@NotNull final KeyEvent2 e) {
118  updateModifiers(e);
119 
120  switch (e.getKeyCode()) {
121  case KeyEvent.VK_ALT:
122  case KeyEvent.VK_ALT_GRAPH:
123  case KeyEvent.VK_SHIFT:
124  case KeyEvent.VK_CONTROL:
125  debugKeyboardWrite("keyPressed: ignoring modifier key");
126  return;
127  }
128 
129  if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
130  debugKeyboardWrite("keyPressed: ESC");
132  return;
133  }
134 
136  debugKeyboardWrite("keyPressed: keybindingsManager consumed key");
137  return;
138  }
139 
140  for (Gui dialog : windowRenderer.getOpenDialogs()) {
141  if (!dialog.isHidden(windowRenderer.getGuiState())) {
142  if (dialog.handleKeyPress(e)) {
143  debugKeyboardWrite("keyPressed: dialog "+dialog+" consumed key");
144  return;
145  }
146  if (dialog.isModal()) {
147  debugKeyboardWrite("keyPressed: dialog "+dialog+" is modal");
148  return;
149  }
150  debugKeyboardWrite("keyPressed: dialog "+dialog+" didn't consume key");
151  }
152  }
153 
155  debugKeyboardWrite("keyPressed: main gui consumed key");
156  return;
157  }
158 
160  debugKeyboardWrite("keyPressed: keybindingsManager consumed key");
161  return;
162  }
163 
164  if (e.getModifiers() == KeyEvent2.NONE) {
165  switch (e.getKeyCode()) {
166  case KeyEvent.VK_0:
167  debugKeyboardWrite("keyPressed: number key");
169  break;
170 
171  case KeyEvent.VK_1:
172  debugKeyboardWrite("keyPressed: number key");
174  break;
175 
176  case KeyEvent.VK_2:
177  debugKeyboardWrite("keyPressed: number key");
179  break;
180 
181  case KeyEvent.VK_3:
182  debugKeyboardWrite("keyPressed: number key");
184  break;
185 
186  case KeyEvent.VK_4:
187  debugKeyboardWrite("keyPressed: number key");
189  break;
190 
191  case KeyEvent.VK_5:
192  debugKeyboardWrite("keyPressed: number key");
194  break;
195 
196  case KeyEvent.VK_6:
197  debugKeyboardWrite("keyPressed: number key");
199  break;
200 
201  case KeyEvent.VK_7:
202  debugKeyboardWrite("keyPressed: number key");
204  break;
205 
206  case KeyEvent.VK_8:
207  debugKeyboardWrite("keyPressed: number key");
209  break;
210 
211  case KeyEvent.VK_9:
212  debugKeyboardWrite("keyPressed: number key");
214  break;
215 
216  default:
217  debugKeyboardWrite("keyPressed: ignoring key");
218  break;
219  }
220  return;
221  }
222 
223  debugKeyboardWrite("keyPressed: ignoring key because modifiers != 0");
224  }
225 
230  private void handleKeyRelease(@NotNull final KeyEvent2 e) {
231  updateModifiers(e);
232 
233  switch (e.getKeyCode()) {
234  case KeyEvent.VK_ALT:
235  case KeyEvent.VK_ALT_GRAPH:
236  case KeyEvent.VK_SHIFT:
237  case KeyEvent.VK_CONTROL:
238  debugKeyboardWrite("keyReleased: ignoring modifier key");
239  return;
240  }
241 
242  if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
243  debugKeyboardWrite("keyReleased: ignoring ESC");
244  return;
245  }
246 
248  debugKeyboardWrite("keyReleased: keybindingsManager consumed key");
250  return;
251  }
252 
253  debugKeyboardWrite("keyReleased: ignoring key");
254  }
255 
260  public void keyPressed(@NotNull final KeyEvent e) {
261  final KeyEvent2 keyEvent = new KeyEvent2(e.getKeyCode(), e.getKeyChar(), e.getModifiersEx());
262  debugKeyboardWrite("pressed", e, keyEvent);
263  try {
264  handleKeyPress(keyEvent);
265  } finally {
266  debugKeyboardWrite("");
267  }
268  }
269 
274  public void keyReleased(@NotNull final KeyEvent e) {
275  final KeyEvent2 keyEvent = new KeyEvent2(e.getKeyCode(), e.getKeyChar(), e.getModifiersEx());
276  debugKeyboardWrite("released", e, keyEvent);
277  try {
278  handleKeyRelease(keyEvent);
279  } finally {
280  debugKeyboardWrite("");
281  }
282  }
283 
288  private void updateModifiers(@NotNull final KeyEvent2 keyEvent) {
289  if ((keyEvent.getModifiers()&KeyEvent2.CTRL) == 0 && isRunningUsingCtrl && commandQueue.stopRunning()) {
290  debugKeyboardWrite("updateModifiers: stopping run");
291  isRunningUsingCtrl = false;
292  }
293  if ((keyEvent.getModifiers()&KeyEvent2.CTRL) != 0) {
294  isRunningUsingCtrl = true;
295  }
296  }
297 
304  private void debugKeyboardWrite(@NotNull final String type, @NotNull final KeyEvent keyEvent, @NotNull final KeyEvent2 keyEvent2) {
305  if (debugKeyboard == null) {
306  return;
307  }
308 
309  debugKeyboardWrite(type+" "+keyEvent2+" "+keyEvent);
310  }
311 
316  private void debugKeyboardWrite(@NotNull final CharSequence message) {
317  if (debugKeyboard == null) {
318  return;
319  }
320 
321  try {
322  debugKeyboard.append(FORMATTER.format(LocalDateTime.now()));
323  debugKeyboard.append(message);
324  debugKeyboard.append("\n");
325  debugKeyboard.flush();
326  } catch (final IOException ex) {
327  System.err.println("Cannot write keyboard debug: "+ex.getMessage());
328  System.exit(1);
329  throw new AssertionError(ex);
330  }
331  }
332 
337  public boolean isRunningUsingCtrl() {
338  return isRunningUsingCtrl;
339  }
340 
341 }
com.realtime.crossfire.jxclient
com.realtime.crossfire.jxclient.window.KeyHandler.updateModifiers
void updateModifiers(@NotNull final KeyEvent2 keyEvent)
Definition: KeyHandler.java:288
com.realtime.crossfire.jxclient.gui.keybindings.KeyEvent2
Definition: KeyEvent2.java:34
com.realtime.crossfire.jxclient.window.KeyHandler.isRunningUsingCtrl
boolean isRunningUsingCtrl
Definition: KeyHandler.java:87
com.realtime.crossfire.jxclient.gui.gui.Gui
Definition: Gui.java:49
com.realtime.crossfire.jxclient.window.KeyHandler.debugKeyboardWrite
void debugKeyboardWrite(@NotNull final CharSequence message)
Definition: KeyHandler.java:316
com.realtime.crossfire.jxclient.window.KeyHandler.keyHandlerListener
final KeyHandlerListener keyHandlerListener
Definition: KeyHandler.java:76
com.realtime.crossfire.jxclient.queue.CommandQueue.addToRepeatCount
void addToRepeatCount(final int digit)
Definition: CommandQueue.java:159
com.realtime.crossfire.jxclient.gui.keybindings.KeybindingsManager.setDefaultKeyBindings
void setDefaultKeyBindings(@NotNull final KeyBindings defaultKeyBindings)
Definition: KeybindingsManager.java:108
com.realtime.crossfire.jxclient.window.KeyHandler.keybindingsManager
final KeybindingsManager keybindingsManager
Definition: KeyHandler.java:58
com.realtime.crossfire.jxclient.window.KeyHandlerListener
Definition: KeyHandlerListener.java:29
com.realtime.crossfire.jxclient.window.KeyHandler.debugKeyboardWrite
void debugKeyboardWrite(@NotNull final String type, @NotNull final KeyEvent keyEvent, @NotNull final KeyEvent2 keyEvent2)
Definition: KeyHandler.java:304
com.realtime.crossfire.jxclient.gui.keybindings.KeyEvent2.CTRL
static final int CTRL
Definition: KeyEvent2.java:54
com.realtime.crossfire.jxclient.window.KeyHandler.commandQueue
final CommandQueue commandQueue
Definition: KeyHandler.java:64
com.realtime.crossfire.jxclient.window.KeyHandler
Definition: KeyHandler.java:45
com.realtime.crossfire.jxclient.gui.keybindings
Definition: InvalidKeyBindingException.java:23
com.realtime.crossfire.jxclient.window.KeyHandler.keyReleased
void keyReleased(@NotNull final KeyEvent e)
Definition: KeyHandler.java:274
com.realtime.crossfire.jxclient.window.KeyHandlerListener.escPressed
void escPressed()
com.realtime.crossfire.jxclient.gui.misc.JXCWindowRenderer
Definition: JXCWindowRenderer.java:87
com.realtime.crossfire.jxclient.window.KeyHandler.windowRenderer
final JXCWindowRenderer windowRenderer
Definition: KeyHandler.java:70
com.realtime.crossfire.jxclient.gui.misc.JXCWindowRenderer.getOpenDialogs
Iterable< Gui > getOpenDialogs()
Definition: JXCWindowRenderer.java:738
com.realtime.crossfire.jxclient.gui.keybindings.KeybindingsManager.handleKeyPress
boolean handleKeyPress(@NotNull final KeyEvent2 e)
Definition: KeybindingsManager.java:262
com.realtime.crossfire.jxclient.window.KeyHandler.handleKeyPress
void handleKeyPress(@NotNull final KeyEvent2 e)
Definition: KeyHandler.java:117
com.realtime.crossfire.jxclient.gui.misc.JXCWindowRenderer.handleKeyPress
boolean handleKeyPress(@NotNull final KeyEvent2 e)
Definition: JXCWindowRenderer.java:1069
com.realtime.crossfire.jxclient.window.KeyHandler.keyPressed
void keyPressed(@NotNull final KeyEvent e)
Definition: KeyHandler.java:260
com.realtime.crossfire.jxclient.gui
com.realtime.crossfire.jxclient.queue.CommandQueue
Definition: CommandQueue.java:38
com.realtime.crossfire.jxclient.queue.CommandQueue.stopRunning
boolean stopRunning()
Definition: CommandQueue.java:269
com.realtime.crossfire.jxclient.gui.misc.JXCWindowRenderer.getGuiState
RendererGuiState getGuiState()
Definition: JXCWindowRenderer.java:857
com.realtime.crossfire.jxclient.window.KeyHandler.FORMATTER
static final DateTimeFormatter FORMATTER
Definition: KeyHandler.java:82
com.realtime.crossfire.jxclient.gui.keybindings.KeybindingsManager.keyReleased
boolean keyReleased()
Definition: KeybindingsManager.java:216
com.realtime.crossfire.jxclient.window.KeyHandler.setDefaultKeyBindings
void setDefaultKeyBindings(@NotNull final KeyBindings defaultKeyBindings)
Definition: KeyHandler.java:109
com.realtime.crossfire.jxclient.gui.gui
Definition: AbstractGUIElement.java:23
com.realtime.crossfire.jxclient.queue
Definition: CommandQueue.java:23
com.realtime.crossfire.jxclient.window.KeyHandler.handleKeyRelease
void handleKeyRelease(@NotNull final KeyEvent2 e)
Definition: KeyHandler.java:230
com.realtime.crossfire
com.realtime
com.realtime.crossfire.jxclient.window.KeyHandler.KeyHandler
KeyHandler(@Nullable final Writer debugKeyboard, @NotNull final KeybindingsManager keybindingsManager, @NotNull final CommandQueue commandQueue, @NotNull final JXCWindowRenderer windowRenderer, @NotNull final KeyHandlerListener keyHandlerListener)
Definition: KeyHandler.java:97
com
com.realtime.crossfire.jxclient.window.KeyHandler.isRunningUsingCtrl
boolean isRunningUsingCtrl()
Definition: KeyHandler.java:337
com.realtime.crossfire.jxclient.gui.keybindings.KeyBindings
Definition: KeyBindings.java:47
com.realtime.crossfire.jxclient.gui.keybindings.KeyEvent2.NONE
static final int NONE
Definition: KeyEvent2.java:39
com.realtime.crossfire.jxclient.window.KeyHandlerListener.keyReleased
void keyReleased()
com.realtime.crossfire.jxclient.gui.misc
Definition: GUICheckBox.java:23
com.realtime.crossfire.jxclient.gui.keybindings.KeybindingsManager.keyPressed
boolean keyPressed(@NotNull final KeyEvent2 keyEvent)
Definition: KeybindingsManager.java:234
com.realtime.crossfire.jxclient.window.KeyHandler.debugKeyboard
final Writer debugKeyboard
Definition: KeyHandler.java:52
com.realtime.crossfire.jxclient.gui.keybindings.KeybindingsManager
Definition: KeybindingsManager.java:40