diff --git a/src/main/dig/Ampel_Einfach.dig b/src/main/dig/Ampel_Einfach.dig
index 287e379a4..2de9f4cd7 100644
--- a/src/main/dig/Ampel_Einfach.dig
+++ b/src/main/dig/Ampel_Einfach.dig
@@ -5,6 +5,10 @@
JK_FF
+
+ valueIsProbe
+ true
+
Label
z_0
@@ -16,6 +20,10 @@
JK_FF
+
+ valueIsProbe
+ true
+
Label
z_1
@@ -36,6 +44,21 @@
0
+
+ Clock
+
+
+ Label
+ Takt
+
+
+ Frequency
+ 10
+
+
+
+ 0
+
LED
@@ -87,17 +110,6 @@
0
-
- Clock
-
-
- Label
- Takt
-
-
-
- 0
-
@@ -201,4 +213,12 @@
+
+ Takt
+ z_0
+ z_1
+ Rot
+ Gelb
+ GrĂ¼n
+
\ No newline at end of file
diff --git a/src/main/dig/MS-JK.dig b/src/main/dig/MS-JK.dig
index cca6d0baa..6d09b1c86 100644
--- a/src/main/dig/MS-JK.dig
+++ b/src/main/dig/MS-JK.dig
@@ -1,5 +1,6 @@
+ 1
And
@@ -9,7 +10,7 @@
3
-
+
0
@@ -20,13 +21,13 @@
3
-
+
0
Not
-
+
0
@@ -41,7 +42,7 @@
1
-
+
0
@@ -52,43 +53,43 @@
C
-
+
0
NOr
-
+
0
NOr
-
+
0
And
-
+
0
And
-
+
0
NOr
-
+
0
NOr
-
+
0
@@ -99,7 +100,7 @@
Q
-
+
0
@@ -110,7 +111,7 @@
~Q
-
+
0
@@ -125,214 +126,221 @@
1
-
+
0
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ C
+ J
+ K
+ Q
+ ~Q
+
\ No newline at end of file
diff --git a/src/main/java/de/neemann/digital/core/Model.java b/src/main/java/de/neemann/digital/core/Model.java
index f99a47bbc..fc4f924c6 100644
--- a/src/main/java/de/neemann/digital/core/Model.java
+++ b/src/main/java/de/neemann/digital/core/Model.java
@@ -361,6 +361,16 @@ public class Model {
return signals;
}
+ /**
+ * @return a copy of all registered Signals
+ */
+ public ArrayList getSignalsCopy() {
+ ArrayList n = new ArrayList<>(signals.size());
+ n.addAll(signals);
+ return n;
+ }
+
+
/**
* registers a ROM to the model
* @param rom the ROM
@@ -419,6 +429,11 @@ public class Model {
public int compareTo(Signal o) {
return name.compareTo(o.name);
}
+
+ @Override
+ public String toString() {
+ return name;
+ }
}
}
diff --git a/src/main/java/de/neemann/digital/draw/elements/Circuit.java b/src/main/java/de/neemann/digital/draw/elements/Circuit.java
index db6fa67df..76013e2c4 100644
--- a/src/main/java/de/neemann/digital/draw/elements/Circuit.java
+++ b/src/main/java/de/neemann/digital/draw/elements/Circuit.java
@@ -23,6 +23,7 @@ import de.neemann.digital.lang.Lang;
import java.awt.*;
import java.io.*;
import java.util.*;
+import java.util.List;
/**
* @author hneemann
@@ -39,6 +40,7 @@ public class Circuit {
private ElementAttributes attributes;
private final ArrayList visualElements;
private ArrayList wires;
+ private List measurementOrdering;
private transient boolean dotsPresent = false;
private transient boolean modified = false;
@@ -430,4 +432,21 @@ public class Circuit {
return pinList.toArray(new ObservableValue[pinList.size()]);
}
+ /**
+ * Gets the ordering of values used to show measurements
+ *
+ * @return list of names
+ */
+ public List getMeasurementOrdering() {
+ return measurementOrdering;
+ }
+
+ /**
+ * Sets the ordering of values used to show measurements
+ *
+ * @param measurementOrdering
+ */
+ public void setMeasurementOrdering(List measurementOrdering) {
+ this.measurementOrdering = measurementOrdering;
+ }
}
diff --git a/src/main/java/de/neemann/digital/gui/Main.java b/src/main/java/de/neemann/digital/gui/Main.java
index 9a72d2d90..ee8d5da6c 100644
--- a/src/main/java/de/neemann/digital/gui/Main.java
+++ b/src/main/java/de/neemann/digital/gui/Main.java
@@ -13,9 +13,9 @@ import de.neemann.digital.draw.model.RealTimeClock;
import de.neemann.digital.draw.shapes.ShapeFactory;
import de.neemann.digital.gui.components.CircuitComponent;
import de.neemann.digital.gui.components.ElementOrderer;
+import de.neemann.digital.gui.components.OrderMerger;
import de.neemann.digital.gui.components.ProbeDialog;
import de.neemann.digital.gui.components.data.DataSetDialog;
-import de.neemann.digital.gui.components.data.MeasurementFilter;
import de.neemann.digital.gui.components.listing.ROMListingDialog;
import de.neemann.digital.gui.state.State;
import de.neemann.digital.gui.state.StateManager;
@@ -31,6 +31,8 @@ import java.awt.event.WindowEvent;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.prefs.Preferences;
@@ -45,7 +47,6 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
private static final Icon ICON_STEP = IconCreator.create("step.gif");
private static final Icon ICON_ELEMENT = IconCreator.create("element.gif");
private static final Icon ICON_SELECT = IconCreator.create("Select24.gif");
- // private static final Icon ICON_WIRE = IconCreator.create("wire.gif");
private static final Icon ICON_NEW = IconCreator.create("New24.gif");
private static final Icon ICON_OPEN = IconCreator.create("Open24.gif");
private static final Icon ICON_OPEN_WIN = IconCreator.create("OpenNew24.gif");
@@ -73,7 +74,6 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
private ScheduledThreadPoolExecutor timerExecuter = new ScheduledThreadPoolExecutor(1);
private State elementState;
- //private State wireState;
private State selectState;
private State runModelState;
private State runModelMicroState;
@@ -203,7 +203,6 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
JMenu edit = new JMenu(Lang.get("menu_edit"));
bar.add(edit);
- //ToolTipAction wireStateAction = wireState.createToolTipAction(Lang.get("menu_wire"), ICON_WIRE).setToolTip(Lang.get("menu_wire_tt"));
ToolTipAction elementStateAction = elementState.createToolTipAction(Lang.get("menu_element"), ICON_ELEMENT).setToolTip(Lang.get("menu_element_tt"));
ToolTipAction selectStateAction = selectState.createToolTipAction(Lang.get("menu_select"), ICON_SELECT).setToolTip(Lang.get("menu_select_tt"));
@@ -226,8 +225,7 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
ToolTipAction orderMeasurements = new ToolTipAction(Lang.get("menu_orderMeasurements")) {
@Override
public void actionPerformed(ActionEvent e) {
- ElementOrder o = new ElementOrder(circuitComponent.getCircuit(), new MeasurementFilter());
- new ElementOrderer<>(Main.this, Lang.get("menu_orderMeasurements"), o).setVisible(true);
+ orderMeasurements();
}
}.setToolTip(Lang.get("menu_orderMeasurements_tt"));
@@ -241,7 +239,6 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
edit.add(elementStateAction.createJMenuItem());
- //edit.add(wireStateAction.createJMenuItem());
edit.add(selectStateAction.createJMenuItem());
edit.add(orderInputs.createJMenuItem());
edit.add(orderOutputs.createJMenuItem());
@@ -316,7 +313,6 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
run.add(runModelMicroAction.createJMenuItem());
run.add(doStep.createJMenuItem());
run.add(runToBreak.createJMenuItem());
- //run.add(speedTest.createJMenuItem());
run.add(showProbes);
run.add(showGraph);
run.add(showListing);
@@ -329,7 +325,6 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
toolBar.add(save.createJButtonNoText());
toolBar.addSeparator();
toolBar.add(elementState.setIndicator(elementStateAction.createJButtonNoText()));
- //toolBar.add(wireState.setIndicator(wireStateAction.createJButtonNoText()));
toolBar.add(selectState.setIndicator(selectStateAction.createJButtonNoText()));
toolBar.add(circuitComponent.getDeleteAction().createJButtonNoText());
toolBar.addSeparator();
@@ -353,9 +348,24 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
setLocationRelativeTo(parent);
}
+ private void orderMeasurements() {
+ try {
+ Model m = new ModelDescription(circuitComponent.getCircuit(), library).createModel();
+ circuitComponent.getCircuit().clearState();
+ ArrayList names = new ArrayList<>();
+ for (Model.Signal s : m.getSignals())
+ names.add(s.getName());
+ new OrderMerger(circuitComponent.getCircuit().getMeasurementOrdering()).order(names);
+ ElementOrderer.ListOrder o = new ElementOrderer.ListOrder<>(names);
+ new ElementOrderer<>(Main.this, Lang.get("menu_orderMeasurements"), o).setVisible(true);
+ circuitComponent.getCircuit().setMeasurementOrdering(names);
+ } catch (Exception e1) {
+ showSwingError(Lang.get("msg_errorCreatingModel"), e1);
+ }
+ }
+
private void setupStates() {
elementState = stateManager.register(new ModeState(CircuitComponent.Mode.part));
- //wireState = stateManager.register(new ModeState(CircuitComponent.Mode.wire));
selectState = stateManager.register(new ModeState(CircuitComponent.Mode.select));
runModelState = stateManager.register(new State() {
@Override
@@ -425,11 +435,13 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
runToBreak.setEnabled(!runClock && model.isFastRunModel());
- if (showProbes.isSelected())
- new ProbeDialog(this, model, updateEvent).setVisible(true);
+ List ordering = circuitComponent.getCircuit().getMeasurementOrdering();
+ if (showProbes.isSelected()) {
+ new ProbeDialog(this, model, updateEvent, ordering).setVisible(true);
+ }
if (showGraph.isSelected())
- new DataSetDialog(this, model, updateEvent).setVisible(true);
+ new DataSetDialog(this, model, updateEvent, ordering).setVisible(true);
if (showListing.isSelected())
for (ROM rom : model.getRoms())
diff --git a/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java b/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java
index 9b021f6ba..f81e7769a 100644
--- a/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java
+++ b/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java
@@ -39,9 +39,9 @@ import java.util.HashSet;
* @author hneemann
*/
public class CircuitComponent extends JComponent {
- private static final Icon iconDelete = IconCreator.create("Delete24.gif");
+ private static final Icon ICON_DELETE = IconCreator.create("Delete24.gif");
+ private static final String DEL_ACTION = "myDelAction";
- private static final String delAction = "myDelAction";
private final ElementLibrary library;
private final ShapeFactory shapeFactory;
private final HashSet highLighted;
@@ -59,8 +59,8 @@ public class CircuitComponent extends JComponent {
setCircuit(aCircuit);
KeyStroke delKey = KeyStroke.getKeyStroke("DELETE");
- getInputMap().put(delKey, delAction);
- getActionMap().put(delAction, deleteAction);
+ getInputMap().put(delKey, DEL_ACTION);
+ getActionMap().put(DEL_ACTION, deleteAction);
setFocusable(true);
@@ -92,10 +92,6 @@ public class CircuitComponent extends JComponent {
listener = new PartMouseListener();
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
break;
- case wire:
- listener = new WireMouseListener();
- setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
- break;
case select:
listener = new SelectMouseListener();
setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
@@ -202,7 +198,7 @@ public class CircuitComponent extends JComponent {
setModeAndReset(Mode.part);
}
- public enum Mode {part, wire, running, select}
+ public enum Mode {part, running, select}
private abstract class Mouse extends MouseAdapter implements MouseMotionListener {
private Vector pos;
@@ -225,49 +221,6 @@ public class CircuitComponent extends JComponent {
}
}
- private class WireMouseListener extends Mouse {
-
- private Wire wire;
-
- @Override
- public void mouseClicked(MouseEvent e) {
- if (e.getButton() == MouseEvent.BUTTON1) {
- if (wire != null) {
- circuit.add(wire);
- Vector startPos = raster(getPosVector(e));
- if (circuit.isPinPos(startPos))
- wire = null;
- else
- wire = new Wire(startPos, startPos);
- } else {
- Vector startPos = raster(getPosVector(e));
- wire = new Wire(startPos, startPos);
- }
- repaint();
- } else {
- if (wire != null) {
- wire = null;
- repaint();
- } else
- editAttributes(e);
- }
- }
-
- @Override
- public void mouseMoved(MouseEvent e) {
- if (wire != null) {
- wire.setP2(raster(getPosVector(e)));
- repaint();
- }
- }
-
- @Override
- public void drawTo(Graphic gr) {
- if (wire != null)
- wire.drawTo(gr, false);
- }
- }
-
private class PartMouseListener extends Mouse {
private VisualElement partToInsert;
@@ -522,7 +475,7 @@ public class CircuitComponent extends JComponent {
private class DelAction extends ToolTipAction {
DelAction() {
- super(Lang.get("menu_delete"), iconDelete);
+ super(Lang.get("menu_delete"), ICON_DELETE);
setToolTip(Lang.get("menu_delete_tt"));
}
diff --git a/src/main/java/de/neemann/digital/gui/components/ElementOrderer.java b/src/main/java/de/neemann/digital/gui/components/ElementOrderer.java
index 15887ea7f..155c7a7ab 100644
--- a/src/main/java/de/neemann/digital/gui/components/ElementOrderer.java
+++ b/src/main/java/de/neemann/digital/gui/components/ElementOrderer.java
@@ -62,10 +62,35 @@ public class ElementOrderer extends JDialog {
}
- private static class ArrayOrderInterface implements OrderInterface {
+ public static class ListOrder implements OrderInterface {
+ private java.util.List list;
+
+ public ListOrder(java.util.List list) {
+ this.list = list;
+ }
+
+ @Override
+ public int size() {
+ return list.size();
+ }
+
+ @Override
+ public T get(int index) {
+ return list.get(index);
+ }
+
+ @Override
+ public void swap(int i, int j) {
+ T z = list.get(i);
+ list.set(i, list.get(j));
+ list.set(j, z);
+ }
+ }
+
+ private static class ArrayOrder implements OrderInterface {
private final T[] data;
- public ArrayOrderInterface(T[] data) {
+ public ArrayOrder(T[] data) {
this.data = data;
}
@@ -129,6 +154,6 @@ public class ElementOrderer extends JDialog {
}
public static void main(String[] args) {
- new ElementOrderer<>(null, "Test", new ArrayOrderInterface<>(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9})).setVisible(true);
+ new ElementOrderer<>(null, "Test", new ArrayOrder<>(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9})).setVisible(true);
}
}
diff --git a/src/main/java/de/neemann/digital/gui/components/OrderMerger.java b/src/main/java/de/neemann/digital/gui/components/OrderMerger.java
new file mode 100644
index 000000000..d8e97196b
--- /dev/null
+++ b/src/main/java/de/neemann/digital/gui/components/OrderMerger.java
@@ -0,0 +1,39 @@
+package de.neemann.digital.gui.components;
+
+import java.util.List;
+
+/**
+ * @author hneemann
+ */
+public class OrderMerger {
+ private final List oldOrdering;
+
+ public OrderMerger(List oldOrdering) {
+ this.oldOrdering = oldOrdering;
+ }
+
+ public > void order(L list) {
+ if (oldOrdering == null || oldOrdering.size() == 0)
+ return;
+
+ int n = 0;
+ for (O o : oldOrdering) {
+ int found = -1;
+ for (int i = n; i < list.size(); i++) {
+ if (equals(list.get(i), o)) {
+ found = i;
+ break;
+ }
+ }
+ if (found >= 0) {
+ N r = list.remove(found);
+ list.add(n, r);
+ n++;
+ }
+ }
+ }
+
+ public boolean equals(N a, O b) {
+ return a.equals(b);
+ }
+}
diff --git a/src/main/java/de/neemann/digital/gui/components/ProbeDialog.java b/src/main/java/de/neemann/digital/gui/components/ProbeDialog.java
index 8443c7f28..b55b0eecc 100644
--- a/src/main/java/de/neemann/digital/gui/components/ProbeDialog.java
+++ b/src/main/java/de/neemann/digital/gui/components/ProbeDialog.java
@@ -13,6 +13,7 @@ import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
+import java.util.List;
/**
* @author hneemann
@@ -22,12 +23,19 @@ public class ProbeDialog extends JDialog implements ModelStateObserver {
private final ModelEvent.Event type;
private final SignalTableModel tableModel;
- public ProbeDialog(Frame owner, Model model, ModelEvent.Event type) {
+ public ProbeDialog(Frame owner, Model model, ModelEvent.Event type, List ordering) {
super(owner, Lang.get("win_measures"), false);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
this.type = type;
- ArrayList signals = model.getSignals();
+ ArrayList signals = model.getSignalsCopy();
+ new OrderMerger(ordering) {
+ @Override
+ public boolean equals(Model.Signal a, String b) {
+ return a.getName().equals(b);
+ }
+ }.order(signals);
+
tableModel = new SignalTableModel(signals);
JTable list = new JTable(tableModel);
getContentPane().add(new JScrollPane(list), BorderLayout.CENTER);
diff --git a/src/main/java/de/neemann/digital/gui/components/data/DataSetDialog.java b/src/main/java/de/neemann/digital/gui/components/data/DataSetDialog.java
index b685cfaef..7a13e1760 100644
--- a/src/main/java/de/neemann/digital/gui/components/data/DataSetDialog.java
+++ b/src/main/java/de/neemann/digital/gui/components/data/DataSetDialog.java
@@ -3,6 +3,7 @@ package de.neemann.digital.gui.components.data;
import de.neemann.digital.core.Model;
import de.neemann.digital.core.ModelEvent;
import de.neemann.digital.core.ModelStateObserver;
+import de.neemann.digital.gui.components.OrderMerger;
import de.neemann.digital.lang.Lang;
import javax.swing.*;
@@ -10,6 +11,7 @@ import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
+import java.util.List;
/**
* The Dialog which shows the data to plot.
@@ -27,17 +29,25 @@ public class DataSetDialog extends JDialog implements ModelStateObserver {
/**
* Creates a new instance
*
- * @param owner the parent frame
- * @param model the model used to collect the data
- * @param type the event type which triggers a new DataSample
+ * @param owner the parent frame
+ * @param model the model used to collect the data
+ * @param type the event type which triggers a new DataSample
+ * @param ordering
*/
- public DataSetDialog(Frame owner, Model model, ModelEvent.Event type) {
+ public DataSetDialog(Frame owner, Model model, ModelEvent.Event type, List ordering) {
super(owner, Lang.get("win_measures"), false);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setAlwaysOnTop(true);
this.type = type;
- signals = model.getSignals();
+ signals = model.getSignalsCopy();
+ new OrderMerger(ordering) {
+ @Override
+ public boolean equals(Model.Signal a, String b) {
+ return a.getName().equals(b);
+ }
+ }.order(signals);
+
dataSet = new DataSet(signals);
dsc = new DataSetComponent(dataSet);
diff --git a/src/main/java/de/neemann/digital/gui/components/data/MeasurementFilter.java b/src/main/java/de/neemann/digital/gui/components/data/MeasurementFilter.java
deleted file mode 100644
index 0b2ca8d68..000000000
--- a/src/main/java/de/neemann/digital/gui/components/data/MeasurementFilter.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package de.neemann.digital.gui.components.data;
-
-import de.neemann.digital.draw.elements.ElementOrder;
-import de.neemann.digital.draw.elements.VisualElement;
-
-/**
- * @author hneemann
- */
-public class MeasurementFilter implements ElementOrder.ElementMatcher {
- @Override
- public boolean matches(VisualElement element) {
- String name = element.getElementName();
- return name.equals("In") || name.equals("Out") || name.equals("LED") || name.equals("Clock") || name.equals("Probe");
- }
-}
diff --git a/src/test/java/de/neemann/digital/gui/components/OrderMergerTest.java b/src/test/java/de/neemann/digital/gui/components/OrderMergerTest.java
new file mode 100644
index 000000000..df967db91
--- /dev/null
+++ b/src/test/java/de/neemann/digital/gui/components/OrderMergerTest.java
@@ -0,0 +1,31 @@
+package de.neemann.digital.gui.components;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+
+/**
+ * @author hneemann
+ */
+public class OrderMergerTest extends TestCase {
+ public void testOrder() throws Exception {
+ ArrayList oldList = new ArrayList<>();
+ oldList.add("b");
+ oldList.add("d");
+
+ ArrayList newList = new ArrayList<>();
+ newList.add("a");
+ newList.add("b");
+ newList.add("c");
+ newList.add("d");
+
+ new OrderMerger(oldList).order(newList);
+
+ assertEquals(4, newList.size());
+ assertEquals("b", newList.get(0));
+ assertEquals("d", newList.get(1));
+ assertEquals("a", newList.get(2));
+ assertEquals("c", newList.get(3));
+ }
+
+}
\ No newline at end of file