started internationalization

This commit is contained in:
hneemann 2016-03-25 21:19:50 +01:00
parent bf464d9cff
commit d74d7b9ea8
23 changed files with 237 additions and 68 deletions

View File

@ -1,10 +1,12 @@
package de.neemann.digital.core;
import de.neemann.digital.lang.Lang;
/**
* @author hneemann
*/
public class BurnException extends NodeException {
public BurnException(Node node, ObservableValue... values) {
super("burnException", node, values);
super(Lang.get("err_burnError"), node, values);
}
}

View File

@ -1,6 +1,7 @@
package de.neemann.digital.core;
import de.neemann.digital.core.wiring.Clock;
import de.neemann.digital.lang.Lang;
import java.util.ArrayList;
import java.util.Collection;
@ -34,7 +35,7 @@ public class Model {
public <T extends Node> T add(T node) {
if (isInitialized)
throw new RuntimeException("is already initialized!");
throw new RuntimeException(Lang.get("err_isAlreadyInitialized"));
nodes.add(node);
node.setModel(this);
@ -82,7 +83,7 @@ public class Model {
int counter = 0;
while (needsUpdate()) {
if (counter++ > maxCounter) {
throw new NodeException("seemsToOscillate", nodesToUpdateNext.get(0));
throw new NodeException(Lang.get("err_seemsToOscillate"), nodesToUpdateNext.get(0));
}
doMicroStep(noise);
}
@ -102,7 +103,7 @@ public class Model {
*/
public void doMicroStep(boolean noise) throws NodeException {
if (!isInitialized)
throw new RuntimeException("notInitialized!");
throw new RuntimeException(Lang.get("err_notInitialized"));
fireEvent(ModelEvent.STEP);

View File

@ -1,5 +1,7 @@
package de.neemann.digital.core;
import de.neemann.digital.lang.Lang;
import java.util.ArrayList;
/**
@ -97,7 +99,7 @@ public class ObservableValue extends Value {
public ObservableValue checkBits(int bits, Node node) throws BitsException {
if (this.bits != bits) {
throw new BitsException("needs " + bits + " bits, found " + this.bits, node, this);
throw new BitsException(Lang.get("err_needs_N0_bits_found_N2_bits", bits, this.bits), node, this);
}
return this;
}

View File

@ -1,6 +1,7 @@
package de.neemann.digital.core;
import de.neemann.digital.core.wiring.Clock;
import de.neemann.digital.lang.Lang;
import java.util.ArrayList;
@ -18,9 +19,9 @@ public class SpeedTest {
public double calculate() throws NodeException {
ArrayList<Clock> clocks = model.getClocks();
if (clocks.isEmpty())
throw new NodeException("NoClockFound", null);
throw new NodeException(Lang.get("err_noClockFound"), null);
else if (clocks.size() > 1)
throw new NodeException("MoreThenOneClocksFound", null);
throw new NodeException(Lang.get("err_moreThenOneClocksFound"), null);
Clock clock = clocks.get(0);

View File

@ -1,26 +1,30 @@
package de.neemann.digital.core.element;
import de.neemann.digital.core.memory.DataField;
import de.neemann.digital.lang.Lang;
/**
* @author hneemann
*/
public class AttributeKey<VALUE> {
public static final AttributeKey<Integer> Bits = new AttributeKey<>("Data Bits", 1);
public static final AttributeKey<Integer> InputCount = new AttributeKey<>("Number of Inputs", 2);
public static final AttributeKey<String> Label = new AttributeKey<>("Label", "");
public static final AttributeKey<Integer> Value = new AttributeKey<>("Value", 1);
public static final AttributeKey<Integer> Default = new AttributeKey<>("Default", 0);
public static final AttributeKey<java.awt.Color> Color = new AttributeKey<>("Color", java.awt.Color.RED);
public static final AttributeKey<String> InputSplit = new AttributeKey<>("Input Splitting", "");
public static final AttributeKey<String> OutputSplit = new AttributeKey<>("Output Splitting", "");
public static final AttributeKey<Integer> Frequency = new AttributeKey<>("Frequency", 1);
public static final AttributeKey<Integer> SelectorBits = new AttributeKey<>("Selector Bits", 1);
public static final AttributeKey<Boolean> Signed = new AttributeKey<>("Signed", false);
public static final AttributeKey<Integer> Bits = new AttributeKey<>(Lang.get("key_dataBits"), 1);
public static final AttributeKey<Integer> InputCount = new AttributeKey<>(Lang.get("key_numberInputs"), 2);
public static final AttributeKey<String> Label = new AttributeKey<>(Lang.get("key_label"), "");
public static final AttributeKey<Integer> Value = new AttributeKey<>(Lang.get("key_value"), 1);
public static final AttributeKey<Integer> Default = new AttributeKey<>(Lang.get("key_default"), 0);
public static final AttributeKey<java.awt.Color> Color = new AttributeKey<>(Lang.get("key_color"), java.awt.Color.RED);
public static final AttributeKey<String> InputSplit = new AttributeKey<>(Lang.get("key_inputSplitting"), "");
public static final AttributeKey<String> OutputSplit = new AttributeKey<>(Lang.get("key_outputSplitting"), "");
public static final AttributeKey<Integer> Frequency = new AttributeKey<>(Lang.get("key_frequency"), 1);
public static final AttributeKey<Integer> SelectorBits = new AttributeKey<>(Lang.get("key_selectorBits"), 1);
public static final AttributeKey<Boolean> Signed = new AttributeKey<>(Lang.get("key_signed"), false);
public static final AttributeKey<DataField> Data = new AttributeKey<>(Lang.get("key_data"), DataField.DEFAULT);
private final String name;
private final VALUE def;
public AttributeKey(String name, VALUE def) {
private AttributeKey(String name, VALUE def) {
this.name = name;
if (def == null)
throw new NullPointerException();

View File

@ -54,18 +54,9 @@ public class JK_FF extends Node implements Element {
@Override
public void setInputs(ObservableValue... inputs) throws BitsException {
jVal = inputs[0].addObserver(this);
clockVal = inputs[1].addObserver(this);
kVal = inputs[2].addObserver(this);
if (jVal.getBits() != 1)
throw new BitsException("wrongBitCount", this, jVal);
if (kVal.getBits() != 1)
throw new BitsException("wrongBitCount", this, kVal);
if (clockVal.getBits() != 1)
throw new BitsException("carryIsABit", this, clockVal);
jVal = inputs[0].addObserver(this).checkBits(1, this);
clockVal = inputs[1].addObserver(this).checkBits(1, this);
kVal = inputs[2].addObserver(this).checkBits(1, this);
}
@Override

View File

@ -53,18 +53,9 @@ public class RS_FF extends Node implements Element {
@Override
public void setInputs(ObservableValue... inputs) throws BitsException {
jVal = inputs[0].addObserver(this);
clockVal = inputs[1].addObserver(this);
kVal = inputs[2].addObserver(this);
if (jVal.getBits() != 1)
throw new BitsException("wrongBitCount", this, jVal);
if (kVal.getBits() != 1)
throw new BitsException("wrongBitCount", this, kVal);
if (clockVal.getBits() != 1)
throw new BitsException("carryIsABit", this, clockVal);
jVal = inputs[0].addObserver(this).checkBits(1, this);
clockVal = inputs[1].addObserver(this).checkBits(1, this);
kVal = inputs[2].addObserver(this).checkBits(1, this);
}
@Override

View File

@ -47,10 +47,7 @@ public class T_FF extends Node implements Element {
@Override
public void setInputs(ObservableValue... inputs) throws BitsException {
clockVal = inputs[0].addObserver(this);
if (clockVal.getBits() != 1)
throw new BitsException("carryIsABit", this, clockVal);
clockVal = inputs[0].addObserver(this).checkBits(1, this);
}
@Override

View File

@ -7,6 +7,7 @@ import de.neemann.digital.core.element.AttributeKey;
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.lang.Lang;
/**
* @author hneemann
@ -26,7 +27,7 @@ public class Const implements Element {
@Override
public void setInputs(ObservableValue... inputs) throws NodeException {
throw new NodeException("no inputs available!", null);
throw new NodeException(Lang.get("err_noInputsAvailable"), null);
}
@Override

View File

@ -7,6 +7,7 @@ import de.neemann.digital.core.element.AttributeKey;
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.lang.Lang;
/**
* @author hneemann
@ -27,7 +28,7 @@ public class In implements Element {
@Override
public void setInputs(ObservableValue... inputs) throws NodeException {
throw new NodeException("no inputs available!", null);
throw new NodeException(Lang.get("err_noInputsAvailable"), null);
}
@Override

View File

@ -25,14 +25,16 @@ public class Out implements Element {
.addAttribute(AttributeKey.Label)
.addAttribute(AttributeKey.Color);
private final int bits;
private ObservableValue value;
public Out(ElementAttributes attributes) {
bits = attributes.getBits();
}
@Override
public void setInputs(ObservableValue... inputs) throws NodeException {
value = inputs[0];
value = inputs[0].checkBits(bits, null);
}
@Override

View File

@ -0,0 +1,24 @@
package de.neemann.digital.core.memory;
/**
* @author hneemann
*/
public class DataField {
public static final DataField DEFAULT = new DataField();
private long[] data;
public void setData(int addr, long value) {
if (addr < data.length)
data[addr] = value;
}
public long getData(int addr) {
if (addr >= data.length)
return 0;
else
return data[addr];
}
}

View File

@ -0,0 +1,72 @@
package de.neemann.digital.core.memory;
import de.neemann.digital.core.Node;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.core.ObservableValue;
import de.neemann.digital.core.element.AttributeKey;
import de.neemann.digital.core.element.Element;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.ElementTypeDescription;
/**
* @author hneemann
*/
public class LookUpTable extends Node implements Element {
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(LookUpTable.class) {
@Override
public String[] getInputNames(ElementAttributes elementAttributes) {
int size = elementAttributes.get(AttributeKey.InputCount);
String[] names = new String[size];
for (int i = 0; i < size; i++)
names[i] = "in_" + i;
return names;
}
}
.addAttribute(AttributeKey.Bits)
.addAttribute(AttributeKey.InputCount)
.addAttribute(AttributeKey.Data)
.setShortName("LUT");
private final DataField data;
private final int bits;
private final ObservableValue output;
private ObservableValue[] inputs;
private int addr;
public LookUpTable(ElementAttributes attr) {
bits = attr.get(AttributeKey.Bits);
output = new ObservableValue("out", bits);
data = attr.get(AttributeKey.Data);
}
@Override
public void setInputs(ObservableValue... inputs) throws NodeException {
this.inputs = inputs;
for (int i = 0; i < inputs.length; i++)
inputs[i].checkBits(1, this).addObserver(this);
}
@Override
public ObservableValue[] getOutputs() {
return new ObservableValue[]{output};
}
@Override
public void readInputs() throws NodeException {
addr = 0;
int mask = 1;
for (int i = 0; i < inputs.length; i++) {
if (inputs[i].getValue() > 0)
addr = addr | mask;
mask = mask * 2;
}
}
@Override
public void writeOutputs() throws NodeException {
output.setValue(data.getData(addr));
}
}

View File

@ -5,6 +5,7 @@ import de.neemann.digital.core.element.AttributeKey;
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.lang.Lang;
import de.process.utils.gui.ErrorMessage;
import javax.swing.*;
@ -29,7 +30,7 @@ public class Clock implements Element {
@Override
public void setInputs(ObservableValue... inputs) throws NodeException {
throw new NodeException("no inputs available!", null);
throw new NodeException(Lang.get("err_noInputsAvailable"), null);
}
@Override

View File

@ -7,6 +7,7 @@ import de.neemann.digital.core.basic.FanIn;
import de.neemann.digital.core.element.AttributeKey;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.lang.Lang;
import java.util.Arrays;
@ -56,6 +57,6 @@ public class Multiplexer extends FanIn {
super.setInputs(in);
if (in.length != (1 << selectorBits))
throw new BitsException("selectorInputCountMismatch", this, selector);
throw new BitsException(Lang.get("err_selectorInputCountMismatch"), this, selector);
}
}

View File

@ -5,6 +5,7 @@ import de.neemann.digital.core.element.AttributeKey;
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.lang.Lang;
import java.util.ArrayList;
import java.util.Arrays;
@ -50,13 +51,13 @@ public class Splitter implements Element {
@Override
public void setInputs(ObservableValue... inputs) throws NodeException {
if (inPorts.getBits() != outPorts.getBits())
throw new BitsException("splitterBitsMismatch", null, combine(inputs, outputs));
throw new BitsException(Lang.get("err_splitterBitsMismatch"), null, combine(inputs, outputs));
this.inputs = inputs;
for (int i = 0; i < inputs.length; i++) {
Port inPort = inPorts.getPort(i);
if (inPort.getBits() != inputs[i].getBits())
throw new BitsException("splitterBitsMismatch", null, inputs[i]);
throw new BitsException(Lang.get("err_splitterBitsMismatch"), null, inputs[i]);
}
for (Port out : outPorts)

View File

@ -2,6 +2,7 @@ package de.neemann.digital.gui.components;
import de.neemann.digital.core.element.AttributeKey;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.lang.Lang;
import de.process.utils.gui.ErrorMessage;
import javax.swing.*;
@ -17,7 +18,7 @@ public class AttributeDialog extends JDialog {
private final ArrayList<EditorHolder> editors;
public AttributeDialog(Point pos, ArrayList<AttributeKey> list, ElementAttributes elementAttributes) {
super((Frame) null, "Attributes", true);
super((Frame) null, Lang.get("attr_dialogTitle"), true);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
JPanel panel = new JPanel(new GridLayout(0, 2));
@ -30,17 +31,17 @@ public class AttributeDialog extends JDialog {
panel.add(new JLabel(key.getName() + ": "));
Editor e = EditorFactory.INSTANCE.create(key.getValueClass(), elementAttributes.get(key));
editors.add(new EditorHolder(e, key));
panel.add(e.getComponent());
panel.add(e.getComponent(elementAttributes));
}
JButton okButton = new JButton(new AbstractAction("ok") {
JButton okButton = new JButton(new AbstractAction(Lang.get("ok")) {
@Override
public void actionPerformed(ActionEvent e) {
try {
setEditedValues(elementAttributes);
dispose();
} catch (RuntimeException err) {
new ErrorMessage("Error editing a value").addCause(err).setComponent(AttributeDialog.this).show();
new ErrorMessage(Lang.get("msg_errorEditingValue")).addCause(err).setComponent(AttributeDialog.this).show();
}
}
});

View File

@ -1,5 +1,7 @@
package de.neemann.digital.gui.components;
import de.neemann.digital.core.element.ElementAttributes;
import java.awt.*;
/**
@ -7,7 +9,7 @@ import java.awt.*;
*/
public interface Editor<T> {
Component getComponent();
Component getComponent(ElementAttributes elementAttributes);
T getValue();
}

View File

@ -1,5 +1,9 @@
package de.neemann.digital.gui.components;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.memory.DataField;
import de.neemann.digital.lang.Lang;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
@ -19,6 +23,7 @@ public final class EditorFactory {
add(Integer.class, IntegerEditor.class);
add(Color.class, ColorEditor.class);
add(Boolean.class, BooleanEditor.class);
add(DataField.class, DataFieldEditor.class);
}
public <T> void add(Class<T> clazz, Class<? extends Editor<T>> editor) {
@ -47,7 +52,7 @@ public final class EditorFactory {
}
@Override
public Component getComponent() {
public Component getComponent(ElementAttributes attr) {
return text;
}
@ -67,7 +72,7 @@ public final class EditorFactory {
}
@Override
public Component getComponent() {
public Component getComponent(ElementAttributes attr) {
return comboBox;
}
@ -91,7 +96,7 @@ public final class EditorFactory {
}
@Override
public Component getComponent() {
public Component getComponent(ElementAttributes attr) {
return bool;
}
@ -112,7 +117,7 @@ public final class EditorFactory {
button = new JButton(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
Color col = JColorChooser.showDialog(button, "Color", color);
Color col = JColorChooser.showDialog(button, Lang.get("msg_color"), color);
if (col != null) {
color = col;
button.setBackground(color);
@ -123,7 +128,7 @@ public final class EditorFactory {
}
@Override
public Component getComponent() {
public Component getComponent(ElementAttributes attr) {
return button;
}
@ -133,4 +138,25 @@ public final class EditorFactory {
}
}
private static class DataFieldEditor implements Editor<DataField> {
private final DataField data;
public DataFieldEditor(DataField data) {
this.data = data;
}
@Override
public Component getComponent(ElementAttributes attr) {
JPanel panel = new JPanel(new FlowLayout());
panel.add(new JButton(Lang.get("btn_edit")));
panel.add(new JButton(Lang.get("btn_load")));
return panel;
}
@Override
public DataField getValue() {
return data;
}
}
}

View File

@ -1,5 +1,6 @@
package de.neemann.digital.gui.components;
import de.neemann.digital.lang.Lang;
import de.process.utils.gui.ToolTipAction;
import javax.swing.*;
@ -33,7 +34,7 @@ public class ElementOrderer<T> extends JDialog {
list.setSelectedIndex(i - 1);
}
}
}.setToolTip("move item up").createJButton());
}.setToolTip(Lang.get("tt_moveItemUp")).createJButton());
buttons.add(new ToolTipAction("\u2193") {
@Override
public void actionPerformed(ActionEvent e) {
@ -44,7 +45,7 @@ public class ElementOrderer<T> extends JDialog {
}
}
}.setToolTip("move item up").createJButton());
}.setToolTip(Lang.get("tt_moveItemDown")).createJButton());
getContentPane().add(buttons, BorderLayout.EAST);
pack();

View File

@ -1,6 +1,7 @@
package de.neemann.digital.gui.components;
import de.neemann.digital.core.ObservableValue;
import de.neemann.digital.lang.Lang;
import javax.swing.*;
import java.awt.*;
@ -15,7 +16,7 @@ public class SingleValueDialog extends JDialog {
private String returnText;
public SingleValueDialog(Point pos, String text) {
super((Frame) null, "Attributes", true);
super((Frame) null, Lang.get("attr_dialogTitle"), true);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
JTextField textField = new JTextField(30);

View File

@ -13,6 +13,7 @@ import de.neemann.digital.core.flipflops.T_FF;
import de.neemann.digital.core.io.Const;
import de.neemann.digital.core.io.In;
import de.neemann.digital.core.io.Out;
import de.neemann.digital.core.memory.LookUpTable;
import de.neemann.digital.core.wiring.*;
import java.util.ArrayList;
@ -36,7 +37,7 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
add(XOr.DESCRIPTION, "Logic");
add(XNOr.DESCRIPTION, "Logic");
add(Not.DESCRIPTION, "Logic");
add(Delay.DESCRIPTION, "Logic");
add(LookUpTable.DESCRIPTION, "Logic");
add(In.DESCRIPTION, "IO");
add(Out.DESCRIPTION, "IO");
@ -50,6 +51,7 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
add(Splitter.DESCRIPTION, "Wires");
add(Const.DESCRIPTION, "Wires");
add(Delay.DESCRIPTION, "Wires");
add(RS_FF.DESCRIPTION, "FlipFlops");
add(JK_FF.DESCRIPTION, "FlipFlops");

View File

@ -0,0 +1,44 @@
package de.neemann.digital.lang;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
/**
* @author hneemann
*/
public class Lang {
private static class InstanceHolder {
static final Lang INSTANCE = new Lang();
}
public static String get(String key, Object... params) {
return InstanceHolder.INSTANCE.getKey(key, params);
}
private ResourceBundle bundle;
private Lang() {
Locale currentLocale = Locale.getDefault();
try {
bundle = ResourceBundle.getBundle("lang/lang", currentLocale);
} catch (MissingResourceException e) {
bundle = ResourceBundle.getBundle("lang/lang", Locale.ENGLISH);
}
}
private String getKey(String key, Object... params) {
try {
String str = bundle.getString(key);
if (params != null && params.length > 0)
str = MessageFormat.format(str, params);
return str;
} catch (MissingResourceException e) {
System.out.println(key + "=" + key.substring(key.indexOf("_") + 1));
return key + " is missing";
}
}
}