allow to show the graph data as a table

This commit is contained in:
hneemann 2017-07-03 20:56:08 +02:00
parent 7ca7d7197b
commit b51abacc8c
8 changed files with 200 additions and 134 deletions

View File

@ -29,7 +29,7 @@ import de.neemann.digital.gui.components.modification.Modifications;
import de.neemann.digital.gui.components.modification.ModifyAttribute;
import de.neemann.digital.gui.components.modification.ModifyMeasurementOrdering;
import de.neemann.digital.gui.components.table.TableDialog;
import de.neemann.digital.gui.components.testing.TestResultDialog;
import de.neemann.digital.gui.components.testing.ValueTableDialog;
import de.neemann.digital.gui.components.tree.LibraryTreeModel;
import de.neemann.digital.gui.components.tree.SelectTree;
import de.neemann.digital.gui.remote.DigitalHandler;
@ -828,17 +828,17 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
*/
public void startTests() {
try {
ArrayList<TestResultDialog.TestSet> tsl = new ArrayList<>();
ArrayList<ValueTableDialog.TestSet> tsl = new ArrayList<>();
for (VisualElement el : circuitComponent.getCircuit().getElements())
if (el.equalsDescription(TestCaseElement.TESTCASEDESCRIPTION))
tsl.add(new TestResultDialog.TestSet(
tsl.add(new ValueTableDialog.TestSet(
el.getElementAttributes().get(TestCaseElement.TESTDATA),
el.getElementAttributes().getCleanLabel()));
if (tsl.isEmpty())
throw new TestingDataException(Lang.get("err_noTestData"));
windowPosManager.register("testResult", new TestResultDialog(Main.this, tsl, circuitComponent.getCircuit(), library)).setVisible(true);
windowPosManager.register("testResult", new ValueTableDialog(Main.this).addTestResult(tsl, circuitComponent.getCircuit(), library)).setVisible(true);
ensureModelIsStopped();
} catch (NodeException | ElementNotFoundException | PinException | TestingDataException | RuntimeException e1) {

View File

@ -7,6 +7,7 @@ import de.neemann.digital.core.Signal;
import de.neemann.digital.data.ValueTable;
import de.neemann.digital.gui.SaveAsHelper;
import de.neemann.digital.gui.components.OrderMerger;
import de.neemann.digital.gui.components.testing.ValueTableDialog;
import de.neemann.digital.gui.sync.NoSync;
import de.neemann.digital.gui.sync.Sync;
import de.neemann.digital.lang.Lang;
@ -33,6 +34,7 @@ public class GraphDialog extends JDialog implements ModelStateObserver {
private final GraphComponent dsc;
private final JScrollPane scrollPane;
private final Sync modelSync;
private final ToolTipAction showTable;
private ValueTableObserver valueTableObserver;
private static final Icon ICON_EXPAND = IconCreator.create("View-zoom-fit.png");
@ -50,7 +52,7 @@ public class GraphDialog extends JDialog implements ModelStateObserver {
* @param modelSync the lock to access the model
* @return the created instance
*/
public static GraphDialog createLiveDialog(Frame owner, Model model, boolean microStep, List<String> ordering, Sync modelSync) {
public static GraphDialog createLiveDialog(JFrame owner, Model model, boolean microStep, List<String> ordering, Sync modelSync) {
String title;
if (microStep)
title = Lang.get("win_measures_microstep");
@ -78,7 +80,7 @@ public class GraphDialog extends JDialog implements ModelStateObserver {
* @param title the frame title
* @param logData the data to visualize
*/
public GraphDialog(Frame owner, String title, ValueTable logData) {
public GraphDialog(JFrame owner, String title, ValueTable logData) {
this(owner, title, null, logData, null, NoSync.INST);
}
@ -91,7 +93,7 @@ public class GraphDialog extends JDialog implements ModelStateObserver {
* @param logData the data to visualize
* @param modelSync used to access the running model
*/
private GraphDialog(Frame owner, String title, Model model, ValueTable logData, ValueTableObserver valueTableObserver, Sync modelSync) {
private GraphDialog(JFrame owner, String title, Model model, ValueTable logData, ValueTableObserver valueTableObserver, Sync modelSync) {
super(owner, title, false);
this.valueTableObserver = valueTableObserver;
this.modelSync = modelSync;
@ -125,6 +127,13 @@ public class GraphDialog extends JDialog implements ModelStateObserver {
}
}.setAccelerator("control MINUS");
showTable = new ToolTipAction(Lang.get("menu_showDataAsTable")) {
@Override
public void actionPerformed(ActionEvent e) {
new ValueTableDialog(owner).addValueTable("Data", logData).disableGraph().setVisible(true);
}
}.setToolTip(Lang.get("menu_showDataAsTable_tt"));
toolBar.add(zoomIn.createJButtonNoText());
toolBar.add(zoomOut.createJButtonNoText());
toolBar.add(maximize.createJButtonNoText());
@ -165,6 +174,8 @@ public class GraphDialog extends JDialog implements ModelStateObserver {
view.add(maximize.createJMenuItem());
view.add(zoomOut.createJMenuItem());
view.add(zoomIn.createJMenuItem());
view.addSeparator();
view.add(showTable.createJMenuItem());
setJMenuBar(bar);
pack();
@ -185,4 +196,14 @@ public class GraphDialog extends JDialog implements ModelStateObserver {
});
});
}
/**
* Disable the show as table function
*
* @return this for chained calls
*/
public GraphDialog disableTable() {
showTable.setActive(false);
return this;
}
}

View File

@ -10,15 +10,14 @@ import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.draw.library.ElementLibrary;
import de.neemann.digital.draw.library.ElementNotFoundException;
import de.neemann.digital.draw.model.ModelCreator;
import de.neemann.digital.gui.SaveAsHelper;
import de.neemann.digital.gui.components.data.GraphDialog;
import de.neemann.digital.lang.Lang;
import de.neemann.digital.testing.*;
import de.neemann.gui.ErrorMessage;
import de.neemann.gui.IconCreator;
import de.neemann.gui.LineBreaker;
import de.neemann.gui.ToolTipAction;
import de.neemann.gui.*;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.DefaultTableCellRenderer;
import java.awt.*;
import java.awt.event.ActionEvent;
@ -30,7 +29,7 @@ import java.util.Collections;
*
* @author hneemann
*/
public class TestResultDialog extends JDialog {
public class ValueTableDialog extends JDialog {
private static final Color FAILED_COLOR = new Color(255, 200, 200);
private static final Color PASSED_COLOR = new Color(200, 255, 200);
private static final Icon ICON_FAILED = IconCreator.create("testFailed.png");
@ -39,28 +38,73 @@ public class TestResultDialog extends JDialog {
private final ArrayList<ValueTable> resultTableData;
private final JTabbedPane tp;
private final JFrame owner;
private final ToolTipAction asGraph;
/**
* Creates a new result dialog.
*
* @param owner the parent frame
* @param owner the parent frame
*/
public ValueTableDialog(JFrame owner) {
super(owner, Lang.get("msg_testResult"), false);
this.owner = owner;
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setAlwaysOnTop(true);
resultTableData = new ArrayList<>();
tp = new JTabbedPane();
JMenuBar bar = new JMenuBar();
JMenu file = new JMenu(Lang.get("menu_file"));
bar.add(file);
file.add(new ToolTipAction(Lang.get("menu_saveData")) {
@Override
public void actionPerformed(ActionEvent e) {
int tab = tp.getSelectedIndex();
if (tab < 0) tab = 0;
JFileChooser fileChooser = new MyFileChooser();
fileChooser.setFileFilter(new FileNameExtensionFilter("Comma Separated Values", "csv"));
new SaveAsHelper(ValueTableDialog.this, fileChooser, "csv")
.checkOverwrite(resultTableData.get(tab)::saveCSV);
}
}.setToolTip(Lang.get("menu_saveData_tt")).createJMenuItem());
JMenu view = new JMenu(Lang.get("menu_view"));
asGraph = new ToolTipAction(Lang.get("menu_showDataAsGraph"), ICON_GRAPH) {
@Override
public void actionPerformed(ActionEvent actionEvent) {
int tab = tp.getSelectedIndex();
if (tab < 0) tab = 0;
new GraphDialog(owner, Lang.get("win_testdata_N", tp.getTitleAt(tab)), resultTableData.get(tab)).disableTable().setVisible(true);
}
}.setToolTip(Lang.get("menu_showDataAsGraph_tt"));
view.add(asGraph.createJMenuItem());
bar.add(view);
setJMenuBar(bar);
JToolBar toolBar = new JToolBar();
toolBar.add(asGraph.createJButtonNoText());
getContentPane().add(toolBar, BorderLayout.NORTH);
getContentPane().add(tp);
}
/**
* Add test results
*
* @param tsl list of test sets
* @param circuit the circuit
* @param library the library to use
* @return this for chained calls
* @throws NodeException NodeException
* @throws TestingDataException DataException
* @throws PinException PinException
* @throws ElementNotFoundException ElementNotFoundException
*/
public TestResultDialog(JFrame owner, ArrayList<TestSet> tsl, Circuit circuit, ElementLibrary library) throws NodeException, TestingDataException, PinException, ElementNotFoundException {
super(owner, Lang.get("msg_testResult"), false);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
public ValueTableDialog addTestResult(ArrayList<TestSet> tsl, Circuit circuit, ElementLibrary library) throws PinException, NodeException, ElementNotFoundException, TestingDataException {
Collections.sort(tsl);
resultTableData = new ArrayList<>();
JTabbedPane tp = new JTabbedPane();
int i = 0;
int errorTabIndex = -1;
for (TestSet ts : tsl) {
@ -71,14 +115,6 @@ public class TestResultDialog extends JDialog {
if (testExecutor.getException() != null)
SwingUtilities.invokeLater(new ErrorMessage(Lang.get("msg_errorWhileExecutingTests_N0", ts.name)).addCause(testExecutor.getException()).setComponent(this));
JTable table = new JTable(new ValueTableModel(testExecutor.getResult()));
table.setDefaultRenderer(Value.class, new ValueRenderer());
table.setDefaultRenderer(Integer.class, new NumberRenderer());
final Font font = table.getFont();
table.getColumnModel().getColumn(0).setMaxWidth(font.getSize() * 4);
table.setRowHeight(font.getSize() * 6 / 5);
resultTableData.add(testExecutor.getResult());
String tabName;
Icon tabIcon;
if (testExecutor.allPassed()) {
@ -92,36 +128,54 @@ public class TestResultDialog extends JDialog {
if (testExecutor.toManyResults())
tabName += " " + Lang.get("msg_test_missingLines");
tp.addTab(tabName, tabIcon, new JScrollPane(table));
tp.addTab(tabName, tabIcon, new JScrollPane(createTable(testExecutor.getResult())));
if (testExecutor.toManyResults())
tp.setToolTipTextAt(i, new LineBreaker().toHTML().breakLines(Lang.get("msg_test_missingLines_tt")));
resultTableData.add(testExecutor.getResult());
i++;
}
if (errorTabIndex >= 0)
tp.setSelectedIndex(errorTabIndex);
JMenuBar bar = new JMenuBar();
JMenu view = new JMenu(Lang.get("menu_view"));
ToolTipAction asGraph = new ToolTipAction(Lang.get("menu_showDataAsGraph"), ICON_GRAPH) {
@Override
public void actionPerformed(ActionEvent actionEvent) {
int tab = tp.getSelectedIndex();
if (tab < 0) tab = 0;
new GraphDialog(owner, Lang.get("win_testdata_N", tp.getTitleAt(tab)), resultTableData.get(tab)).setVisible(true);
}
}.setToolTip(Lang.get("menu_showDataAsGraph_tt"));
view.add(asGraph.createJMenuItem());
bar.add(view);
setJMenuBar(bar);
JToolBar toolBar = new JToolBar();
toolBar.add(asGraph.createJButtonNoText());
getContentPane().add(toolBar, BorderLayout.NORTH);
getContentPane().add(tp);
pack();
setLocationRelativeTo(owner);
return this;
}
/**
* Add a table to this dialog
*
* @param name the name of the tab
* @param valueTable the values
* @return this for chained calls
*/
public ValueTableDialog addValueTable(String name, ValueTable valueTable) {
tp.addTab(name, new JScrollPane(createTable(valueTable)));
resultTableData.add(valueTable);
pack();
setLocationRelativeTo(owner);
return this;
}
private JTable createTable(ValueTable valueTable) {
JTable table = new JTable(new ValueTableModel(valueTable));
table.setDefaultRenderer(Value.class, new ValueRenderer());
table.setDefaultRenderer(Integer.class, new NumberRenderer());
final Font font = table.getFont();
table.getColumnModel().getColumn(0).setMaxWidth(font.getSize() * 4);
table.setRowHeight(font.getSize() * 6 / 5);
return table;
}
/**
* Disable the show as graph function
*
* @return this for chained calls
*/
public ValueTableDialog disableGraph() {
asGraph.setActive(false);
return this;
}
/**

View File

@ -865,6 +865,8 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
<string name="menu_redo_tt">Letzte rückgängig gemachte Aktion wieder herstellen.</string>
<string name="menu_showDataAsGraph">Zeige Graph</string>
<string name="menu_showDataAsGraph_tt">Zeigt die Daten als Graph an.</string>
<string name="menu_showDataAsTable">Zeige Tabelle</string>
<string name="menu_showDataAsTable_tt">Zeigt die Daten als Tabelle an.</string>
<string name="message">Digital

View File

@ -853,6 +853,8 @@ The names of the variables may not be unique.</string>
<string name="menu_redo_tt">Apply last reverted modification again.</string>
<string name="menu_showDataAsGraph">Show graph</string>
<string name="menu_showDataAsGraph_tt">Show the data as a Graph.</string>
<string name="menu_showDataAsTable">Show table</string>
<string name="menu_showDataAsTable_tt">Shows values as a table.</string>
<string name="message">Digital

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Digital by H.Neemann -->
<!-- created: Mon Jul 03 15:53:05 CEST 2017 -->
<!-- created: Mon Jul 03 20:00:31 CEST 2017 -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
@ -11,15 +11,15 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="17.942812mm"
height="15.855mm"
viewBox="251 63 119.61875 105.7"
width="14.19281mm"
height="14.19281mm"
viewBox="252 63 94.618731 94.618736"
version="1.1"
id="svg134"
id="svg116"
sodipodi:docname="measurement-graph.svg"
inkscape:version="0.92.1 r15371">
<metadata
id="metadata140">
id="metadata122">
<rdf:RDF>
<cc:Work
rdf:about="">
@ -31,7 +31,7 @@
</rdf:RDF>
</metadata>
<defs
id="defs138" />
id="defs120" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
@ -43,92 +43,79 @@
inkscape:pageshadow="2"
inkscape:window-width="1680"
inkscape:window-height="1002"
id="namedview136"
id="namedview118"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="8"
inkscape:cx="45.760076"
inkscape:cy="28.200851"
inkscape:zoom="7.6207857"
inkscape:cx="36.816645"
inkscape:cy="14.982514"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:current-layer="svg134"
inkscape:snap-grids="true"
inkscape:current-layer="svg116"
inkscape:snap-page="true" />
<rect
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79929172;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="rect4682"
width="119.61875"
height="105.7"
x="251"
y="63"
ry="0.0021948952" />
<path
style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:square"
inkscape:connector-curvature="0"
id="path2"
d="m 269.21875,68.35 h 25 v 25 h 25 25 v -25 h 25" />
<path
style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:square"
inkscape:connector-curvature="0"
id="path4"
d="m 269.21875,103.35 h 25 v 25 h 25 v -25 h 25 v 25 h 25" />
<path
style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:square"
inkscape:connector-curvature="0"
id="path6"
d="m 269.21875,138.35 h 25 v 25 h 25 25 25" />
<path
style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:square;stroke-dasharray:4, 4"
inkscape:connector-curvature="0"
id="path24"
d="m 269.21875,98.35 h 100" />
<path
style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:square;stroke-dasharray:4, 4"
inkscape:connector-curvature="0"
id="path26"
d="m 269.21875,133.35 h 100" />
<path
style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:square;stroke-dasharray:4, 4"
inkscape:connector-curvature="0"
id="path28"
d="m 369.21875,168.35 v -105 h -100 v 105 h 100" />
<path
style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:square;stroke-dasharray:4, 4"
inkscape:connector-curvature="0"
id="path30"
d="m 294.21875,63.35 v 105" />
<path
style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:square;stroke-dasharray:4, 4"
inkscape:connector-curvature="0"
id="path32"
d="m 319.21875,63.35 v 105" />
<path
style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:square;stroke-dasharray:4, 4"
inkscape:connector-curvature="0"
id="path34"
d="m 344.21875,63.35 v 105" />
<g
style="stroke-linecap:square"
id="g130"
transform="translate(-2.78125,-1.65)">
<text
id="text124"
style="font-size:24px;text-anchor:end;fill:#000000"
y="91"
x="270">A</text>
<text
id="text126"
style="font-size:24px;text-anchor:end;fill:#000000"
y="126"
x="270">B</text>
<text
id="text128"
style="font-size:24px;text-anchor:end;fill:#000000"
y="161"
x="270">C</text>
id="g4679"
transform="translate(0,-0.32345319)">
<rect
ry="0.0023457941"
y="71.053566"
x="252"
height="79.158508"
width="94.618736"
id="rect4655"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.89391804;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
<g
transform="translate(0,-0.12674537)"
id="g4666">
<path
style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:square"
inkscape:connector-curvature="0"
id="path10"
d="m 270.21875,80.759571 h 25 v 24.999989 h 25 V 80.759571 h 25" />
<path
style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:square"
inkscape:connector-curvature="0"
id="path12"
d="m 270.21875,115.75956 h 25 v 25 h 25 25" />
<path
style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:square;stroke-dasharray:4, 4"
inkscape:connector-curvature="0"
id="path22"
d="m 270.21875,110.75956 h 75" />
<path
style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:square;stroke-dasharray:4, 4"
inkscape:connector-curvature="0"
id="path24"
d="M 345.21875,145.75956 V 75.759571 h -75 v 69.999989 h 75" />
<path
style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:square;stroke-dasharray:4, 4"
inkscape:connector-curvature="0"
id="path26"
d="M 295.21875,75.759571 V 145.75956" />
<path
style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:square;stroke-dasharray:4, 4"
inkscape:connector-curvature="0"
id="path28"
d="M 320.21875,75.759571 V 145.75956" />
<g
style="stroke-linecap:square"
id="g112"
transform="translate(-1.78125,10.759571)">
<text
id="text108"
style="font-size:24px;text-anchor:end;fill:#000000"
y="91"
x="270">A</text>
<text
id="text110"
style="font-size:24px;text-anchor:end;fill:#000000"
y="126"
x="270">B</text>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB