From 51874037fbf889d9a18d4829e9f2faefee33eaf4 Mon Sep 17 00:00:00 2001 From: hneemann Date: Thu, 25 Jul 2019 07:36:55 +0200 Subject: [PATCH] improved the AllSolutionsDialog --- .../text/formatter/GraphicsFormatter.java | 40 +++++++--- .../digital/fsm/TransitionTableCreator.java | 4 +- .../components/table/AllSolutionsDialog.java | 42 +++++------ .../components/table/ExpressionComponent.java | 73 +++++++++++++++++++ .../gui/components/table/TableDialog.java | 44 +++++------ 5 files changed, 143 insertions(+), 60 deletions(-) create mode 100644 src/main/java/de/neemann/digital/gui/components/table/ExpressionComponent.java diff --git a/src/main/java/de/neemann/digital/draw/graphics/text/formatter/GraphicsFormatter.java b/src/main/java/de/neemann/digital/draw/graphics/text/formatter/GraphicsFormatter.java index e1704b49a..2045086ca 100644 --- a/src/main/java/de/neemann/digital/draw/graphics/text/formatter/GraphicsFormatter.java +++ b/src/main/java/de/neemann/digital/draw/graphics/text/formatter/GraphicsFormatter.java @@ -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 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 diff --git a/src/main/java/de/neemann/digital/fsm/TransitionTableCreator.java b/src/main/java/de/neemann/digital/fsm/TransitionTableCreator.java index 725eb9b54..9aaa0c417 100644 --- a/src/main/java/de/neemann/digital/fsm/TransitionTableCreator.java +++ b/src/main/java/de/neemann/digital/fsm/TransitionTableCreator.java @@ -83,7 +83,7 @@ public class TransitionTableCreator { // create state variables ArrayList 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 results = new TreeSet<>(); diff --git a/src/main/java/de/neemann/digital/gui/components/table/AllSolutionsDialog.java b/src/main/java/de/neemann/digital/gui/components/table/AllSolutionsDialog.java index 649debf79..b2b3ecca3 100644 --- a/src/main/java/de/neemann/digital/gui/components/table/AllSolutionsDialog.java +++ b/src/main/java/de/neemann/digital/gui/components/table/AllSolutionsDialog.java @@ -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 expressions) { + expressionComponent.setExpressions(expressions); + } + + } diff --git a/src/main/java/de/neemann/digital/gui/components/table/ExpressionComponent.java b/src/main/java/de/neemann/digital/gui/components/table/ExpressionComponent.java new file mode 100644 index 000000000..d8fab02f2 --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/components/table/ExpressionComponent.java @@ -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 expressions; + private Dimension lastRectSet; + + /** + * Sets the expressions to visualize + * + * @param expressions expressions + */ + public void setExpressions(ArrayList 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(); + }); + } + } +} diff --git a/src/main/java/de/neemann/digital/gui/components/table/TableDialog.java b/src/main/java/de/neemann/digital/gui/components/table/TableDialog.java index bd77022ae..0e1e942fc 100644 --- a/src/main/java/de/neemann/digital/gui/components/table/TableDialog.java +++ b/src/main/java/de/neemann/digital/gui/components/table/TableDialog.java @@ -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 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 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 expressions; - private HTMLExpressionListener() { - html = new StringBuilder("\n"); - count = 0; + private OutputExpressionListener() { + expressions = new ArrayList<>(); } @Override - public void resultFound(String name, Expression expression) throws FormatterException { - if (count == 0) - firstExp = "" + htmlFormatter.identifier(name) + "=" + htmlFormatter.format(expression) + ""; - html.append(""); - html.append(""); - html.append(""); - html.append(""); - html.append("\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("
").append(htmlFormatter.identifier(name)).append("=").append(htmlFormatter.format(expression)).append("
"); + public void close() throws FormatterException { + String html = null; + if (expressions.size() == 1) + html = "" + htmlFormatter.format(expressions.get(0)) + ""; + 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); } });