Skip to content

Commit bf2e396

Browse files
committed
[#314] zx-spectrum: keyboard handling wip
1 parent c7c8691 commit bf2e396

File tree

5 files changed

+163
-186
lines changed

5 files changed

+163
-186
lines changed

plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/DeviceImpl.java

+1-7
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,8 @@
2323
import net.emustudio.emulib.plugins.annotations.PluginRoot;
2424
import net.emustudio.emulib.plugins.device.AbstractDevice;
2525
import net.emustudio.emulib.runtime.ApplicationApi;
26-
import net.emustudio.emulib.runtime.interaction.GuiUtils;
2726
import net.emustudio.emulib.runtime.settings.PluginSettings;
2827
import net.emustudio.plugins.device.zxspectrum.bus.api.ZxSpectrumBus;
29-
import net.emustudio.plugins.device.zxspectrum.ula.gui.Keyboard;
3028
import net.emustudio.plugins.device.zxspectrum.ula.gui.DisplayWindow;
3129

3230
import javax.swing.*;
@@ -39,7 +37,6 @@
3937
public class DeviceImpl extends AbstractDevice {
4038

4139
private final boolean guiSupported;
42-
private final Keyboard keyboard = new Keyboard();
4340
private boolean guiIOset = false;
4441

4542
private ULA ula;
@@ -58,7 +55,6 @@ public void initialize() throws PluginInitializationException {
5855
this.ula = new ULA(bus);
5956
this.passedCyclesMediator = new PassedCyclesMediator(ula);
6057
bus.addPassedCyclesListener(passedCyclesMediator);
61-
keyboard.addOnKeyListener(ula);
6258
bus.attachDevice(0xFE, ula);
6359
}
6460

@@ -69,7 +65,6 @@ public void reset() {
6965

7066
@Override
7167
public void destroy() {
72-
keyboard.close();
7368
if (guiIOset || gui != null) {
7469
gui.destroy();
7570
gui = null;
@@ -91,9 +86,8 @@ public boolean isShowSettingsSupported() {
9186
public void showGUI(JFrame parent) {
9287
if (guiSupported) {
9388
if (!guiIOset) {
94-
this.gui = new DisplayWindow(parent, ula, keyboard);
89+
this.gui = new DisplayWindow(parent, ula);
9590
passedCyclesMediator.setCanvas(gui.getCanvas());
96-
GuiUtils.addKeyListener(gui, keyboard);
9791
guiIOset = true;
9892
this.gui.setVisible(true);
9993
}

plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/ULA.java

+128-117
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,16 @@
2020

2121
import net.emustudio.plugins.cpu.intel8080.api.Context8080;
2222
import net.emustudio.plugins.device.zxspectrum.bus.api.ZxSpectrumBus;
23-
import net.emustudio.plugins.device.zxspectrum.ula.gui.Keyboard;
23+
import net.emustudio.plugins.device.zxspectrum.ula.gui.KeyboardDispatcher;
2424

2525
import java.awt.event.KeyEvent;
2626
import java.util.Arrays;
2727
import java.util.HashMap;
2828
import java.util.Map;
2929
import java.util.Objects;
30+
import java.util.function.BiConsumer;
3031

32+
import static java.awt.event.KeyEvent.*;
3133
import static net.emustudio.plugins.device.zxspectrum.ula.ZxParameters.*;
3234

3335
/**
@@ -74,7 +76,7 @@
7476
* - P2 to P0 is the PAPER colour
7577
* - I2 to I0 is the INK colour
7678
*/
77-
public class ULA implements Context8080.CpuPortDevice, Keyboard.OnKeyListener {
79+
public class ULA implements Context8080.CpuPortDevice, KeyboardDispatcher.OnKeyListener {
7880
private final static byte[] RST_7 = new byte[0x38]; // works for IM1 and IM2 modes
7981
private final static byte[] KEY_SHIFT = new byte[]{0, 1};
8082
private final static byte[] KEY_SYM_SHIFT = new byte[]{7, 2};
@@ -88,49 +90,72 @@ public class ULA implements Context8080.CpuPortDevice, Keyboard.OnKeyListener {
8890

8991
// maps host characters to ZX Spectrum key "commands"
9092
// Byte[] = {keymap index, "zero" value, shift, symshift}
91-
private final static Map<Character, Byte[]> CHAR_MAPPING = new HashMap<>();
93+
private final static Map<Integer, Byte[]> CHAR_MAPPING = new HashMap<>();
9294

9395
static {
94-
CHAR_MAPPING.put('Z', new Byte[]{0, 2, -1, -1}); // z, COPY, ":"
95-
CHAR_MAPPING.put('X', new Byte[]{0, 4, -1, -1}); // x, CLEAR, "£"
96-
CHAR_MAPPING.put('C', new Byte[]{0, 8, -1, -1}); // c, CONT, "?"
97-
CHAR_MAPPING.put('V', new Byte[]{0, 16, -1, -1}); // v, CLS, "/"
98-
CHAR_MAPPING.put('B', new Byte[]{7, 16, -1, -1}); // b, BORDER, "*"
99-
CHAR_MAPPING.put('N', new Byte[]{7, 8, -1, -1}); // n, NEXT, ","
100-
CHAR_MAPPING.put('M', new Byte[]{7, 4, -1, -1}); // m, PAUSE, "."
101-
CHAR_MAPPING.put(' ', new Byte[]{7, 1, -1, -1}); // " "
102-
CHAR_MAPPING.put('\n', new Byte[]{6, 1, -1, -1}); // ENTER
103-
CHAR_MAPPING.put('A', new Byte[]{1, 1, -1, -1}); // a, NEW, "STOP"
104-
CHAR_MAPPING.put('S', new Byte[]{1, 2, -1, -1}); // s, SAVE, "NOT"
105-
CHAR_MAPPING.put('D', new Byte[]{1, 4, -1, -1}); // d, DIM, "STEP"
106-
CHAR_MAPPING.put('F', new Byte[]{1, 8, -1, -1}); // f, FOR, "TO"
107-
CHAR_MAPPING.put('G', new Byte[]{1, 16, -1, -1}); // g, GOTO, "THEN"
108-
CHAR_MAPPING.put('H', new Byte[]{6, 16, -1, -1}); // h, GOSUB, "↑"
109-
CHAR_MAPPING.put('J', new Byte[]{6, 8, -1, -1}); // j, LOAD, "-"
110-
CHAR_MAPPING.put('K', new Byte[]{6, 4, -1, -1}); // k, LIST, "+"
111-
CHAR_MAPPING.put('L', new Byte[]{6, 2, -1, -1}); // l, LET, "="
112-
CHAR_MAPPING.put('Q', new Byte[]{2, 1, -1, -1}); // q, PLOT, "<="
113-
CHAR_MAPPING.put('W', new Byte[]{2, 2, -1, -1}); // w, DRAW, "<>"
114-
CHAR_MAPPING.put('E', new Byte[]{2, 4, -1, -1}); // e, REM, ">="
115-
CHAR_MAPPING.put('R', new Byte[]{2, 8, -1, -1}); // r, RUN, "<"
116-
CHAR_MAPPING.put('T', new Byte[]{2, 16, -1, -1}); // t, RAND, ">"
117-
CHAR_MAPPING.put('Y', new Byte[]{5, 16, -1, -1}); // y, RETURN, "AND"
118-
CHAR_MAPPING.put('U', new Byte[]{5, 8, -1, -1}); // u, IF, "OR"
119-
CHAR_MAPPING.put('I', new Byte[]{5, 4, -1, -1}); // i, INPUT, "AT"
120-
CHAR_MAPPING.put('O', new Byte[]{5, 2, -1, -1}); // o, POKE, ";"
121-
CHAR_MAPPING.put('P', new Byte[]{5, 1, -1, -1}); // p, PRINT, "
122-
CHAR_MAPPING.put('1', new Byte[]{3, 1, -1, -1}); // 1, "!"
123-
CHAR_MAPPING.put('2', new Byte[]{3, 2, -1, -1}); // 2, "@"
124-
CHAR_MAPPING.put('3', new Byte[]{3, 4, -1, -1}); // 3, "#"
125-
CHAR_MAPPING.put('4', new Byte[]{3, 8, -1, -1}); // 4, "$"
126-
CHAR_MAPPING.put('5', new Byte[]{3, 16, -1, -1}); // 5, "%"
127-
CHAR_MAPPING.put('6', new Byte[]{4, 16, -1, -1}); // 6, "&"
128-
CHAR_MAPPING.put('7', new Byte[]{4, 8, -1, -1}); // 7, "'"
129-
CHAR_MAPPING.put('8', new Byte[]{4, 4, -1, -1}); // 8, "("
130-
CHAR_MAPPING.put('9', new Byte[]{4, 2, -1, -1}); // 9, ")"
131-
CHAR_MAPPING.put('0', new Byte[]{4, 1, -1, -1}); // 0, "_"
132-
CHAR_MAPPING.put('\b', new Byte[]{4, 1, 1, -1}); // backspace
133-
CHAR_MAPPING.put((char) 127, new Byte[]{4, 1, 1, -1}); // delete
96+
CHAR_MAPPING.put(VK_Z, new Byte[]{0, 2, -1, -1}); // z, COPY, ":"
97+
CHAR_MAPPING.put(VK_COLON, new Byte[]{0, 2, 0, 1});
98+
CHAR_MAPPING.put(VK_X, new Byte[]{0, 4, -1, -1}); // x, CLEAR, "£"
99+
CHAR_MAPPING.put(VK_C, new Byte[]{0, 8, -1, -1}); // c, CONT, "?"
100+
CHAR_MAPPING.put(VK_V, new Byte[]{0, 16, -1, -1}); // v, CLS, "/"
101+
CHAR_MAPPING.put(VK_SLASH, new Byte[]{0, 16, 0, 1});
102+
CHAR_MAPPING.put(VK_B, new Byte[]{7, 16, -1, -1}); // b, BORDER, "*"
103+
CHAR_MAPPING.put(VK_ASTERISK, new Byte[]{7, 16, 0, 1});
104+
CHAR_MAPPING.put(VK_N, new Byte[]{7, 8, -1, -1}); // n, NEXT, ","
105+
CHAR_MAPPING.put(VK_COMMA, new Byte[]{7, 8, 0, 1});
106+
CHAR_MAPPING.put(VK_M, new Byte[]{7, 4, -1, -1}); // m, PAUSE, "."
107+
CHAR_MAPPING.put(VK_DECIMAL, new Byte[]{7, 4, 0, 1});
108+
CHAR_MAPPING.put(VK_PERIOD, new Byte[]{7, 4, 0, 1});
109+
CHAR_MAPPING.put(VK_SPACE, new Byte[]{7, 1, -1, -1}); // " "
110+
CHAR_MAPPING.put(VK_ENTER, new Byte[]{6, 1, -1, -1}); // ENTER
111+
CHAR_MAPPING.put(VK_A, new Byte[]{1, 1, -1, -1}); // a, NEW, "STOP"
112+
CHAR_MAPPING.put(VK_S, new Byte[]{1, 2, -1, -1}); // s, SAVE, "NOT"
113+
CHAR_MAPPING.put(VK_D, new Byte[]{1, 4, -1, -1}); // d, DIM, "STEP"
114+
CHAR_MAPPING.put(VK_F, new Byte[]{1, 8, -1, -1}); // f, FOR, "TO"
115+
CHAR_MAPPING.put(VK_G, new Byte[]{1, 16, -1, -1}); // g, GOTO, "THEN"
116+
CHAR_MAPPING.put(VK_H, new Byte[]{6, 16, -1, -1}); // h, GOSUB, "↑"
117+
CHAR_MAPPING.put(VK_UP, new Byte[]{6, 16, 0, 1});
118+
CHAR_MAPPING.put(VK_J, new Byte[]{6, 8, -1, -1}); // j, LOAD, "-"
119+
CHAR_MAPPING.put(VK_SUBTRACT, new Byte[]{6, 8, 0, 1});
120+
CHAR_MAPPING.put(VK_K, new Byte[]{6, 4, -1, -1}); // k, LIST, "+"
121+
CHAR_MAPPING.put(VK_ADD, new Byte[]{6, 4, 0, 1});
122+
CHAR_MAPPING.put(VK_L, new Byte[]{6, 2, -1, -1}); // l, LET, "="
123+
CHAR_MAPPING.put(VK_EQUALS, new Byte[]{6, 2, 0, 1});
124+
CHAR_MAPPING.put(VK_Q, new Byte[]{2, 1, -1, -1}); // q, PLOT, "<="
125+
CHAR_MAPPING.put(VK_W, new Byte[]{2, 2, -1, -1}); // w, DRAW, "<>"
126+
CHAR_MAPPING.put(VK_E, new Byte[]{2, 4, -1, -1}); // e, REM, ">="
127+
CHAR_MAPPING.put(VK_R, new Byte[]{2, 8, -1, -1}); // r, RUN, "<"
128+
CHAR_MAPPING.put(VK_LESS, new Byte[]{2, 8, 0, 1});
129+
CHAR_MAPPING.put(VK_T, new Byte[]{2, 16, -1, -1}); // t, RAND, ">"
130+
CHAR_MAPPING.put(VK_GREATER, new Byte[]{2, 16, 0, 1});
131+
CHAR_MAPPING.put(VK_Y, new Byte[]{5, 16, -1, -1}); // y, RETURN, "AND"
132+
CHAR_MAPPING.put(VK_U, new Byte[]{5, 8, -1, -1}); // u, IF, "OR"
133+
CHAR_MAPPING.put(VK_I, new Byte[]{5, 4, -1, -1}); // i, INPUT, "AT"
134+
CHAR_MAPPING.put(VK_O, new Byte[]{5, 2, -1, -1}); // o, POKE, ";"
135+
CHAR_MAPPING.put(VK_SEMICOLON, new Byte[]{5, 2, 0, 1});
136+
CHAR_MAPPING.put(VK_P, new Byte[]{5, 1, -1, -1}); // p, PRINT, "
137+
CHAR_MAPPING.put(VK_QUOTEDBL, new Byte[]{5, 1, 0, 1});
138+
CHAR_MAPPING.put(VK_1, new Byte[]{3, 1, -1, -1}); // 1, "!"
139+
CHAR_MAPPING.put(VK_EXCLAMATION_MARK, new Byte[]{3, 1, 0, 1});
140+
CHAR_MAPPING.put(VK_2, new Byte[]{3, 2, -1, -1}); // 2, "@"
141+
CHAR_MAPPING.put(VK_AT, new Byte[]{3, 2, 0, 1});
142+
CHAR_MAPPING.put(VK_3, new Byte[]{3, 4, -1, -1}); // 3, "#"
143+
CHAR_MAPPING.put(VK_NUMBER_SIGN, new Byte[]{3, 4, 0, 1});
144+
CHAR_MAPPING.put(VK_4, new Byte[]{3, 8, -1, -1}); // 4, "$"
145+
CHAR_MAPPING.put(VK_DOLLAR, new Byte[]{3, 8, 0, 1});
146+
CHAR_MAPPING.put(VK_5, new Byte[]{3, 16, -1, -1}); // 5, "%"
147+
CHAR_MAPPING.put(VK_6, new Byte[]{4, 16, -1, -1}); // 6, "&"
148+
CHAR_MAPPING.put(VK_AMPERSAND, new Byte[]{4, 16, 0, 1});
149+
CHAR_MAPPING.put(VK_7, new Byte[]{4, 8, -1, -1}); // 7, "'"
150+
CHAR_MAPPING.put(VK_QUOTE, new Byte[]{4, 8, 0, 1});
151+
CHAR_MAPPING.put(VK_8, new Byte[]{4, 4, -1, -1}); // 8, "("
152+
CHAR_MAPPING.put(VK_LEFT_PARENTHESIS, new Byte[]{4, 4, 0, 1});
153+
CHAR_MAPPING.put(VK_9, new Byte[]{4, 2, -1, -1}); // 9, ")"
154+
CHAR_MAPPING.put(VK_RIGHT_PARENTHESIS, new Byte[]{4, 2, 0, 1});
155+
CHAR_MAPPING.put(VK_0, new Byte[]{4, 1, -1, -1}); // 0, "_"
156+
CHAR_MAPPING.put(VK_UNDERSCORE, new Byte[]{4, 1, 0, 1});
157+
CHAR_MAPPING.put(VK_BACK_SPACE, new Byte[]{4, 1, 1, 0}); // backspace
158+
CHAR_MAPPING.put(VK_DELETE, new Byte[]{4, 1, 1, 0}); // delete
134159
}
135160

136161
public boolean videoFlash = false;
@@ -187,30 +212,23 @@ public byte read(int portAddress) {
187212
// If more than one address line is made low, the result is the logical AND of all single inputs
188213

189214
byte result = (byte) 0xBF; // 1011 1111 // no EAR input
190-
if ((portAddress & 0xFEFE) == 0xFEFE) {
191-
// SHIFT, Z, X, C, V
192-
result &= keymap[0];
193-
} else if ((portAddress & 0xFDFE) == 0xFDFE) {
194-
// A, S, D, F, G
195-
result &= keymap[1];
196-
} else if ((portAddress & 0xFBFE) == 0xFBFE) {
197-
// Q, W, E, R, T
198-
result &= keymap[2];
199-
} else if ((portAddress & 0xF7FE) == 0xF7FE) {
200-
// 1, 2, 3, 4, 5
201-
result &= keymap[3];
202-
} else if ((portAddress & 0xEFFE) == 0xEFFE) {
203-
// 0, 9, 8, 7, 6
204-
result &= keymap[4];
205-
} else if ((portAddress & 0xDFFE) == 0xDFFE) {
206-
// P, O, I, U, Y
207-
result &= keymap[5];
208-
} else if ((portAddress & 0xBFFE) == 0xBFFE) {
209-
// ENTER, L, K, J, H
210-
result &= keymap[6];
211-
} else if ((portAddress & 0x7FFE) == 0x7FFE) {
212-
// SPACE, SYM SHIFT, M, N, B
213-
result &= keymap[7];
215+
if ((portAddress & 0xFE) == 0xFE) {
216+
int keyLine = 0;
217+
portAddress >>>= 8;
218+
while ((portAddress & 1) != 0) {
219+
portAddress >>>= 1;
220+
keyLine++;
221+
}
222+
223+
// FE = 0 1111 1110
224+
// FD = 1 1111 1101
225+
// FB = 2 1111 1011
226+
// F7 = 3 1111 0111
227+
// EF = 4 1110 1111
228+
// DF = 5 1101 1111
229+
// BF = 6 1011 1111
230+
// 7F = 7 0111 1111
231+
result &= keymap[keyLine];
214232
}
215233

216234
// LINE IN?
@@ -235,61 +253,54 @@ public String toString() {
235253
}
236254

237255
@Override
238-
public void onKeyUp(KeyEvent evt) {
239-
int keyCode = evt.getExtendedKeyCode();
240-
switch (keyCode) {
241-
case KeyEvent.VK_CONTROL:
242-
keymap[KEY_SYM_SHIFT[0]] |= KEY_SYM_SHIFT[1];
243-
break;
244-
case KeyEvent.VK_SHIFT:
245-
keymap[KEY_SHIFT[0]] |= KEY_SHIFT[1];
246-
break;
247-
default:
248-
Byte[] command = CHAR_MAPPING.get((char) keyCode);
249-
if (command != null) {
250-
if (command[2] == 1) {
251-
keymap[KEY_SHIFT[0]] |= KEY_SHIFT[1];
252-
} else if (command[2] == 0) {
253-
keymap[KEY_SHIFT[0]] &= (byte) ((~KEY_SHIFT[1]) & 0xFF);
254-
}
255-
if (command[3] == 1) {
256-
keymap[KEY_SYM_SHIFT[0]] |= KEY_SYM_SHIFT[1];
257-
} else if (command[3] == 0) {
258-
keymap[KEY_SYM_SHIFT[0]] &= (byte) ((~KEY_SYM_SHIFT[1]) & 0xFF);
259-
}
260-
keymap[command[0]] |= command[1];
261-
}
256+
public void onKeyEvent(KeyEvent e) {
257+
boolean pressed = e.getID() == KEY_PRESSED;
258+
if (!pressed && e.getID() != KEY_RELEASED) {
259+
return;
262260
}
263-
}
261+
BiConsumer<Byte, Byte> keySet = pressed ? this::andKeyMap : this::orKeyMap;
262+
BiConsumer<Byte, Byte> keyUnset = pressed ? this::orKeyMap : this::andKeyMap;
264263

265-
@Override
266-
public void onKeyDown(KeyEvent evt) {
267-
int keyCode = evt.getExtendedKeyCode();
268-
switch (keyCode) {
269-
case KeyEvent.VK_CONTROL:
270-
keymap[KEY_SYM_SHIFT[0]] &= (byte) ((~KEY_SYM_SHIFT[1]) & 0xFF);
271-
break;
272-
case KeyEvent.VK_SHIFT:
273-
keymap[KEY_SHIFT[0]] &= (byte) ((~KEY_SHIFT[1]) & 0xFF);
274-
break;
275-
default:
276-
Byte[] command = CHAR_MAPPING.get((char) keyCode);
277-
if (command != null) {
278-
if (command[2] == 1) {
279-
keymap[KEY_SHIFT[0]] &= (byte) ((~KEY_SHIFT[1]) & 0xFF);
280-
} else if (command[2] == 0) {
281-
keymap[KEY_SHIFT[0]] |= KEY_SHIFT[1];
282-
}
283-
if (command[3] == 1) {
284-
keymap[KEY_SYM_SHIFT[0]] &= (byte) ((~KEY_SYM_SHIFT[1]) & 0xFF);
285-
} else if (command[3] == 0) {
286-
keymap[KEY_SYM_SHIFT[0]] |= KEY_SYM_SHIFT[1];
287-
}
288-
keymap[command[0]] &= (byte) ((~command[1]) & 0xFF);
289-
}
264+
// shift / alt / ctrl are visible in modifiersEx only if pressed = true
265+
boolean symShift = (e.getModifiersEx() & (KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)) != 0;
266+
boolean shift = (e.getModifiersEx() & (KeyEvent.SHIFT_DOWN_MASK)) != 0;
267+
268+
Byte[] command = CHAR_MAPPING.get(e.getKeyCode());
269+
if (command != null) {
270+
if (command[2] == 1 || (command[2] == -1 && shift)) {
271+
keySet.accept(KEY_SHIFT[0], KEY_SHIFT[1]);
272+
} else if (command[2] == 0 || !shift) {
273+
keyUnset.accept(KEY_SHIFT[0], KEY_SHIFT[1]);
274+
}
275+
if (command[3] == 1 || (command[3] == -1 && symShift)) {
276+
keySet.accept(KEY_SYM_SHIFT[0], KEY_SYM_SHIFT[1]);
277+
} else if (command[3] == 0 || !symShift) {
278+
keyUnset.accept(KEY_SYM_SHIFT[0], KEY_SYM_SHIFT[1]);
279+
}
280+
// TODO: shift/symshift are toggling for some reason
281+
keySet.accept(command[0], command[1]);
282+
} else {
283+
if (shift) {
284+
keySet.accept(KEY_SHIFT[0], KEY_SHIFT[1]);
285+
} else {
286+
keyUnset.accept(KEY_SHIFT[0], KEY_SHIFT[1]);
287+
}
288+
if (symShift) {
289+
keySet.accept(KEY_SYM_SHIFT[0], KEY_SYM_SHIFT[1]);
290+
} else {
291+
keyUnset.accept(KEY_SYM_SHIFT[0], KEY_SYM_SHIFT[1]);
292+
}
290293
}
291294
}
292295

296+
private void andKeyMap(byte key, byte value) {
297+
keymap[key] &= (byte) ((~value) & 0xFF);
298+
}
299+
300+
private void orKeyMap(byte key, byte value) {
301+
keymap[key] |= value;
302+
}
303+
293304
/**
294305
* Computes address offsets for each line in the screen.
295306
* <p>

plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/gui/DisplayWindow.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import net.emustudio.plugins.device.zxspectrum.ula.ULA;
2222

2323
import javax.swing.*;
24+
import java.awt.*;
2425
import java.awt.event.WindowEvent;
2526

2627
import static net.emustudio.plugins.device.zxspectrum.ula.ZxParameters.SCREEN_IMAGE_HEIGHT;
@@ -32,10 +33,10 @@ public class DisplayWindow extends JDialog {
3233

3334
public final static int MARGIN = 30;
3435

35-
public DisplayWindow(JFrame parent, ULA ula, Keyboard keyboard) {
36+
public DisplayWindow(JFrame parent, ULA ula) {
3637
super(parent);
3738
this.canvas = new DisplayCanvas(ula);
38-
this.keyboardCanvas = new KeyboardCanvas(keyboard);
39+
this.keyboardCanvas = new KeyboardCanvas();
3940

4041
initComponents();
4142
setLocationRelativeTo(parent);
@@ -49,6 +50,12 @@ public void windowActivated(WindowEvent winEvt) {
4950
canvas.redrawNow();
5051
}
5152
});
53+
KeyboardDispatcher keyboardDispatcher = new KeyboardDispatcher();
54+
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
55+
manager.addKeyEventDispatcher(keyboardDispatcher);
56+
57+
keyboardDispatcher.addOnKeyListener(keyboardCanvas);
58+
keyboardDispatcher.addOnKeyListener(ula);
5259
}
5360

5461
public void destroy() {

0 commit comments

Comments
 (0)