From dd508b4abac95e7c40611b6831dbb2f413321756 Mon Sep 17 00:00:00 2001 From: hneemann Date: Sun, 10 Jul 2016 12:25:17 +0200 Subject: [PATCH] added a simple keyboard --- .../digital/draw/library/ElementLibrary.java | 2 + .../gui/components/terminal/Keyboard.java | 104 ++++++++++++++++++ .../components/terminal/KeyboardDialog.java | 67 +++++++++++ .../gui/components/terminal/Terminal.java | 11 +- src/main/resources/lang/lang_de.xml | 3 + src/main/resources/lang/lang_en.xml | 3 + 6 files changed, 185 insertions(+), 5 deletions(-) create mode 100644 src/main/java/de/neemann/digital/gui/components/terminal/Keyboard.java create mode 100644 src/main/java/de/neemann/digital/gui/components/terminal/KeyboardDialog.java diff --git a/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java b/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java index 59897aa72..981ca75bb 100644 --- a/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java +++ b/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java @@ -13,6 +13,7 @@ import de.neemann.digital.core.wiring.*; import de.neemann.digital.draw.elements.Tunnel; import de.neemann.digital.gui.components.data.DummyElement; import de.neemann.digital.gui.components.graphics.GraphicCard; +import de.neemann.digital.gui.components.terminal.Keyboard; import de.neemann.digital.gui.components.terminal.Terminal; import de.neemann.digital.gui.components.test.TestCaseElement; import de.neemann.digital.lang.Lang; @@ -56,6 +57,7 @@ public class ElementLibrary implements Iterable add(Terminal.DESCRIPTION, menu); add(DummyElement.DATADESCRIPTION, menu); add(DummyElement.TEXTDESCRIPTION, menu); + add(Keyboard.DESCRIPTION, menu); menu = Lang.get("lib_mux"); add(Multiplexer.DESCRIPTION, menu); diff --git a/src/main/java/de/neemann/digital/gui/components/terminal/Keyboard.java b/src/main/java/de/neemann/digital/gui/components/terminal/Keyboard.java new file mode 100644 index 000000000..f40d25179 --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/components/terminal/Keyboard.java @@ -0,0 +1,104 @@ +package de.neemann.digital.gui.components.terminal; + +import de.neemann.digital.core.*; +import de.neemann.digital.core.element.Element; +import de.neemann.digital.core.element.ElementAttributes; +import de.neemann.digital.core.element.ElementTypeDescription; +import de.neemann.digital.core.element.Keys; +import de.neemann.digital.lang.Lang; + +import javax.swing.*; + +import static de.neemann.digital.core.element.PinInfo.input; + +/** + * @author hneemann + */ +public class Keyboard extends Node implements Element { + + /** + * The keyboard description + */ + public static final ElementTypeDescription DESCRIPTION + = new ElementTypeDescription(Keyboard.class, + input("C"), + input("sel", Lang.get("elem_Keyboard_pin_sel"))) + .addAttribute(Keys.ROTATE) + .addAttribute(Keys.LABEL) + .setShortName(Lang.get("elem_Keyboard")); + + private static final Object KEYBOARD_LOCK = new Object(); + private static KeyboardDialog keyboardDialog; + + private ObservableValue data; + private ObservableValue clock; + private ObservableValue select; + private boolean lastClock; + private int keyData; + private boolean sel; + + /** + * Creates a new terminal instance + * + * @param attributes the attributes + */ + public Keyboard(ElementAttributes attributes) { + data = new ObservableValue("D", 16).setDescription(Lang.get("elem_Keyboard_pin_D")); + } + + @Override + public void setInputs(ObservableValues inputs) throws NodeException { + clock = inputs.get(0).addObserverToValue(this).checkBits(1, this); + select = inputs.get(1).addObserverToValue(this).checkBits(1, this); + } + + @Override + public ObservableValues getOutputs() { + return data.asList(); + } + + @Override + public void readInputs() throws NodeException { + boolean clockVal = clock.getBool(); + sel = select.getBool(); + if (!lastClock && clockVal) { + KeyboardDialog kbd; + synchronized (KEYBOARD_LOCK) { + kbd = keyboardDialog; + } + if (kbd==null) + keyData=0; + else + keyData = keyboardDialog.getChar(); + } + lastClock = clockVal; + } + + @Override + public void writeOutputs() throws NodeException { + data.set(keyData, !sel); + } + + @Override + public void init(Model model) throws NodeException { + SwingUtilities.invokeLater(() -> { + if (keyboardDialog == null || !keyboardDialog.isVisible()) { + synchronized (KEYBOARD_LOCK) { + keyboardDialog = new KeyboardDialog(null); + } + keyboardDialog.setVisible(true); + } + }); + model.addObserver(event -> { + if (event.equals(ModelEvent.STOPPED)) { + if (keyboardDialog != null) { + KeyboardDialog kd = keyboardDialog; + SwingUtilities.invokeLater(kd::dispose); + synchronized (KEYBOARD_LOCK) { + keyboardDialog = null; + } + } + } + }); + } +} diff --git a/src/main/java/de/neemann/digital/gui/components/terminal/KeyboardDialog.java b/src/main/java/de/neemann/digital/gui/components/terminal/KeyboardDialog.java new file mode 100644 index 000000000..bb627ea3f --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/components/terminal/KeyboardDialog.java @@ -0,0 +1,67 @@ +package de.neemann.digital.gui.components.terminal; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; + +/** + * A simple keyboard implementation + * + * @author hneemann + */ +public class KeyboardDialog extends JDialog { + private final JLabel textLabel; + private final Object textLock = new Object(); + private String text; + + /** + * Create a new Instance + * + * @param owner the owner frame + */ + public KeyboardDialog(Frame owner) { + super(owner); + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + + textLabel = new JLabel("Enter Text "); + textLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + getContentPane().add(textLabel); + text = ""; + + textLabel.setFocusable(true); + textLabel.addKeyListener(new KeyAdapter() { + @Override + public void keyTyped(KeyEvent e) { + String t; + synchronized (textLock) { + text += e.getKeyChar(); + t = text; + } + textLabel.setText(t); + } + }); + + pack(); + setLocationRelativeTo(owner); + } + + /** + * @return the oldest char + */ + public int getChar() { + if (text.length() == 0) + return 0; + else { + int c; + String t; + synchronized (textLock) { + c = text.charAt(0); + text = text.substring(1); + t = text; + } + SwingUtilities.invokeLater(() -> textLabel.setText(t)); + return c; + } + } +} diff --git a/src/main/java/de/neemann/digital/gui/components/terminal/Terminal.java b/src/main/java/de/neemann/digital/gui/components/terminal/Terminal.java index e70db0dcb..7768bc087 100644 --- a/src/main/java/de/neemann/digital/gui/components/terminal/Terminal.java +++ b/src/main/java/de/neemann/digital/gui/components/terminal/Terminal.java @@ -63,11 +63,12 @@ public class Terminal extends Node implements Element { boolean clockVal = clock.getBool(); if (!lastClock && clockVal) { long value = data.getValue(); - SwingUtilities.invokeLater(() -> { - if (terminalDialog == null || !terminalDialog.isVisible()) - terminalDialog = new TerminalDialog(attr); - terminalDialog.addChar((char) value); - }); + if (value != 0) + SwingUtilities.invokeLater(() -> { + if (terminalDialog == null || !terminalDialog.isVisible()) + terminalDialog = new TerminalDialog(attr); + terminalDialog.addChar((char) value); + }); } lastClock = clockVal; } diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml index e807c4015..504646970 100644 --- a/src/main/resources/lang/lang_de.xml +++ b/src/main/resources/lang/lang_de.xml @@ -112,6 +112,9 @@ in der Stabilisierungsphase befindet. Hat sich die Schaltung stabilisiert wird d Exclusiv Oder Testfall Beschreibt einen Testfall + Tastatur + Wenn gesetzt is der Ausgang D aktiv. + Die letzte Taste oder 0, wenn keine Taste gedrückt. Fehler Flipflop hat keine Bezeichnung! Pin {0} in Element {1} ist werder Eingang noch Ausgang diff --git a/src/main/resources/lang/lang_en.xml b/src/main/resources/lang/lang_en.xml index 91c114f1b..1255a3d01 100644 --- a/src/main/resources/lang/lang_en.xml +++ b/src/main/resources/lang/lang_en.xml @@ -112,6 +112,9 @@ The terminal opens its own window. XOr Test case Describes a single test case. + Keyboard + If high the output D is active + The last pressed key, or null if no key is typed. Error D-Flipflop has no label set Pin {0} in element {1} is not a input or output