mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-27 06:51:37 -04:00
Improved the SingleValueDialog to enter multi bit values
This commit is contained in:
parent
5a27cf916f
commit
7fc84db1f1
@ -5,54 +5,204 @@ import de.neemann.digital.gui.sync.Sync;
|
||||
import de.neemann.digital.lang.Lang;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Dialog to edit a single value.
|
||||
* Used to enter a multi bit input value
|
||||
* Used to enter a multi bit input value.
|
||||
*
|
||||
* @author hneemann
|
||||
* @author Rüdiger Heintz
|
||||
*/
|
||||
public final class SingleValueDialog extends JDialog {
|
||||
|
||||
private String returnText;
|
||||
private enum InMode {
|
||||
HEX(Lang.get("attr_dialogHex")),
|
||||
DECIMAL(Lang.get("attr_dialogDecimal")),
|
||||
OCTAL(Lang.get("attr_dialogOctal")),
|
||||
ASCII(Lang.get("attr_dialogAscii")),
|
||||
HIGHZ(Lang.get("attr_dialogHighz"));
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param pos the position to show the dialog
|
||||
* @param text the text to edit
|
||||
*/
|
||||
private SingleValueDialog(Point pos, String text) {
|
||||
private String langText;
|
||||
|
||||
InMode(String langKey) {
|
||||
this.langText = langKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return langText;
|
||||
}
|
||||
|
||||
public static InMode[] values(boolean supportsHighZ) {
|
||||
if (supportsHighZ) {
|
||||
return values();
|
||||
} else {
|
||||
return Arrays.copyOf(values(), values().length - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final JTextField textField;
|
||||
private final boolean supportsHighZ;
|
||||
private final JComboBox<InMode> formatComboBox;
|
||||
private JCheckBox[] checkBoxes;
|
||||
private boolean programmaticModifyingFormat = false;
|
||||
private long editValue;
|
||||
private boolean ok = false;
|
||||
|
||||
private SingleValueDialog(Point pos, ObservableValue value) {
|
||||
super((Frame) null, Lang.get("attr_dialogTitle"), true);
|
||||
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
||||
|
||||
JTextField textField = new JTextField(30);
|
||||
textField.setText(text);
|
||||
getContentPane().add(textField);
|
||||
editValue = value.getValue();
|
||||
supportsHighZ = value.supportsHighZ();
|
||||
|
||||
textField.addActionListener(new ActionListener() {
|
||||
textField = new JTextField(10);
|
||||
textField.setHorizontalAlignment(JTextField.RIGHT);
|
||||
formatComboBox = new JComboBox<>(InMode.values(supportsHighZ));
|
||||
formatComboBox.addActionListener(actionEvent -> {
|
||||
if (!programmaticModifyingFormat)
|
||||
setLongToDialog(editValue);
|
||||
});
|
||||
|
||||
JPanel panel = new JPanel(new DialogLayout());
|
||||
panel.add(formatComboBox, DialogLayout.LABEL);
|
||||
panel.add(textField, DialogLayout.INPUT);
|
||||
panel.add(new JLabel(Lang.get("attr_dialogBinary")), DialogLayout.LABEL);
|
||||
panel.add(createCheckBoxPanel(value.getBits(), editValue), DialogLayout.INPUT);
|
||||
getContentPane().add(panel);
|
||||
|
||||
textField.getDocument().addDocumentListener(new MyDocumentListener(() -> setStringToDialog(textField.getText())));
|
||||
|
||||
if (value.isHighZ())
|
||||
formatComboBox.setSelectedItem(InMode.HIGHZ);
|
||||
else
|
||||
setLongToDialog(editValue);
|
||||
|
||||
JButton okButton = new JButton(new AbstractAction(Lang.get("ok")) {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
returnText = textField.getText();
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
ok = true;
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
||||
buttonPanel.add(okButton);
|
||||
getContentPane().add(buttonPanel, BorderLayout.EAST);
|
||||
|
||||
getRootPane().setDefaultButton(okButton);
|
||||
getRootPane().registerKeyboardAction(actionEvent -> dispose(),
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
|
||||
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
|
||||
pack();
|
||||
setLocation(pos.x, pos.y);
|
||||
textField.requestFocus();
|
||||
textField.select(0, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* edits the given value
|
||||
*
|
||||
* @return result or null if dialog closed without something entered
|
||||
*/
|
||||
private String showDialog() {
|
||||
private JPanel createCheckBoxPanel(int bits, long value) {
|
||||
JPanel p = new JPanel();
|
||||
p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
|
||||
checkBoxes = new JCheckBox[bits];
|
||||
for (int i = bits - 1; i >= 0; i--) {
|
||||
final int bit = i;
|
||||
checkBoxes[bit] = new JCheckBox("", (value & (1L << bit)) != 0);
|
||||
checkBoxes[bit].setBorder(null);
|
||||
checkBoxes[bit].addActionListener(actionEvent -> setBit(bit, checkBoxes[bit].isSelected()));
|
||||
p.add(checkBoxes[bit]);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
private void setBit(int bitNum, boolean set) {
|
||||
if (set)
|
||||
editValue |= 1L << bitNum;
|
||||
else
|
||||
editValue &= ~(1L << bitNum);
|
||||
|
||||
if (getSelectedFormat().equals(InMode.HIGHZ))
|
||||
setSelectedFormat(InMode.HEX);
|
||||
|
||||
setLongToDialog(editValue);
|
||||
}
|
||||
|
||||
private void setLongToDialog(long editValue) {
|
||||
switch (getSelectedFormat()) {
|
||||
case ASCII:
|
||||
char val = (char) (editValue);
|
||||
textField.setText("\'" + val + "\'");
|
||||
textField.setCaretPosition(1);
|
||||
break;
|
||||
case DECIMAL:
|
||||
textField.setText(Long.toString(editValue));
|
||||
break;
|
||||
case HEX:
|
||||
textField.setText("0x" + Long.toHexString(editValue));
|
||||
break;
|
||||
case OCTAL:
|
||||
textField.setText("0" + Long.toOctalString(editValue));
|
||||
break;
|
||||
case HIGHZ:
|
||||
textField.setText("?");
|
||||
break;
|
||||
default:
|
||||
}
|
||||
textField.requestFocus();
|
||||
}
|
||||
|
||||
private InMode getSelectedFormat() {
|
||||
return (InMode) formatComboBox.getSelectedItem();
|
||||
}
|
||||
|
||||
private void setSelectedFormat(InMode format) {
|
||||
if (!getSelectedFormat().equals(format)) {
|
||||
programmaticModifyingFormat = true;
|
||||
formatComboBox.setSelectedItem(format);
|
||||
programmaticModifyingFormat = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void setStringToDialog(String text) {
|
||||
text = text.trim();
|
||||
if (text.length() > 0) {
|
||||
if (text.contains("?") && supportsHighZ) {
|
||||
setSelectedFormat(InMode.HIGHZ);
|
||||
editValue = 0;
|
||||
} else if (text.charAt(0) == '\'') {
|
||||
setSelectedFormat(InMode.ASCII);
|
||||
if (text.length() > 1) {
|
||||
editValue = text.charAt(1);
|
||||
} else {
|
||||
editValue = 0;
|
||||
}
|
||||
} else {
|
||||
if (text.startsWith("0x"))
|
||||
setSelectedFormat(InMode.HEX);
|
||||
else if (text.startsWith("0"))
|
||||
setSelectedFormat(InMode.OCTAL);
|
||||
else
|
||||
setSelectedFormat(InMode.DECIMAL);
|
||||
try {
|
||||
editValue = Long.decode(text);
|
||||
} catch (NumberFormatException e) {
|
||||
// do nothing on error
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < checkBoxes.length; i++)
|
||||
checkBoxes[i].setSelected((editValue & (1L << i)) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean showDialog() {
|
||||
setVisible(true);
|
||||
return returnText;
|
||||
return ok;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,23 +212,37 @@ public final class SingleValueDialog extends JDialog {
|
||||
* @param value the value to edit
|
||||
*/
|
||||
public static void editValue(Point pos, ObservableValue value, Sync modelSync) {
|
||||
String ret = new SingleValueDialog(pos, value.getValueString()).showDialog();
|
||||
if (ret != null) {
|
||||
ret = ret.trim();
|
||||
if (ret.equals("?") && value.supportsHighZ()) {
|
||||
modelSync.access(() -> {
|
||||
value.setHighZ(true);
|
||||
});
|
||||
SingleValueDialog svd = new SingleValueDialog(pos, value);
|
||||
if (svd.showDialog()) {
|
||||
if (svd.getSelectedFormat().equals(InMode.HIGHZ)) {
|
||||
modelSync.access(() -> value.setHighZ(true));
|
||||
} else {
|
||||
try {
|
||||
long l = Long.decode(ret);
|
||||
modelSync.access(() -> {
|
||||
value.set(l, false);
|
||||
});
|
||||
} catch (NumberFormatException e) {
|
||||
|
||||
}
|
||||
modelSync.access(() -> value.set(svd.editValue, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final class MyDocumentListener implements DocumentListener {
|
||||
private final Runnable runnable;
|
||||
|
||||
private MyDocumentListener(Runnable runnable) {
|
||||
this.runnable = runnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent documentEvent) {
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent documentEvent) {
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent documentEvent) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,12 @@
|
||||
<string name="attr_openCircuit_tt">Öffnet die Schaltung in einem neuen Fenster.</string>
|
||||
<string name="attr_help">Hilfe</string>
|
||||
<string name="attr_help_tt">Zeigt eine Beschreibung dieses Elements.</string>
|
||||
<string name="attr_dialogHex">Hex</string>
|
||||
<string name="attr_dialogDecimal">Dezimal</string>
|
||||
<string name="attr_dialogAscii">Ascii</string>
|
||||
<string name="attr_dialogHighz">HighZ</string>
|
||||
<string name="attr_dialogOctal">Oktal</string>
|
||||
<string name="attr_dialogBinary">Binär</string>
|
||||
<string name="btn_discard">Verwerfen</string>
|
||||
<string name="btn_edit">Bearbeiten</string>
|
||||
<string name="btn_editFurther">Weiter bearbeiten</string>
|
||||
|
@ -13,6 +13,12 @@
|
||||
<string name="attr_openCircuit_tt">Opens the circuit in a new window.</string>
|
||||
<string name="attr_help">Help</string>
|
||||
<string name="attr_help_tt">Shows a short description of this element.</string>
|
||||
<string name="attr_dialogHex">Hex</string>
|
||||
<string name="attr_dialogDecimal">Decimal</string>
|
||||
<string name="attr_dialogAscii">Ascii</string>
|
||||
<string name="attr_dialogHighz">HighZ</string>
|
||||
<string name="attr_dialogOctal">Octal</string>
|
||||
<string name="attr_dialogBinary">Binary</string>
|
||||
<string name="btn_discard">Discard Changes</string>
|
||||
<string name="btn_edit">Edit</string>
|
||||
<string name="btn_editFurther">Continue editing</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user