improved the AllSolutionsDialog

This commit is contained in:
hneemann 2019-07-25 07:36:55 +02:00
parent e5266242d9
commit 51874037fb
5 changed files with 143 additions and 60 deletions

View File

@ -79,17 +79,13 @@ public final class GraphicsFormatter {
} else if (text instanceof Sentence) {
Sentence s = (Sentence) text;
SentenceFragment sf = new SentenceFragment();
int x = 0;
for (Text t : s)
if (t instanceof Blank)
x += font.getSize() / 2;
sf.pad(font.getSize() / 2);
else {
final Fragment f = createFragment(sizer, font, t);
f.x = x;
x += f.dx;
sf.add(f);
}
sf.dx = x;
return sf.setUp();
} else if (text instanceof Index) {
Index i = (Index) text;
@ -154,27 +150,41 @@ public final class GraphicsFormatter {
NamedExpression ne = (NamedExpression) expression;
SentenceFragment f = new SentenceFragment();
f.add(createFragment(sizer, font, ne.getName()));
f.pad(font.getSize()/2);
f.add(new TextFragment(sizer, font, "="));
f.pad(font.getSize()/2);
f.add(createFragment(sizer, font, ne.getExpression()));
return f;
return f.setUp();
} else
throw new FormatterException("unknown expression " + expression.getClass().getSimpleName());
}
private static Fragment createOperationFragment(FontSizer sizer, Font font, Operation op, String opString) throws FormatterException {
int pad = font.getSize() / 2;
SentenceFragment f = new SentenceFragment();
for (Expression e : op.getExpressions()) {
if (f.size() > 0)
f.add(new TextFragment(sizer, font, opString));
f.add(createFragment(sizer, font, e));
if (f.size() > 0) {
f.pad(pad);
if (!opString.isEmpty()) {
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));
}
}
return f;
return f.setUp();
}
/**
* Exception which indicates a formatter exception
*/
private static final class FormatterException extends Exception {
public static final class FormatterException extends Exception {
FormatterException(String 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;
@ -272,6 +282,12 @@ public final class GraphicsFormatter {
private void add(Fragment fragment) {
fragments.add(fragment);
fragment.x = dx;
dx += fragment.dx;
}
private void pad(int p) {
dx += p;
}
@Override

View File

@ -83,7 +83,7 @@ public class TransitionTableCreator {
// create state variables
ArrayList<Variable> vars = new ArrayList<>();
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);
boolean initVal = (initState & (1 << i)) != 0;
modelAnalyserInfo.setSequentialInitValue(var.getIdentifier(), initVal ? 1 : 0);
@ -93,7 +93,7 @@ public class TransitionTableCreator {
// create the next state result variables
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
TreeSet<String> results = new TreeSet<>();

View File

@ -5,6 +5,7 @@
*/
package de.neemann.digital.gui.components.table;
import de.neemann.digital.analyse.expression.Expression;
import de.neemann.digital.lang.Lang;
import de.neemann.gui.Screen;
@ -12,13 +13,15 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
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.
*/
public class AllSolutionsDialog extends JDialog {
private final JTextPane textPane;
private final JScrollPane scroll;
private final ExpressionComponent expressionComponent;
private boolean userHasClosed = false;
/**
@ -31,15 +34,11 @@ public class AllSolutionsDialog extends JDialog {
super(owner, Lang.get("win_allSolutions"), false);
setDefaultCloseOperation(HIDE_ON_CLOSE);
textPane = new JTextPane();
textPane.setContentType("text/html");
textPane.setFont(font);
textPane.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, true);
textPane.setEditable(false);
textPane.setPreferredSize(Screen.getInstance().scale(new Dimension(600, 300)));
expressionComponent = new ExpressionComponent();
expressionComponent.setPreferredSize(Screen.getInstance().scale(new Dimension(600, 300)));
expressionComponent.setFont(font);
scroll = new JScrollPane(textPane);
getContentPane().add(scroll);
getContentPane().add(new JScrollPane(expressionComponent));
addWindowListener(new WindowAdapter() {
@Override
@ -52,18 +51,6 @@ public class AllSolutionsDialog extends JDialog {
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.
*
@ -73,4 +60,15 @@ public class AllSolutionsDialog extends JDialog {
if (!userHasClosed)
setVisible(needed);
}
/**
* Sets the expressions
*
* @param expressions the expressions to show
*/
public void setExpressions(ArrayList<Expression> expressions) {
expressionComponent.setExpressions(expressions);
}
}

View File

@ -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();
});
}
}
}

View File

@ -11,6 +11,7 @@ import de.neemann.digital.analyse.TruthTable;
import de.neemann.digital.analyse.TruthTableTableModel;
import de.neemann.digital.analyse.expression.Expression;
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.format.FormatToExpression;
import de.neemann.digital.analyse.expression.format.FormatToTableLatex;
@ -606,7 +607,7 @@ public class TableDialog extends JDialog {
private void calculateExpressions() {
try {
LOGGER.info("start optimization");
ExpressionListener expressionListener = new HTMLExpressionListener();
ExpressionListener expressionListener = new OutputExpressionListener();
if (createJK.isSelected())
expressionListener = new ExpressionListenerJK(expressionListener);
@ -688,7 +689,7 @@ public class TableDialog extends JDialog {
public void actionPerformed(ActionEvent actionEvent) {
ArrayList<Variable> vars = new ArrayList<>();
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);
int i = n - 1;
int rows = 1 << n;
@ -717,7 +718,7 @@ public class TableDialog extends JDialog {
ArrayList<Variable> vars = new ArrayList<>();
vars.add(new Variable("dir"));
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);
int i = 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 final StringBuilder html;
private int count;
private String firstExp;
private final ArrayList<Expression> expressions;
private HTMLExpressionListener() {
html = new StringBuilder("<html><table style=\"white-space: nowrap\">\n");
count = 0;
private OutputExpressionListener() {
expressions = new ArrayList<>();
}
@Override
public void resultFound(String name, Expression expression) throws FormatterException {
if (count == 0)
firstExp = "<html>" + htmlFormatter.identifier(name) + "=" + htmlFormatter.format(expression) + "</html>";
html.append("<tr>");
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++;
public void resultFound(String name, Expression expression) {
if (name.endsWith("^n+1"))
name = name.substring(0, name.length() - 4) + "^{n+1}";
expressions.add(new NamedExpression(name, expression));
}
@Override
public void close() {
html.append("</table></html>");
public void close() throws FormatterException {
String html = null;
if (expressions.size() == 1)
html = "<html>" + htmlFormatter.format(expressions.get(0)) + "</html>";
final String finalHtml = html;
SwingUtilities.invokeLater(() -> {
switch (count) {
switch (expressions.size()) {
case 0:
statusBar.setVisible(false);
allSolutionsDialog.setNeeded(false);
break;
case 1:
statusBar.setVisible(true);
statusBar.setText(firstExp);
statusBar.setText(finalHtml);
allSolutionsDialog.setNeeded(false);
break;
default:
statusBar.setVisible(false);
allSolutionsDialog.setText(html.toString());
allSolutionsDialog.setExpressions(expressions);
allSolutionsDialog.setNeeded(true);
}
});