From fa8278924dc34cb3ea3b022b902a60fd23ea31dc Mon Sep 17 00:00:00 2001 From: hneemann Date: Sat, 25 Mar 2017 20:53:46 +0100 Subject: [PATCH] separated InsertAction.java to use it in component tree view --- .../digital/draw/library/ElementLibrary.java | 56 ++++++++++--- .../de/neemann/digital/gui/InsertAction.java | 78 +++++++++++++++++++ .../de/neemann/digital/gui/InsertHistory.java | 4 +- .../neemann/digital/gui/LibrarySelector.java | 57 +------------- .../java/de/neemann/digital/gui/Main.java | 10 ++- .../gui/components/CircuitComponent.java | 1 + src/main/resources/lang/lang_de.xml | 2 - src/main/resources/lang/lang_en.xml | 2 - .../digital/lang/TestElemConsistence.java | 3 +- 9 files changed, 138 insertions(+), 75 deletions(-) create mode 100644 src/main/java/de/neemann/digital/gui/InsertAction.java diff --git a/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java b/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java index 63ab189ed..d87902bda 100644 --- a/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java +++ b/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java @@ -1,7 +1,6 @@ package de.neemann.digital.draw.library; import de.neemann.digital.core.arithmetic.*; -import de.neemann.digital.core.arithmetic.Comparator; import de.neemann.digital.core.basic.*; import de.neemann.digital.core.element.*; import de.neemann.digital.core.flipflops.FlipflopD; @@ -34,7 +33,10 @@ import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; /** * @author hneemann @@ -142,7 +144,11 @@ public class ElementLibrary implements Iterable node.add(TestCaseElement.TESTCASEDESCRIPTION); root.add(node); - populateNodeMap(); + try { + populateNodeMap(); + } catch (IOException e) { + // can not happen because there are no custom elements yet + } } /** @@ -154,13 +160,11 @@ public class ElementLibrary implements Iterable this.shapeFactory = shapeFactory; } - private void populateNodeMap() { + private void populateNodeMap() throws IOException { map.clear(); - root.traverse(libraryNode -> { - if (libraryNode.isLeaf()) { - map.put(libraryNode.getName(), libraryNode); - } - }); + String dn = root.traverse(new PopulateModelVisitor(map)).getDoubleNode(); + if (dn != null) + throw new IOException(Lang.get("err_file_N0_ExistsTwiceBelow_N1", dn, rootLibraryPath)); } /** @@ -220,7 +224,7 @@ public class ElementLibrary implements Iterable throw new ElementNotFoundException(Lang.get("err_element_N_notFound", elementName)); } - private void rescanFolder() { + private void rescanFolder() throws IOException { LOGGER.debug("rescan folder"); if (customNode == null) { customNode = new LibraryNode(Lang.get("menu_custom")); @@ -338,7 +342,12 @@ public class ElementLibrary implements Iterable return new LibraryNode(file.getName(), () -> { try { LOGGER.debug("load element " + file); - Circuit circuit = Circuit.loadCircuit(file, shapeFactory); + Circuit circuit; + try { + circuit = Circuit.loadCircuit(file, shapeFactory); + } catch (IOException e) { + throw new IOException(Lang.get("err_couldNotFindIncludedFile_N0", file)); + } ElementTypeDescriptionCustom description = new ElementTypeDescriptionCustom(file, attributes -> new CustomElement(circuit, ElementLibrary.this, file), @@ -464,4 +473,29 @@ public class ElementLibrary implements Iterable return treePath; } } + + private static final class PopulateModelVisitor implements Visitor { + private final HashMap map; + private String doubleNode; + + private PopulateModelVisitor(HashMap map) { + this.map = map; + } + + @Override + public void visit(LibraryNode libraryNode) { + if (libraryNode.isLeaf()) { + final String name = libraryNode.getName(); + + if (map.containsKey(name)) + doubleNode = name; + + map.put(name, libraryNode); + } + } + + private String getDoubleNode() { + return doubleNode; + } + } } diff --git a/src/main/java/de/neemann/digital/gui/InsertAction.java b/src/main/java/de/neemann/digital/gui/InsertAction.java new file mode 100644 index 000000000..4e7136242 --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/InsertAction.java @@ -0,0 +1,78 @@ +package de.neemann.digital.gui; + +import de.neemann.digital.draw.elements.VisualElement; +import de.neemann.digital.draw.graphics.Vector; +import de.neemann.digital.draw.library.ElementLibrary; +import de.neemann.digital.draw.library.LibraryNode; +import de.neemann.digital.draw.shapes.ShapeFactory; +import de.neemann.digital.gui.components.CircuitComponent; +import de.neemann.digital.lang.Lang; +import de.neemann.gui.ErrorMessage; +import de.neemann.gui.ToolTipAction; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.io.IOException; + +/** + * Action to insert the given node to the given circuit + * Created by hneemann on 25.03.17. + */ +final class InsertAction extends ToolTipAction { + private final LibraryNode node; + private final InsertHistory insertHistory; + private final CircuitComponent circuitComponent; + private final ShapeFactory shapeFactory; + + /** + * Creates a new instance + * + * @param node the node which holds the element to add + * @param insertHistory the history to add the element to + * @param circuitComponent the component to add the element to + * @param shapeFactory the shapeFactory to create the icon + */ + public InsertAction(LibraryNode node, InsertHistory insertHistory, CircuitComponent circuitComponent, ShapeFactory shapeFactory) { + super(node.getTranslatedName(), createIcon(node, shapeFactory)); + this.shapeFactory = shapeFactory; + this.node = node; + this.insertHistory = insertHistory; + this.circuitComponent = circuitComponent; + } + + @Override + public void actionPerformed(ActionEvent e) { + VisualElement visualElement = new VisualElement(node.getName()).setPos(new Vector(10, 10)).setShapeFactory(shapeFactory); + circuitComponent.setPartToInsert(visualElement); + if (getIcon() == null) { + try { + node.getDescription(); + setIcon(createIcon(node, shapeFactory)); + } catch (IOException ex) { + SwingUtilities.invokeLater(new ErrorMessage(Lang.get("msg_errorImportingModel")).addCause(ex)); + } + } + insertHistory.add(this); + } + + /** + * @return true if element to insert is a custom element + */ + public boolean isCustom() { + return node.getDescriptionOrNull() instanceof ElementLibrary.ElementTypeDescriptionCustom; + } + + private static ImageIcon createIcon(LibraryNode node, ShapeFactory shapeFactory) { + // doesn't load the description if only the icon is needed + // create action without an icon instead + if (node.isDescriptionLoaded()) { + try { + return new VisualElement(node.getDescription().getName()).setShapeFactory(shapeFactory).createIcon(75); + } catch (IOException ex) { + SwingUtilities.invokeLater(new ErrorMessage(Lang.get("msg_errorImportingModel")).addCause(ex)); + } + } + return null; + } + +} diff --git a/src/main/java/de/neemann/digital/gui/InsertHistory.java b/src/main/java/de/neemann/digital/gui/InsertHistory.java index 28966acb6..205d015dc 100644 --- a/src/main/java/de/neemann/digital/gui/InsertHistory.java +++ b/src/main/java/de/neemann/digital/gui/InsertHistory.java @@ -83,8 +83,8 @@ public class InsertHistory { Iterator it = wrappers.iterator(); while (it.hasNext()) { WrapperAction w = it.next(); - if (w.action instanceof LibrarySelector.InsertAction) { - if (((LibrarySelector.InsertAction) w.action).isCustom()) { + if (w.action instanceof InsertAction) { + if (((InsertAction) w.action).isCustom()) { removeWrapperFromBar(w); it.remove(); } diff --git a/src/main/java/de/neemann/digital/gui/LibrarySelector.java b/src/main/java/de/neemann/digital/gui/LibrarySelector.java index e8d5cf9e0..6bc11b6ef 100644 --- a/src/main/java/de/neemann/digital/gui/LibrarySelector.java +++ b/src/main/java/de/neemann/digital/gui/LibrarySelector.java @@ -1,13 +1,10 @@ package de.neemann.digital.gui; -import de.neemann.digital.draw.elements.VisualElement; -import de.neemann.digital.draw.graphics.Vector; import de.neemann.digital.draw.library.ElementLibrary; import de.neemann.digital.draw.library.LibraryListener; import de.neemann.digital.draw.library.LibraryNode; import de.neemann.digital.draw.shapes.ShapeFactory; import de.neemann.digital.gui.components.CircuitComponent; -import de.neemann.digital.gui.state.State; import de.neemann.digital.lang.Lang; import de.neemann.gui.ErrorMessage; import de.neemann.gui.StringUtils; @@ -26,7 +23,6 @@ import java.io.IOException; public class LibrarySelector implements LibraryListener { private final ElementLibrary library; private final ShapeFactory shapeFactory; - private final State elementState; private JMenu componentsMenu; private InsertHistory insertHistory; private CircuitComponent circuitComponent; @@ -37,13 +33,11 @@ public class LibrarySelector implements LibraryListener { * * @param library the library to select elements from * @param shapeFactory The shape factory - * @param elementState the elements state */ - public LibrarySelector(ElementLibrary library, ShapeFactory shapeFactory, State elementState) { + public LibrarySelector(ElementLibrary library, ShapeFactory shapeFactory) { this.library = library; library.addListener(this); this.shapeFactory = shapeFactory; - this.elementState = elementState; } /** @@ -91,7 +85,7 @@ public class LibrarySelector implements LibraryListener { private void addComponents(JMenu parts, LibraryNode node) { if (node.isLeaf()) { - parts.add(new InsertAction(node, insertHistory, circuitComponent) + parts.add(new InsertAction(node, insertHistory, circuitComponent, shapeFactory) .setToolTip(createToolTipText(node.getName())) .createJMenuItem()); } else { @@ -105,51 +99,4 @@ public class LibrarySelector implements LibraryListener { private static String createToolTipText(String elementName) { return StringUtils.textToHTML(Lang.getNull("elem_" + elementName + "_tt")); } - - final class InsertAction extends ToolTipAction { - private final LibraryNode node; - private final InsertHistory insertHistory; - private final CircuitComponent circuitComponent; - - private InsertAction(LibraryNode node, InsertHistory insertHistory, CircuitComponent circuitComponent) { - super(node.getTranslatedName(), createIcon(node, shapeFactory)); - this.node = node; - this.insertHistory = insertHistory; - this.circuitComponent = circuitComponent; - } - - @Override - public void actionPerformed(ActionEvent e) { - VisualElement visualElement = new VisualElement(node.getName()).setPos(new Vector(10, 10)).setShapeFactory(shapeFactory); - elementState.enter(); - circuitComponent.setPartToInsert(visualElement); - if (getIcon() == null) { - try { - node.getDescription(); - setIcon(createIcon(node, shapeFactory)); - } catch (IOException ex) { - SwingUtilities.invokeLater(new ErrorMessage(Lang.get("msg_errorImportingModel")).addCause(ex)); - } - } - insertHistory.add(this); - } - - public boolean isCustom() { - return node.getDescriptionOrNull() instanceof ElementLibrary.ElementTypeDescriptionCustom; - } - } - - private static ImageIcon createIcon(LibraryNode node, ShapeFactory shapeFactory) { - // don't load the description if only the icon is needed - // create action without an icon instead - if (node.isDescriptionLoaded()) { - try { - return new VisualElement(node.getDescription().getName()).setShapeFactory(shapeFactory).createIcon(75); - } catch (IOException ex) { - SwingUtilities.invokeLater(new ErrorMessage(Lang.get("msg_errorImportingModel")).addCause(ex)); - } - } - return null; - } - } diff --git a/src/main/java/de/neemann/digital/gui/Main.java b/src/main/java/de/neemann/digital/gui/Main.java index e10373475..26bfe7ab4 100644 --- a/src/main/java/de/neemann/digital/gui/Main.java +++ b/src/main/java/de/neemann/digital/gui/Main.java @@ -225,7 +225,7 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E toolBar.addSeparator(); - librarySelector = new LibrarySelector(library, shapeFactory, stoppedState); + librarySelector = new LibrarySelector(library, shapeFactory); menuBar.add(librarySelector.buildMenu(new InsertHistory(toolBar), circuitComponent)); getContentPane().add(toolBar, BorderLayout.NORTH); @@ -797,6 +797,14 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E }); } + /** + * stops the model + */ + public void stopModel() { + stoppedState.enter(); + } + + private static JFileChooser getJFileChooser(File filename) { File folder = null; if (filename != null) 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 f1481b437..e1b9d579e 100644 --- a/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java +++ b/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java @@ -398,6 +398,7 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe * @param element the element to insert */ public void setPartToInsert(VisualElement element) { + parent.stopModel(); mouseInsertElement.activate(element); } diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml index 80c19eadf..032d6fc81 100644 --- a/src/main/resources/lang/lang_de.xml +++ b/src/main/resources/lang/lang_de.xml @@ -601,8 +601,6 @@ Es sind nur {1} Variablen erlaubt, es wurden jedoch {2} gefunden. Sortieren der Ausgänge Sortiert die Ausgänge für die Verwendung als eingebettete Schaltung Einfügen - Alle neu laden - Alle importierten Schaltungen werden neu geladen Rotieren Start der Simulation Startet die Simulation der Schaltung diff --git a/src/main/resources/lang/lang_en.xml b/src/main/resources/lang/lang_en.xml index 678eaa39c..8b3a0aeb8 100644 --- a/src/main/resources/lang/lang_en.xml +++ b/src/main/resources/lang/lang_en.xml @@ -588,8 +588,6 @@ allowed are {1} variables but {2} are found. Order Outputs Order the outputs for the usage as nested circuit Paste - Reload - Reload all imported circuits Rotate Start Simulation Starts the simulation of the circuit. diff --git a/src/test/java/de/neemann/digital/lang/TestElemConsistence.java b/src/test/java/de/neemann/digital/lang/TestElemConsistence.java index 7b850ff41..2be2953e4 100644 --- a/src/test/java/de/neemann/digital/lang/TestElemConsistence.java +++ b/src/test/java/de/neemann/digital/lang/TestElemConsistence.java @@ -23,7 +23,6 @@ public class TestElemConsistence extends TestCase { * @throws NodeException */ public void testConsistence() throws NodeException, PinException { - /* ElementLibrary library = new ElementLibrary(); for (ElementLibrary.ElementContainer e : library) { ElementTypeDescription etd = e.getDescription(); @@ -38,7 +37,7 @@ public class TestElemConsistence extends TestCase { checkPins(key, etd.getInputDescription(new ElementAttributes())); checkPins(key, etd.getOutputDescriptions(new ElementAttributes())); } - }*/ fail(); + } } private void checkPins(String key, PinDescriptions pins) {