Merge remote-tracking branch 'remotes/origin/groupEdit'

Conflicts:
	src/main/java/de/neemann/digital/gui/components/EditorFactory.java
This commit is contained in:
hneemann 2017-09-12 10:56:34 +02:00
commit be49ce68e6
16 changed files with 5111 additions and 357 deletions

View File

@ -3,6 +3,8 @@ Release Notes
HEAD, planned as v0.15 HEAD, planned as v0.15
- Added an EEPROM which behaves like a memory that can be written and whose content - Added an EEPROM which behaves like a memory that can be written and whose content
is non-volatile. is non-volatile.
- Replaced shortcut 'B' with a more general attribute editing dialog (select
and left click).
v0.14, released on 31. Aug 2017 v0.14, released on 31. Aug 2017
- Added visualization of KV maps (thanks to roy77) - Added visualization of KV maps (thanks to roy77)

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,7 @@ public class Key<VALUE> {
private final String key; private final String key;
private final VALUE def; private final VALUE def;
private final String langKey; private final String langKey;
private boolean groupEditAllowed = false;
/** /**
* Creates a new Key * Creates a new Key
@ -84,6 +85,18 @@ public class Key<VALUE> {
return langKey; return langKey;
} }
/**
* @return true if group edit is allowed
*/
public boolean isGroupEditAllowed() {
return groupEditAllowed;
}
Key<VALUE> setGroupEditAllowed(boolean groupEditAllowed) {
this.groupEditAllowed = groupEditAllowed;
return this;
}
/** /**
* A integer attribute. * A integer attribute.
* Stores additional combo box values * Stores additional combo box values
@ -146,6 +159,7 @@ public class Key<VALUE> {
setMin(1); setMin(1);
super.setMax(64); super.setMax(64);
setComboBoxValues(VALUES); setComboBoxValues(VALUES);
setGroupEditAllowed(true);
} }
KeyBits setMax(int bits) { KeyBits setMax(int bits) {
@ -202,6 +216,7 @@ public class Key<VALUE> {
names = new String[values.length]; names = new String[values.length];
for (int i = 0; i < values.length; i++) for (int i = 0; i < values.length; i++)
names[i] = Lang.get(getLangKey(values[i])); names[i] = Lang.get(getLangKey(values[i]));
setGroupEditAllowed(true);
} }
/** /**

View File

@ -48,10 +48,11 @@ public final class Keys {
/** /**
* The size of a LED * The size of a LED
*/ */
public static final Key.KeyInteger SIZE public static final Key<Integer> SIZE
= new Key.KeyInteger("Size", 1) = new Key.KeyInteger("Size", 1)
.setComboBoxValues(new Integer[]{1, 2, 3, 4, 5}) .setComboBoxValues(new Integer[]{1, 2, 3, 4, 5})
.setMin(1); .setMin(1)
.setGroupEditAllowed(true);
/** /**
* The value of constants * The value of constants
@ -75,7 +76,7 @@ public final class Keys {
* Color of LEDs * Color of LEDs
*/ */
public static final Key<java.awt.Color> COLOR public static final Key<java.awt.Color> COLOR
= new Key<>("Color", java.awt.Color.RED); = new Key<>("Color", java.awt.Color.RED).setGroupEditAllowed(true);
/** /**
* Background Color of nested circuits * Background Color of nested circuits
@ -119,19 +120,19 @@ public final class Keys {
* indicates a diode as blown fuse or as programmed * indicates a diode as blown fuse or as programmed
*/ */
public static final Key<Boolean> BLOWN public static final Key<Boolean> BLOWN
= new Key<>("Blown", false); = new Key<>("Blown", false).setGroupEditAllowed(true);
/** /**
* indicates a switch as closed or not * indicates a switch as closed or not
*/ */
public static final Key<Boolean> CLOSED public static final Key<Boolean> CLOSED
= new Key<>("Closed", false); = new Key<>("Closed", false).setGroupEditAllowed(true);
/** /**
* signed flag for comparator element * signed flag for comparator element
*/ */
public static final Key<Boolean> SIGNED public static final Key<Boolean> SIGNED
= new Key<>("Signed", false); = new Key<>("Signed", false).setGroupEditAllowed(true);
/** /**
* the data key for memory * the data key for memory
@ -183,7 +184,7 @@ public final class Keys {
* flag to make a value a probe * flag to make a value a probe
*/ */
public static final Key<Boolean> VALUE_IS_PROBE public static final Key<Boolean> VALUE_IS_PROBE
= new Key<>("valueIsProbe", false); = new Key<>("valueIsProbe", false).setGroupEditAllowed(true);
/** /**
* flag to set a ROM as program memory * flag to set a ROM as program memory
@ -331,7 +332,7 @@ public final class Keys {
* Used to enable the storage of the last state in the Seven Seg display. * Used to enable the storage of the last state in the Seven Seg display.
*/ */
public static final Key<Boolean> LED_PERSISTENCE public static final Key<Boolean> LED_PERSISTENCE
= new Key<>("ledPersistence", false); = new Key<>("ledPersistence", false).setGroupEditAllowed(true);
/** /**
* Fitter for the atf1502 * Fitter for the atf1502
@ -339,12 +340,6 @@ public final class Keys {
public static final Key<File> SETTINGS_ATF1502_FITTER public static final Key<File> SETTINGS_ATF1502_FITTER
= new Key.KeyFile("atf1502Fitter", new File("c:/Wincupl/WinCupl/Fitters")).setDirectoryOnly(true); = new Key.KeyFile("atf1502Fitter", new File("c:/Wincupl/WinCupl/Fitters")).setDirectoryOnly(true);
/**
* A pin number, empty means no pin assigned
*/
public static final Key<String> PIN
= new Key<>("pin", "");
/** /**
* row bits in led matrix * row bits in led matrix
*/ */
@ -414,7 +409,7 @@ public final class Keys {
* true if component is active low * true if component is active low
*/ */
public static final Key<Boolean> ACTIVE_LOW public static final Key<Boolean> ACTIVE_LOW
= new Key<>("activeLow", false); = new Key<>("activeLow", false).setGroupEditAllowed(true);
/** /**
* Fitter for the atf1502 * Fitter for the atf1502

View File

@ -13,6 +13,7 @@ import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
/** /**
* Dialog used to edit Attributes. * Dialog used to edit Attributes.
@ -32,6 +33,8 @@ public class AttributeDialog extends JDialog {
private final ElementAttributes originalAttributes; private final ElementAttributes originalAttributes;
private final ElementAttributes modifiedAttributes; private final ElementAttributes modifiedAttributes;
private final JPanel buttonPanel; private final JPanel buttonPanel;
private final ConstrainsBuilder constrains;
private HashMap<Key, JCheckBox> checkBoxes;
private JComponent topMostTextComponent; private JComponent topMostTextComponent;
private VisualElement visualElement; private VisualElement visualElement;
private boolean okPressed = false; private boolean okPressed = false;
@ -44,7 +47,7 @@ public class AttributeDialog extends JDialog {
* @param elementAttributes the data stored * @param elementAttributes the data stored
*/ */
public AttributeDialog(Component parent, java.util.List<Key> list, ElementAttributes elementAttributes) { public AttributeDialog(Component parent, java.util.List<Key> list, ElementAttributes elementAttributes) {
this(parent, null, list, elementAttributes); this(parent, null, list, elementAttributes, false);
} }
/** /**
@ -56,6 +59,19 @@ public class AttributeDialog extends JDialog {
* @param elementAttributes the data stored * @param elementAttributes the data stored
*/ */
public AttributeDialog(Component parent, Point pos, java.util.List<Key> list, ElementAttributes elementAttributes) { public AttributeDialog(Component parent, Point pos, java.util.List<Key> list, ElementAttributes elementAttributes) {
this(parent, pos, list, elementAttributes, false);
}
/**
* Creates a new instance
*
* @param parent the parent
* @param pos the position to pop up the dialog
* @param list the list of keys which are to edit
* @param elementAttributes the data stored
* @param addCheckBoxes add checkboxes behind the attributes
*/
public AttributeDialog(Component parent, Point pos, java.util.List<Key> list, ElementAttributes elementAttributes, boolean addCheckBoxes) {
super(SwingUtilities.getWindowAncestor(parent), Lang.get("attr_dialogTitle"), ModalityType.APPLICATION_MODAL); super(SwingUtilities.getWindowAncestor(parent), Lang.get("attr_dialogTitle"), ModalityType.APPLICATION_MODAL);
this.parent = parent; this.parent = parent;
this.pos = pos; this.pos = pos;
@ -63,17 +79,27 @@ public class AttributeDialog extends JDialog {
this.modifiedAttributes = new ElementAttributes(elementAttributes); this.modifiedAttributes = new ElementAttributes(elementAttributes);
setDefaultCloseOperation(DISPOSE_ON_CLOSE); setDefaultCloseOperation(DISPOSE_ON_CLOSE);
panel = new JPanel(new DialogLayout()); panel = new JPanel(new GridBagLayout());
getContentPane().add(new JScrollPane(panel)); getContentPane().add(new JScrollPane(panel));
editors = new ArrayList<>(); editors = new ArrayList<>();
topMostTextComponent = null; topMostTextComponent = null;
constrains = new ConstrainsBuilder().inset(3).fill();
for (Key key : list) { for (Key key : list) {
Editor e = EditorFactory.INSTANCE.create(key, modifiedAttributes.get(key)); Editor e = EditorFactory.INSTANCE.create(key, modifiedAttributes.get(key));
editors.add(new EditorHolder(e, key)); editors.add(new EditorHolder(e, key));
e.addToPanel(panel, key, modifiedAttributes, this); e.addToPanel(panel, key, modifiedAttributes, this, constrains);
if (addCheckBoxes) {
if (checkBoxes == null)
checkBoxes = new HashMap<>();
JCheckBox checkBox = new JCheckBox();
checkBox.setToolTipText(Lang.get("msg_modifyThisAttribute"));
checkBoxes.put(key, checkBox);
panel.add(checkBox, constrains.x(2));
}
constrains.nextRow();
if (topMostTextComponent == null && e instanceof EditorFactory.StringEditor) if (topMostTextComponent == null && e instanceof EditorFactory.StringEditor)
topMostTextComponent = ((EditorFactory.StringEditor) e).getTextComponent(); topMostTextComponent = ((EditorFactory.StringEditor) e).getTextComponent();
@ -119,6 +145,13 @@ public class AttributeDialog extends JDialog {
dispose(); dispose();
} }
/**
* @return the keys check boxes
*/
public HashMap<Key, JCheckBox> getCheckBoxes() {
return checkBoxes;
}
/** /**
* Adds a button to this dialog * Adds a button to this dialog
* *
@ -127,13 +160,14 @@ public class AttributeDialog extends JDialog {
* @return this for chained calls * @return this for chained calls
*/ */
public AttributeDialog addButton(String label, ToolTipAction action) { public AttributeDialog addButton(String label, ToolTipAction action) {
panel.add(new JLabel(label), DialogLayout.LABEL); panel.add(new JLabel(label), constrains);
panel.add(action.createJButton(), DialogLayout.INPUT); panel.add(action.createJButton(), constrains.x(1));
constrains.nextRow();
return this; return this;
} }
/** /**
* Adds a button to the bottom of this dialog * Adds a button to the botton of this dialog
* *
* @param action the action * @param action the action
* @return this for chained calls * @return this for chained calls
@ -181,6 +215,14 @@ public class AttributeDialog extends JDialog {
return parent; return parent;
} }
/**
* @return true if ok is pressed
*/
public boolean isOkPressed() {
return okPressed;
}
/** /**
* @return the containing Main instance or null * @return the containing Main instance or null
*/ */

View File

@ -7,6 +7,7 @@ import de.neemann.digital.core.element.*;
import de.neemann.digital.core.io.In; import de.neemann.digital.core.io.In;
import de.neemann.digital.core.io.InValue; import de.neemann.digital.core.io.InValue;
import de.neemann.digital.draw.elements.*; import de.neemann.digital.draw.elements.*;
import de.neemann.digital.draw.graphics.Vector;
import de.neemann.digital.draw.shapes.InputShape; import de.neemann.digital.draw.shapes.InputShape;
import de.neemann.digital.gui.components.modification.*; import de.neemann.digital.gui.components.modification.*;
import de.neemann.digital.draw.graphics.*; import de.neemann.digital.draw.graphics.*;
@ -33,9 +34,7 @@ import java.awt.geom.Point2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.List; import java.util.List;
import static de.neemann.digital.draw.shapes.GenericShape.SIZE; import static de.neemann.digital.draw.shapes.GenericShape.SIZE;
@ -45,6 +44,7 @@ import static java.awt.event.InputEvent.CTRL_DOWN_MASK;
/** /**
* Component which shows the circuit. * Component which shows the circuit.
* ToDo: refactoring of repaint logic. Its to complex now. * ToDo: refactoring of repaint logic. Its to complex now.
* ToDo: class is to large, move the MouseController classes to their own package
* *
* @author hneemann * @author hneemann
*/ */
@ -187,8 +187,6 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe
new PlusMinusAction(1).setAccelerator("PLUS").enableAcceleratorIn(this); new PlusMinusAction(1).setAccelerator("PLUS").enableAcceleratorIn(this);
new PlusMinusAction(-1).setAccelerator("MINUS").enableAcceleratorIn(this); new PlusMinusAction(-1).setAccelerator("MINUS").enableAcceleratorIn(this);
new BitSetAction().setAccelerator("B").enableAcceleratorIn(this);
new ToolTipAction(Lang.get("menu_programDiode")) { new ToolTipAction(Lang.get("menu_programDiode")) {
@Override @Override
public void actionPerformed(ActionEvent e) { // is allowed also if locked! public void actionPerformed(ActionEvent e) { // is allowed also if locked!
@ -978,6 +976,59 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe
return library; return library;
} }
private void editGroup(Vector min, Vector max) {
if (!isLocked())
try {
ArrayList<Key> keyList = new ArrayList<>();
ArrayList<VisualElement> elementList = new ArrayList<>();
HashMap<Key, Boolean> useKeyMap = new HashMap<>();
ElementAttributes attr = new ElementAttributes();
for (VisualElement ve : circuit.getElements())
if (ve.matches(min, max)) {
elementList.add(ve);
for (Key k : library.getElementType(ve.getElementName()).getAttributeList()) {
if (k.isGroupEditAllowed()) {
if (keyList.contains(k)) {
if (!ve.getElementAttributes().get(k).equals(attr.get(k))) {
useKeyMap.put(k, false);
}
} else {
keyList.add(k);
attr.set(k, ve.getElementAttributes().get(k));
useKeyMap.put(k, true);
}
}
}
}
if (keyList.size() > 0) {
AttributeDialog ad = new AttributeDialog(this, null, keyList, attr, true);
for (Map.Entry<Key, Boolean> u : useKeyMap.entrySet())
ad.getCheckBoxes().get(u.getKey()).setSelected(u.getValue());
ElementAttributes mod = ad.showDialog();
if (ad.isOkPressed()) {
if (mod == null) mod = attr;
Modifications.Builder modBuilder = new Modifications.Builder(Lang.get("mod_groupEdit"));
for (Key key : keyList)
if (ad.getCheckBoxes().get(key).isSelected()) {
Object newVal = mod.get(key);
for (VisualElement ve : elementList) {
if (library.getElementType(ve.getElementName()).getAttributeList().contains(key)) {
if (!ve.getElementAttributes().get(key).equals(newVal))
modBuilder.add(new ModifyAttribute<>(ve, key, newVal));
}
}
}
modify(modBuilder.build());
}
}
} catch (ElementNotFoundException e) {
// Do nothing if an element is not in library
}
}
private final class PlusMinusAction extends ToolTipAction { private final class PlusMinusAction extends ToolTipAction {
private final int delta; private final int delta;
@ -1005,38 +1056,6 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe
} }
} }
private final class BitSetAction extends ToolTipAction {
private BitSetAction() {
super("setBits");
}
@Override
public void actionPerformed(ActionEvent e) {
if (!isLocked()) {
if (activeMouseController instanceof MouseControllerSelect) {
MouseControllerSelect mouseControllerSelect = (MouseControllerSelect) activeMouseController;
String num = JOptionPane.showInputDialog(CircuitComponent.this, Lang.get("key_Bits"), "1");
if (num != null) {
try {
int bits = Integer.decode(num);
Vector c1 = mouseControllerSelect.corner1;
Vector c2 = mouseControllerSelect.corner2;
ModifySetBits modifySetBits = new ModifySetBits(c1, c2, bits);
if (modifySetBits.isSomethingToDo(circuit, library))
modify(modifySetBits);
removeHighLighted();
mouseNormal.activate();
} catch (NumberFormatException ex) {
new ErrorMessage(Lang.get("msg_stringIsNotANumber_N", num)).show(CircuitComponent.this);
}
}
}
}
}
}
private class MouseDispatcher extends MouseAdapter implements MouseMotionListener { private class MouseDispatcher extends MouseAdapter implements MouseMotionListener {
private Vector pos; private Vector pos;
private boolean isMoved; private boolean isMoved;
@ -1610,8 +1629,14 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe
@Override @Override
void clicked(MouseEvent e) { void clicked(MouseEvent e) {
mouseNormal.activate(); if (e.getButton() == MouseEvent.BUTTON1) {
removeHighLighted(); mouseNormal.activate();
removeHighLighted();
} else if (e.getButton() == MouseEvent.BUTTON3) {
editGroup(Vector.min(corner1, corner2), Vector.max(corner1, corner2));
mouseNormal.activate();
removeHighLighted();
}
} }
@Override @Override

View File

@ -0,0 +1,142 @@
package de.neemann.digital.gui.components;
import java.awt.*;
/**
* More simple to use GridBagConstrains
*/
public class ConstrainsBuilder extends GridBagConstraints {
/**
* Creates a new instance.
* Position is set to (0,0)
*/
public ConstrainsBuilder() {
gridx = 0;
gridy = 0;
}
private ConstrainsBuilder(ConstrainsBuilder original) {
gridx = original.gridx;
gridy = original.gridy;
gridwidth = original.gridwidth;
gridheight = original.gridheight;
weightx = original.weightx;
weighty = original.weighty;
ipadx = original.ipadx;
ipady = original.ipady;
fill = original.fill;
insets = original.insets;
}
/**
* Sets the position
*
* @param x x position
* @param y y position
* @return the new created ConstrainsBuilder instance
*/
public ConstrainsBuilder pos(int x, int y) {
ConstrainsBuilder c = new ConstrainsBuilder(this);
c.gridx = x;
c.gridy = y;
return c;
}
/**
* Sets the position
*
* @param x x position
* @return the new created ConstrainsBuilder instance
*/
public ConstrainsBuilder x(int x) {
ConstrainsBuilder c = new ConstrainsBuilder(this);
c.gridx = x;
return c;
}
/**
* Sets the width
*
* @param x width
* @return the new created ConstrainsBuilder instance
*/
public ConstrainsBuilder width(int x) {
ConstrainsBuilder c = new ConstrainsBuilder(this);
c.gridwidth = x;
return c;
}
/**
* Sets a dynamic height
*
* @return the new created ConstrainsBuilder instance
*/
public ConstrainsBuilder dynamicHeight() {
ConstrainsBuilder c = new ConstrainsBuilder(this);
c.weighty = 1;
return c;
}
/**
* Sets a dynamic width
*
* @return the new created ConstrainsBuilder instance
*/
public ConstrainsBuilder dynamicWidth() {
ConstrainsBuilder c = new ConstrainsBuilder(this);
c.weightx = 1;
return c;
}
/**
* Sets the padding
*
* @param x x padding
* @param y y padding
* @return the new created ConstrainsBuilder instance
*/
public ConstrainsBuilder pad(int x, int y) {
ConstrainsBuilder c = new ConstrainsBuilder(this);
c.ipadx = x;
c.ipady = y;
return c;
}
/**
* Sets the fill attribute to BOTH
*
* @return the new created ConstrainsBuilder instance
*/
public ConstrainsBuilder fill() {
ConstrainsBuilder c = new ConstrainsBuilder(this);
c.fill = GridBagConstraints.BOTH;
return c;
}
/**
* Sets insets to a border of width b
*
* @param b border width
* @return the new created ConstrainsBuilder instance
*/
public ConstrainsBuilder inset(int b) {
ConstrainsBuilder c = new ConstrainsBuilder(this);
c.insets = new Insets(b, b, b, b);
return c;
}
/**
* Increases the row.
* Does not create a new instance!
*
* @return this for chained calls
*/
public ConstrainsBuilder nextRow() {
gridx = 0;
gridy++;
return this;
}
}

View File

@ -1,279 +0,0 @@
package de.neemann.digital.gui.components;
import java.awt.*;
import java.util.ArrayList;
/**
* Layout manager used in teh GUI dialog
*
* @author hneemann
*/
public class DialogLayout implements LayoutManager {
/**
* Used to indicate the element as a label
*/
public static final String LABEL = "label";
/**
* Used to indicate the element as a label
*/
public static final String INPUT = "input";
/**
* Used to indicate that the element should use the space for label and input (e.g. CheckBoxes)
*/
public static final String BOTH = "both";
/**
* Use label and input column, but indent field
*/
public static final String BOTHINDENT = "indent";
/**
* Use label and input column, height is adjustable
*/
public static final String BOTHDYNAMIC = "bothDyn";
private static final int BOTHOFFSET = 20;
private static final int SPACEX = 5;
private static final int SPACEY = 5;
private ArrayList<Line> lines;
private int label;
private boolean initialized = false;
private int dynCount;
/**
* @return true if the are fields with
*/
public boolean isDynamic() {
initialize();
return dynCount > 0;
}
private static class Line {
private boolean both;
private Component label;
private Component input;
private boolean indent;
private boolean dynamic;
Line(Component both, boolean indent) {
this.label = both;
this.both = true;
this.indent = indent;
}
Line(Component component, String s) {
both = false;
if (LABEL.equals(s)) label = component;
else if (INPUT.equals(s)) input = component;
else throw new IllegalArgumentException();
}
public Component getLabel() {
return label;
}
public Component getInput() {
return input;
}
public void setLabel(Component component) {
label = component;
}
public boolean isLabelFree() {
return !both && label == null;
}
public boolean isInputFree() {
return !both && input == null;
}
public void setInput(Component input) {
this.input = input;
}
public boolean isBoth() {
return both;
}
public int getHeight() {
if (both) return label.getPreferredSize().height;
else {
int height = 0;
if (label != null) {
int h = label.getPreferredSize().height;
if (h > height) height = h;
}
if (input != null) {
int h = input.getPreferredSize().height;
if (h > height) height = h;
}
return height;
}
}
public boolean isIndent() {
return indent;
}
public void setDynamic(boolean dynamic) {
this.dynamic = dynamic;
}
public boolean isDynamic() {
return dynamic;
}
public void initialize() {
if (both) {
if (label instanceof Container)
initContainer((Container) label);
}
}
private void initContainer(Container container) {
for (int i = 0; i < container.getComponentCount(); i++) {
Component c = container.getComponent(i);
if (c instanceof Container /*&& !(((Container)c).getLayout() instanceof DialogLayout)*/)
initContainer((Container) c);
}
LayoutManager lm = container.getLayout();
if (lm instanceof DialogLayout) {
DialogLayout dl = (DialogLayout) lm;
if (dl.isDynamic()) setDynamic(true);
}
}
}
/**
* Creates a new Layout for the edit dialog
*/
public DialogLayout() {
lines = new ArrayList<Line>();
}
@Override
public void addLayoutComponent(String s, Component component) {
if (BOTH.equals(s)) {
lines.add(new Line(component, false));
} else if (BOTHDYNAMIC.equals(s)) {
Line l = new Line(component, false);
lines.add(l);
l.setDynamic(true);
} else if (BOTHINDENT.equals(s)) {
lines.add(new Line(component, true));
} else if (LABEL.equals(s)) {
if (lines.size() > 0 && lines.get(lines.size() - 1).isLabelFree())
lines.get(lines.size() - 1).setLabel(component);
else
lines.add(new Line(component, LABEL));
} else if (INPUT.equals(s)) {
addInput(component);
} else
throw new IllegalArgumentException();
}
private Line addInput(Component component) {
Line l;
if (lines.size() > 0 && lines.get(lines.size() - 1).isInputFree()) {
l = lines.get(lines.size() - 1);
l.setInput(component);
} else {
l = new Line(component, INPUT);
lines.add(l);
}
return l;
}
@Override
public void removeLayoutComponent(Component component) {
throw new UnsupportedOperationException();
}
@Override
public Dimension preferredLayoutSize(Container container) {
return minimumLayoutSize(container);
}
private void initialize() {
if (!initialized) {
dynCount = 0;
for (Line l : lines) {
l.initialize();
if (l.isDynamic()) dynCount++;
}
initialized = true;
}
}
@Override
public Dimension minimumLayoutSize(Container container) {
initialize();
int both = 0;
label = 0;
int input = 0;
int height = 0;
for (Line l : lines) {
if (l.isBoth()) {
int w = l.getLabel().getPreferredSize().width;
if (l.isIndent()) w += BOTHOFFSET;
if (w > both) both = w;
} else {
if (l.getLabel() != null) {
int w = l.getLabel().getPreferredSize().width;
if (w > label) label = w;
}
if (l.getInput() != null) {
int w = l.getInput().getPreferredSize().width;
if (w > input) input = w;
}
}
height += l.getHeight();
}
Insets in = container.getInsets();
return new Dimension(Math.max(both + SPACEX * 2, label + input + SPACEX * 3) + in.left + in.right, height + in.top + in.bottom + (lines.size() + 1) * SPACEY);
}
@Override
public void layoutContainer(Container container) {
Dimension minSize = minimumLayoutSize(container);
Insets in = container.getInsets();
int dynAddendum = 0;
if (dynCount > 0) dynAddendum = (container.getSize().height - minSize.height) / dynCount;
int width = container.getSize().width;
int top = in.top + SPACEY;
for (Line l : lines) {
int height = l.getHeight();
if (l.isDynamic()) height += dynAddendum;
if (l.isBoth()) {
Component c = l.getLabel();
if (l.isIndent()) {
c.setLocation(in.left + BOTHOFFSET + SPACEX, top);
c.setSize(width - BOTHOFFSET - SPACEX * 2 - in.left - in.right, height);
} else {
c.setLocation(in.left + SPACEX, top);
c.setSize(width - SPACEX * 2 - in.left - in.right, height);
}
} else {
Component labelComp = l.getLabel();
if (labelComp != null) {
labelComp.setLocation(in.left + SPACEX, top);
labelComp.setSize(label, height);
}
Component inputComp = l.getInput();
if (inputComp != null) {
inputComp.setLocation(label + in.left + SPACEX * 2, top);
inputComp.setSize(width - label - SPACEX * 3 - in.left - in.right, height);
}
}
top += height + SPACEY;
}
}
}

View File

@ -23,6 +23,7 @@ public interface Editor<T> {
* @param key the key which is to edit * @param key the key which is to edit
* @param elementAttributes the attributes * @param elementAttributes the attributes
* @param dialog the containing dialog * @param dialog the containing dialog
* @param constrains the constrains used to place the components in the panel
*/ */
void addToPanel(JPanel panel, Key key, ElementAttributes elementAttributes, AttributeDialog dialog); void addToPanel(JPanel panel, Key key, ElementAttributes elementAttributes, AttributeDialog dialog, ConstrainsBuilder constrains);
} }

View File

@ -97,7 +97,7 @@ public final class EditorFactory {
private boolean labelAtTop = false; private boolean labelAtTop = false;
@Override @Override
public void addToPanel(JPanel panel, Key key, ElementAttributes elementAttributes, AttributeDialog attributeDialog) { public void addToPanel(JPanel panel, Key key, ElementAttributes elementAttributes, AttributeDialog attributeDialog, ConstrainsBuilder constrains) {
this.attributeDialog = attributeDialog; this.attributeDialog = attributeDialog;
JLabel label = new JLabel(key.getName() + ": "); JLabel label = new JLabel(key.getName() + ": ");
final String description = new LineBreaker().toHTML().breakLines(key.getDescription()); final String description = new LineBreaker().toHTML().breakLines(key.getDescription());
@ -105,11 +105,12 @@ public final class EditorFactory {
JComponent component = getComponent(elementAttributes); JComponent component = getComponent(elementAttributes);
component.setToolTipText(description); component.setToolTipText(description);
if (labelAtTop) { if (labelAtTop) {
panel.add(label, DialogLayout.BOTH); panel.add(label, constrains.width(2));
panel.add(component, DialogLayout.BOTHDYNAMIC); constrains.nextRow();
panel.add(component, constrains.width(2).dynamicHeight());
} else { } else {
panel.add(label, DialogLayout.LABEL); panel.add(label, constrains);
panel.add(component, DialogLayout.INPUT); panel.add(component, constrains.x(1).dynamicWidth());
} }
} }
@ -255,8 +256,8 @@ public final class EditorFactory {
} }
@Override @Override
public void addToPanel(JPanel panel, Key key, ElementAttributes elementAttributes, AttributeDialog attributeDialog) { public void addToPanel(JPanel panel, Key key, ElementAttributes elementAttributes, AttributeDialog attributeDialog, ConstrainsBuilder constrains) {
panel.add(bool, DialogLayout.BOTH); panel.add(bool, constrains.width(2));
} }
} }

View File

@ -89,11 +89,13 @@ public final class SingleValueDialog extends JDialog implements ModelStateObserv
setLongToDialog(editValue); setLongToDialog(editValue);
}); });
JPanel panel = new JPanel(new DialogLayout()); JPanel panel = new JPanel(new GridBagLayout());
panel.add(formatComboBox, DialogLayout.LABEL); ConstrainsBuilder constr = new ConstrainsBuilder().inset(3).fill();
panel.add(textField, DialogLayout.INPUT); panel.add(formatComboBox, constr);
panel.add(new JLabel(Lang.get("attr_dialogBinary")), DialogLayout.LABEL); panel.add(textField, constr.dynamicWidth().x(1));
panel.add(createCheckBoxPanel(value.getBits(), editValue), DialogLayout.INPUT); constr.nextRow();
panel.add(new JLabel(Lang.get("attr_dialogBinary")), constr);
panel.add(createCheckBoxPanel(value.getBits(), editValue), constr.dynamicWidth().x(1));
getContentPane().add(panel); getContentPane().add(panel);
textField.getDocument().addDocumentListener(new MyDocumentListener(() -> setStringToDialog(textField.getText()))); textField.getDocument().addDocumentListener(new MyDocumentListener(() -> setStringToDialog(textField.getText())));

View File

@ -756,6 +756,7 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
<string name="mod_circuitAttrModified">Schaltungsattribute verändert.</string> <string name="mod_circuitAttrModified">Schaltungsattribute verändert.</string>
<string name="mod_modifiedMeasurementOrdering">Reihenfolge der Messwerte verändert.</string> <string name="mod_modifiedMeasurementOrdering">Reihenfolge der Messwerte verändert.</string>
<string name="mod_set_N_BitsToSelection">In selektierten Elementen die Zahl der Daten-Bits auf {0} gesetzt.</string> <string name="mod_set_N_BitsToSelection">In selektierten Elementen die Zahl der Daten-Bits auf {0} gesetzt.</string>
<string name="mod_groupEdit">In selektierten Elementen Attribute geändert.</string>
<string name="lib_Logic">Logisch</string> <string name="lib_Logic">Logisch</string>
<string name="lib_arithmetic">Arithmetik</string> <string name="lib_arithmetic">Arithmetik</string>
@ -1014,7 +1015,7 @@ eine &lt;a href=&quot;https://github.com/hneemann/Digital/issues/new?labels=enha
<string name="msg_modelHasErrors">Es kann nur eine fehlerfreie Schaltung exportiert werden!</string> <string name="msg_modelHasErrors">Es kann nur eine fehlerfreie Schaltung exportiert werden!</string>
<string name="msg_noKVMapAvailable">Keine KV-Tafel verfügbar!</string> <string name="msg_noKVMapAvailable">Keine KV-Tafel verfügbar!</string>
<string name="msg_dataNotUpdatedAnymore">Daten werden nicht mehr aktualisiert!</string> <string name="msg_dataNotUpdatedAnymore">Daten werden nicht mehr aktualisiert!</string>
<string name="msg_stringIsNotANumber_N">Der String {0} ist keine Zahl!</string> <string name="msg_modifyThisAttribute">Diesen Wert verändern.</string>
<string name="ok">Ok</string> <string name="ok">Ok</string>
<string name="rot_0"></string> <string name="rot_0"></string>

View File

@ -740,6 +740,7 @@ The names of the variables may not be unique.</string>
<string name="mod_circuitAttrModified">Modified circuit attributes.</string> <string name="mod_circuitAttrModified">Modified circuit attributes.</string>
<string name="mod_modifiedMeasurementOrdering">Ordered measurements.</string> <string name="mod_modifiedMeasurementOrdering">Ordered measurements.</string>
<string name="mod_set_N_BitsToSelection">Sets the number of data bits to {0} in selected components.</string> <string name="mod_set_N_BitsToSelection">Sets the number of data bits to {0} in selected components.</string>
<string name="mod_groupEdit">Modified attributes of selected components.</string>
<string name="lib_Logic">Logic</string> <string name="lib_Logic">Logic</string>
<string name="lib_arithmetic">Arithmetic</string> <string name="lib_arithmetic">Arithmetic</string>
@ -920,7 +921,6 @@ The names of the variables may not be unique.</string>
<string name="menu_pdfDocumentation">Documentation</string> <string name="menu_pdfDocumentation">Documentation</string>
<string name="menu_openPdfDocumentation">Open {0}</string> <string name="menu_openPdfDocumentation">Open {0}</string>
<string name="msg_errorOpeningDocumentation">Error opening a PDF file!</string> <string name="msg_errorOpeningDocumentation">Error opening a PDF file!</string>
<string name="msg_stringIsNotANumber_N">The string {0} is not a number!</string>
<string name="message">&lt;h1&gt;Digital&lt;/h1&gt;A simple simulator for digital circuits. <string name="message">&lt;h1&gt;Digital&lt;/h1&gt;A simple simulator for digital circuits.
Written by H. Neemann in 2016, 2017. Written by H. Neemann in 2016, 2017.
@ -996,6 +996,7 @@ an &lt;a href=&quot;https://github.com/hneemann/Digital/issues/new?labels=enhanc
<string name="msg_modelHasErrors">You can only export a circuit without errors!</string> <string name="msg_modelHasErrors">You can only export a circuit without errors!</string>
<string name="msg_noKVMapAvailable">No KV map available!</string> <string name="msg_noKVMapAvailable">No KV map available!</string>
<string name="msg_dataNotUpdatedAnymore">Data will not be updated anymore!</string> <string name="msg_dataNotUpdatedAnymore">Data will not be updated anymore!</string>
<string name="msg_modifyThisAttribute">Modify this Value</string>
<string name="ok">Ok</string> <string name="ok">Ok</string>
<string name="rot_0"></string> <string name="rot_0"></string>

View File

@ -388,7 +388,6 @@
<shortcut key="STRG-S">Speichern der Schaltung.</shortcut> <shortcut key="STRG-S">Speichern der Schaltung.</shortcut>
<shortcut key="STRG-Z">Letzte Änderung zurücknehmen.</shortcut> <shortcut key="STRG-Z">Letzte Änderung zurücknehmen.</shortcut>
<shortcut key="STRG-Y">Zurückgenommene Änderung erneut anwenden.</shortcut> <shortcut key="STRG-Y">Zurückgenommene Änderung erneut anwenden.</shortcut>
<shortcut key="B">Anzahl der Datenbits in allen selektierten Elementen setzen.</shortcut>
<shortcut key="P">Programmieren einer Diode oder eines FG-FET.</shortcut> <shortcut key="P">Programmieren einer Diode oder eines FG-FET.</shortcut>
<shortcut key="D">Beim Ziehen einer rechteckigen Leitung in den Diagonalmodus wechseln.</shortcut> <shortcut key="D">Beim Ziehen einer rechteckigen Leitung in den Diagonalmodus wechseln.</shortcut>
<shortcut key="F">Beim Ziehen einer rechteckigen Leitung die Orientierung wechseln.</shortcut> <shortcut key="F">Beim Ziehen einer rechteckigen Leitung die Orientierung wechseln.</shortcut>

View File

@ -326,7 +326,6 @@
<shortcut key="CTRL-S">Save the circuit.</shortcut> <shortcut key="CTRL-S">Save the circuit.</shortcut>
<shortcut key="CTRL-Z">Undo last modification.</shortcut> <shortcut key="CTRL-Z">Undo last modification.</shortcut>
<shortcut key="CTRL-Y">Redo the last undone modification.</shortcut> <shortcut key="CTRL-Y">Redo the last undone modification.</shortcut>
<shortcut key="B">Set the number of data bits in all selected components.</shortcut>
<shortcut key="P">Programs a diode or a FG-FET.</shortcut> <shortcut key="P">Programs a diode or a FG-FET.</shortcut>
<shortcut key="D">While drawing a wire switches to the diagonal mode.</shortcut> <shortcut key="D">While drawing a wire switches to the diagonal mode.</shortcut>
<shortcut key="F">While drawing a line flips the orientation.</shortcut> <shortcut key="F">While drawing a line flips the orientation.</shortcut>

View File

@ -60,7 +60,9 @@
<!-- Checks for Size Violations. --> <!-- Checks for Size Violations. -->
<!-- See http://checkstyle.sf.net/config_sizes.html --> <!-- See http://checkstyle.sf.net/config_sizes.html -->
<module name="FileLength"/> <module name="FileLength">
<property name="max" value="2500"/>
</module>
<!-- Checks for whitespace --> <!-- Checks for whitespace -->
<!-- See http://checkstyle.sf.net/config_whitespace.html --> <!-- See http://checkstyle.sf.net/config_whitespace.html -->