mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-15 15:58:41 -04:00
improved the AllSolutionsDialog
This commit is contained in:
parent
e5266242d9
commit
51874037fb
@ -79,17 +79,13 @@ public final class GraphicsFormatter {
|
|||||||
} else if (text instanceof Sentence) {
|
} else if (text instanceof Sentence) {
|
||||||
Sentence s = (Sentence) text;
|
Sentence s = (Sentence) text;
|
||||||
SentenceFragment sf = new SentenceFragment();
|
SentenceFragment sf = new SentenceFragment();
|
||||||
int x = 0;
|
|
||||||
for (Text t : s)
|
for (Text t : s)
|
||||||
if (t instanceof Blank)
|
if (t instanceof Blank)
|
||||||
x += font.getSize() / 2;
|
sf.pad(font.getSize() / 2);
|
||||||
else {
|
else {
|
||||||
final Fragment f = createFragment(sizer, font, t);
|
final Fragment f = createFragment(sizer, font, t);
|
||||||
f.x = x;
|
|
||||||
x += f.dx;
|
|
||||||
sf.add(f);
|
sf.add(f);
|
||||||
}
|
}
|
||||||
sf.dx = x;
|
|
||||||
return sf.setUp();
|
return sf.setUp();
|
||||||
} else if (text instanceof Index) {
|
} else if (text instanceof Index) {
|
||||||
Index i = (Index) text;
|
Index i = (Index) text;
|
||||||
@ -154,27 +150,41 @@ public final class GraphicsFormatter {
|
|||||||
NamedExpression ne = (NamedExpression) expression;
|
NamedExpression ne = (NamedExpression) expression;
|
||||||
SentenceFragment f = new SentenceFragment();
|
SentenceFragment f = new SentenceFragment();
|
||||||
f.add(createFragment(sizer, font, ne.getName()));
|
f.add(createFragment(sizer, font, ne.getName()));
|
||||||
|
f.pad(font.getSize()/2);
|
||||||
f.add(new TextFragment(sizer, font, "="));
|
f.add(new TextFragment(sizer, font, "="));
|
||||||
|
f.pad(font.getSize()/2);
|
||||||
f.add(createFragment(sizer, font, ne.getExpression()));
|
f.add(createFragment(sizer, font, ne.getExpression()));
|
||||||
return f;
|
return f.setUp();
|
||||||
} else
|
} else
|
||||||
throw new FormatterException("unknown expression " + expression.getClass().getSimpleName());
|
throw new FormatterException("unknown expression " + expression.getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Fragment createOperationFragment(FontSizer sizer, Font font, Operation op, String opString) throws FormatterException {
|
private static Fragment createOperationFragment(FontSizer sizer, Font font, Operation op, String opString) throws FormatterException {
|
||||||
|
int pad = font.getSize() / 2;
|
||||||
SentenceFragment f = new SentenceFragment();
|
SentenceFragment f = new SentenceFragment();
|
||||||
for (Expression e : op.getExpressions()) {
|
for (Expression e : op.getExpressions()) {
|
||||||
if (f.size() > 0)
|
if (f.size() > 0) {
|
||||||
|
f.pad(pad);
|
||||||
|
if (!opString.isEmpty()) {
|
||||||
f.add(new TextFragment(sizer, font, opString));
|
f.add(new TextFragment(sizer, font, opString));
|
||||||
|
f.pad(pad);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (e instanceof Operation) {
|
||||||
|
f.add(new TextFragment(sizer,font, "("));
|
||||||
|
f.add(createFragment(sizer, font, e));
|
||||||
|
f.add(new TextFragment(sizer,font, ")"));
|
||||||
|
} else {
|
||||||
f.add(createFragment(sizer, font, e));
|
f.add(createFragment(sizer, font, e));
|
||||||
}
|
}
|
||||||
return f;
|
}
|
||||||
|
return f.setUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception which indicates a formatter exception
|
* Exception which indicates a formatter exception
|
||||||
*/
|
*/
|
||||||
private static final class FormatterException extends Exception {
|
public static final class FormatterException extends Exception {
|
||||||
FormatterException(String message) {
|
FormatterException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
@ -262,7 +272,7 @@ public final class GraphicsFormatter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static class SentenceFragment extends Fragment {
|
private static class SentenceFragment extends Fragment {
|
||||||
|
|
||||||
private ArrayList<Fragment> fragments;
|
private ArrayList<Fragment> fragments;
|
||||||
|
|
||||||
@ -272,6 +282,12 @@ public final class GraphicsFormatter {
|
|||||||
|
|
||||||
private void add(Fragment fragment) {
|
private void add(Fragment fragment) {
|
||||||
fragments.add(fragment);
|
fragments.add(fragment);
|
||||||
|
fragment.x = dx;
|
||||||
|
dx += fragment.dx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pad(int p) {
|
||||||
|
dx += p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -83,7 +83,7 @@ public class TransitionTableCreator {
|
|||||||
// create state variables
|
// create state variables
|
||||||
ArrayList<Variable> vars = new ArrayList<>();
|
ArrayList<Variable> vars = new ArrayList<>();
|
||||||
for (int i = stateBits - 1; i >= 0; i--) {
|
for (int i = stateBits - 1; i >= 0; i--) {
|
||||||
final Variable var = new Variable(STATE_VAR+"^" + i + "_n");
|
final Variable var = new Variable(STATE_VAR+"_" + i + "^n");
|
||||||
vars.add(var);
|
vars.add(var);
|
||||||
boolean initVal = (initState & (1 << i)) != 0;
|
boolean initVal = (initState & (1 << i)) != 0;
|
||||||
modelAnalyserInfo.setSequentialInitValue(var.getIdentifier(), initVal ? 1 : 0);
|
modelAnalyserInfo.setSequentialInitValue(var.getIdentifier(), initVal ? 1 : 0);
|
||||||
@ -93,7 +93,7 @@ public class TransitionTableCreator {
|
|||||||
|
|
||||||
// create the next state result variables
|
// create the next state result variables
|
||||||
for (int i = stateBits - 1; i >= 0; i--)
|
for (int i = stateBits - 1; i >= 0; i--)
|
||||||
truthTable.addResult(STATE_VAR+"^" + i + "_n+1");
|
truthTable.addResult(STATE_VAR+"_" + i + "^n+1");
|
||||||
|
|
||||||
// add the output variables
|
// add the output variables
|
||||||
TreeSet<String> results = new TreeSet<>();
|
TreeSet<String> results = new TreeSet<>();
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package de.neemann.digital.gui.components.table;
|
package de.neemann.digital.gui.components.table;
|
||||||
|
|
||||||
|
import de.neemann.digital.analyse.expression.Expression;
|
||||||
import de.neemann.digital.lang.Lang;
|
import de.neemann.digital.lang.Lang;
|
||||||
import de.neemann.gui.Screen;
|
import de.neemann.gui.Screen;
|
||||||
|
|
||||||
@ -12,13 +13,15 @@ import javax.swing.*;
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.WindowAdapter;
|
import java.awt.event.WindowAdapter;
|
||||||
import java.awt.event.WindowEvent;
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import static de.neemann.digital.draw.graphics.text.formatter.GraphicsFormatter.createFragment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple Dialog to show all possible functions of a truth table.
|
* Simple Dialog to show all possible functions of a truth table.
|
||||||
*/
|
*/
|
||||||
public class AllSolutionsDialog extends JDialog {
|
public class AllSolutionsDialog extends JDialog {
|
||||||
private final JTextPane textPane;
|
private final ExpressionComponent expressionComponent;
|
||||||
private final JScrollPane scroll;
|
|
||||||
private boolean userHasClosed = false;
|
private boolean userHasClosed = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,15 +34,11 @@ public class AllSolutionsDialog extends JDialog {
|
|||||||
super(owner, Lang.get("win_allSolutions"), false);
|
super(owner, Lang.get("win_allSolutions"), false);
|
||||||
setDefaultCloseOperation(HIDE_ON_CLOSE);
|
setDefaultCloseOperation(HIDE_ON_CLOSE);
|
||||||
|
|
||||||
textPane = new JTextPane();
|
expressionComponent = new ExpressionComponent();
|
||||||
textPane.setContentType("text/html");
|
expressionComponent.setPreferredSize(Screen.getInstance().scale(new Dimension(600, 300)));
|
||||||
textPane.setFont(font);
|
expressionComponent.setFont(font);
|
||||||
textPane.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, true);
|
|
||||||
textPane.setEditable(false);
|
|
||||||
textPane.setPreferredSize(Screen.getInstance().scale(new Dimension(600, 300)));
|
|
||||||
|
|
||||||
scroll = new JScrollPane(textPane);
|
getContentPane().add(new JScrollPane(expressionComponent));
|
||||||
getContentPane().add(scroll);
|
|
||||||
|
|
||||||
addWindowListener(new WindowAdapter() {
|
addWindowListener(new WindowAdapter() {
|
||||||
@Override
|
@Override
|
||||||
@ -52,18 +51,6 @@ public class AllSolutionsDialog extends JDialog {
|
|||||||
setLocation(0, 0);
|
setLocation(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the given text to the frame.
|
|
||||||
*
|
|
||||||
* @param text the text
|
|
||||||
* @return this for call chaining
|
|
||||||
*/
|
|
||||||
public AllSolutionsDialog setText(String text) {
|
|
||||||
textPane.setText(text);
|
|
||||||
SwingUtilities.invokeLater(() -> scroll.getViewport().setViewPosition(new Point(0, 0)));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is called from table dialog if this dialog is needed.
|
* Is called from table dialog if this dialog is needed.
|
||||||
*
|
*
|
||||||
@ -73,4 +60,15 @@ public class AllSolutionsDialog extends JDialog {
|
|||||||
if (!userHasClosed)
|
if (!userHasClosed)
|
||||||
setVisible(needed);
|
setVisible(needed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the expressions
|
||||||
|
*
|
||||||
|
* @param expressions the expressions to show
|
||||||
|
*/
|
||||||
|
public void setExpressions(ArrayList<Expression> expressions) {
|
||||||
|
expressionComponent.setExpressions(expressions);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Helmut Neemann.
|
||||||
|
* Use of this source code is governed by the GPL v3 license
|
||||||
|
* that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
package de.neemann.digital.gui.components.table;
|
||||||
|
|
||||||
|
import de.neemann.digital.analyse.expression.Expression;
|
||||||
|
import de.neemann.digital.draw.graphics.text.formatter.GraphicsFormatter;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import static de.neemann.digital.draw.graphics.text.formatter.GraphicsFormatter.createFragment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component to show an expression
|
||||||
|
*/
|
||||||
|
public class ExpressionComponent extends JComponent {
|
||||||
|
private ArrayList<Expression> expressions;
|
||||||
|
private Dimension lastRectSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the expressions to visualize
|
||||||
|
*
|
||||||
|
* @param expressions expressions
|
||||||
|
*/
|
||||||
|
public void setExpressions(ArrayList<Expression> expressions) {
|
||||||
|
this.expressions = expressions;
|
||||||
|
invalidate();
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics graphics) {
|
||||||
|
graphics.setColor(Color.WHITE);
|
||||||
|
graphics.fillRect(0, 0, getWidth(), getHeight());
|
||||||
|
graphics.setColor(Color.BLACK);
|
||||||
|
|
||||||
|
if (expressions == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
final Graphics2D gr = (Graphics2D) graphics;
|
||||||
|
gr.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||||
|
gr.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||||
|
int lineSpacing = getFont().getSize() / 2;
|
||||||
|
int y = 0;
|
||||||
|
int dx = 0;
|
||||||
|
for (Expression e : expressions) {
|
||||||
|
try {
|
||||||
|
GraphicsFormatter.Fragment fr = createFragment(gr, e);
|
||||||
|
y += fr.getHeight();
|
||||||
|
fr.draw(gr, 5, y);
|
||||||
|
y += lineSpacing;
|
||||||
|
|
||||||
|
if (dx < fr.getWidth())
|
||||||
|
dx = fr.getWidth();
|
||||||
|
|
||||||
|
} catch (GraphicsFormatter.FormatterException ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Dimension p = new Dimension(dx, y);
|
||||||
|
if (!p.equals(lastRectSet)) {
|
||||||
|
lastRectSet = p;
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
setPreferredSize(p);
|
||||||
|
invalidate();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@ import de.neemann.digital.analyse.TruthTable;
|
|||||||
import de.neemann.digital.analyse.TruthTableTableModel;
|
import de.neemann.digital.analyse.TruthTableTableModel;
|
||||||
import de.neemann.digital.analyse.expression.Expression;
|
import de.neemann.digital.analyse.expression.Expression;
|
||||||
import de.neemann.digital.analyse.expression.ExpressionException;
|
import de.neemann.digital.analyse.expression.ExpressionException;
|
||||||
|
import de.neemann.digital.analyse.expression.NamedExpression;
|
||||||
import de.neemann.digital.analyse.expression.Variable;
|
import de.neemann.digital.analyse.expression.Variable;
|
||||||
import de.neemann.digital.analyse.expression.format.FormatToExpression;
|
import de.neemann.digital.analyse.expression.format.FormatToExpression;
|
||||||
import de.neemann.digital.analyse.expression.format.FormatToTableLatex;
|
import de.neemann.digital.analyse.expression.format.FormatToTableLatex;
|
||||||
@ -606,7 +607,7 @@ public class TableDialog extends JDialog {
|
|||||||
private void calculateExpressions() {
|
private void calculateExpressions() {
|
||||||
try {
|
try {
|
||||||
LOGGER.info("start optimization");
|
LOGGER.info("start optimization");
|
||||||
ExpressionListener expressionListener = new HTMLExpressionListener();
|
ExpressionListener expressionListener = new OutputExpressionListener();
|
||||||
|
|
||||||
if (createJK.isSelected())
|
if (createJK.isSelected())
|
||||||
expressionListener = new ExpressionListenerJK(expressionListener);
|
expressionListener = new ExpressionListenerJK(expressionListener);
|
||||||
@ -688,7 +689,7 @@ public class TableDialog extends JDialog {
|
|||||||
public void actionPerformed(ActionEvent actionEvent) {
|
public void actionPerformed(ActionEvent actionEvent) {
|
||||||
ArrayList<Variable> vars = new ArrayList<>();
|
ArrayList<Variable> vars = new ArrayList<>();
|
||||||
for (int i = n - 1; i >= 0; i--)
|
for (int i = n - 1; i >= 0; i--)
|
||||||
vars.add(new Variable("Q_" + i + "n"));
|
vars.add(new Variable("Q" + i + "n"));
|
||||||
TruthTable truthTable = new TruthTable(vars);
|
TruthTable truthTable = new TruthTable(vars);
|
||||||
int i = n - 1;
|
int i = n - 1;
|
||||||
int rows = 1 << n;
|
int rows = 1 << n;
|
||||||
@ -717,7 +718,7 @@ public class TableDialog extends JDialog {
|
|||||||
ArrayList<Variable> vars = new ArrayList<>();
|
ArrayList<Variable> vars = new ArrayList<>();
|
||||||
vars.add(new Variable("dir"));
|
vars.add(new Variable("dir"));
|
||||||
for (int i = n - 1; i >= 0; i--)
|
for (int i = n - 1; i >= 0; i--)
|
||||||
vars.add(new Variable("Q_" + i + "n"));
|
vars.add(new Variable("Q" + i + "n"));
|
||||||
TruthTable truthTable = new TruthTable(vars);
|
TruthTable truthTable = new TruthTable(vars);
|
||||||
int i = n - 1;
|
int i = n - 1;
|
||||||
int rows = 1 << (n + 1);
|
int rows = 1 << (n + 1);
|
||||||
@ -759,47 +760,42 @@ public class TableDialog extends JDialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class HTMLExpressionListener implements ExpressionListener {
|
private final class OutputExpressionListener implements ExpressionListener {
|
||||||
private FormatToExpression htmlFormatter = new HTMLFormatter(FormatToExpression.getDefaultFormat());
|
private FormatToExpression htmlFormatter = new HTMLFormatter(FormatToExpression.getDefaultFormat());
|
||||||
private final StringBuilder html;
|
private final ArrayList<Expression> expressions;
|
||||||
private int count;
|
|
||||||
private String firstExp;
|
|
||||||
|
|
||||||
private HTMLExpressionListener() {
|
private OutputExpressionListener() {
|
||||||
html = new StringBuilder("<html><table style=\"white-space: nowrap\">\n");
|
expressions = new ArrayList<>();
|
||||||
count = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resultFound(String name, Expression expression) throws FormatterException {
|
public void resultFound(String name, Expression expression) {
|
||||||
if (count == 0)
|
if (name.endsWith("^n+1"))
|
||||||
firstExp = "<html>" + htmlFormatter.identifier(name) + "=" + htmlFormatter.format(expression) + "</html>";
|
name = name.substring(0, name.length() - 4) + "^{n+1}";
|
||||||
html.append("<tr>");
|
expressions.add(new NamedExpression(name, expression));
|
||||||
html.append("<td>").append(htmlFormatter.identifier(name)).append("</td>");
|
|
||||||
html.append("<td>=</td>");
|
|
||||||
html.append("<td>").append(htmlFormatter.format(expression)).append("</td>");
|
|
||||||
html.append("</tr>\n");
|
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() throws FormatterException {
|
||||||
html.append("</table></html>");
|
String html = null;
|
||||||
|
if (expressions.size() == 1)
|
||||||
|
html = "<html>" + htmlFormatter.format(expressions.get(0)) + "</html>";
|
||||||
|
final String finalHtml = html;
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
switch (count) {
|
switch (expressions.size()) {
|
||||||
case 0:
|
case 0:
|
||||||
statusBar.setVisible(false);
|
statusBar.setVisible(false);
|
||||||
allSolutionsDialog.setNeeded(false);
|
allSolutionsDialog.setNeeded(false);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
statusBar.setVisible(true);
|
statusBar.setVisible(true);
|
||||||
statusBar.setText(firstExp);
|
statusBar.setText(finalHtml);
|
||||||
allSolutionsDialog.setNeeded(false);
|
allSolutionsDialog.setNeeded(false);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
statusBar.setVisible(false);
|
statusBar.setVisible(false);
|
||||||
allSolutionsDialog.setText(html.toString());
|
allSolutionsDialog.setExpressions(expressions);
|
||||||
allSolutionsDialog.setNeeded(true);
|
allSolutionsDialog.setNeeded(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user