added a simple keyboard

This commit is contained in:
hneemann 2016-07-10 12:25:17 +02:00
parent 07b730a87b
commit dd508b4aba
6 changed files with 185 additions and 5 deletions

View File

@ -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<ElementLibrary.ElementContainer>
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);

View File

@ -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;
}
}
}
});
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}

View File

@ -112,6 +112,9 @@ in der Stabilisierungsphase befindet. Hat sich die Schaltung stabilisiert wird d
<string name="elem_XOr">Exclusiv Oder</string>
<string name="elem_Testcase">Testfall</string>
<string name="elem_Testcase_tt">Beschreibt einen Testfall</string>
<string name="elem_Keyboard">Tastatur</string>
<string name="elem_Keyboard_pin_sel">Wenn gesetzt is der Ausgang D aktiv.</string>
<string name="elem_Keyboard_pin_D">Die letzte Taste oder 0, wenn keine Taste gedrückt.</string>
<string name="error">Fehler</string>
<string name="err_DFlipflopWithoutALabel">Flipflop hat keine Bezeichnung!</string>
<string name="err_N_isNotInputOrOutput">Pin {0} in Element {1} ist werder Eingang noch Ausgang</string>

View File

@ -112,6 +112,9 @@ The terminal opens its own window.</string>
<string name="elem_XOr">XOr</string>
<string name="elem_Testcase">Test case</string>
<string name="elem_Testcase_tt">Describes a single test case.</string>
<string name="elem_Keyboard">Keyboard</string>
<string name="elem_Keyboard_pin_sel">If high the output D is active</string>
<string name="elem_Keyboard_pin_D">The last pressed key, or null if no key is typed.</string>
<string name="error">Error</string>
<string name="err_DFlipflopWithoutALabel">D-Flipflop has no label set</string>
<string name="err_N_isNotInputOrOutput">Pin {0} in element {1} is not a input or output</string>