merged changes

This commit is contained in:
Bane Stojkovic
2025-03-11 23:42:56 +01:00
parent f966f8873a
commit 6e919714d3
17 changed files with 438 additions and 60 deletions
@@ -35,19 +35,9 @@ public enum Orientation {
} }
public double toDegrees() { public double toDegrees() {
switch (this) { if (this == DEFAULT)
case DEFAULT: return 0;
return 0; return Integer.parseInt(name().replace("_", ""));
case _180:
return 180;
case _270:
return 270;
case _90:
return 90;
default:
break;
}
return 0;
} }
public double toRadians() { public double toRadians() {
@@ -0,0 +1,46 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
This file is part of DIYLC.
DIYLC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DIYLC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
*/
package org.diylc.common;
public enum Orientation45 {
DEFAULT, _45, _90, _135, _180, _225, _270, _315;
@Override
public String toString() {
if (this == DEFAULT) {
return "Default";
} else {
return name().replace("_", "") + " degrees clockwise";
}
}
public double toDegrees() {
if (this == DEFAULT)
return 0;
return Integer.parseInt(name().replace("_", ""));
}
public double toRadians() {
return Math.toRadians(toDegrees());
}
}
@@ -72,7 +72,7 @@ public enum IconLoader {
BufferedImage img = null; BufferedImage img = null;
try { try {
img = ImageIO.read(getClass().getResourceAsStream("/images/" + name)); img = ImageIO.read(getClass().getResourceAsStream("/images/" + name));
} catch (IOException e) { } catch (Exception e) {
Logger.getLogger(IconLoader.class).error("Couldn't find file: " + name); Logger.getLogger(IconLoader.class).error("Couldn't find file: " + name);
} }
return img; return img;
@@ -27,9 +27,9 @@ import java.util.Set;
import org.diylc.core.IDIYComponent; import org.diylc.core.IDIYComponent;
public abstract class NetlistAnalyzer { public abstract class AbstractNetlistAnalyzer {
public NetlistAnalyzer() { public AbstractNetlistAnalyzer() {
} }
public List<Summary> summarize(List<Netlist> netlists, Node preferredOutput) public List<Summary> summarize(List<Netlist> netlists, Node preferredOutput)
@@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import org.diylc.core.IDIYComponent; import org.diylc.core.IDIYComponent;
@@ -59,10 +60,6 @@ public class Netlist implements Comparable<Netlist> {
return switchSetup; return switchSetup;
} }
public void done() {
Collections.sort(switchSetup);
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
@@ -88,10 +85,15 @@ public class Netlist implements Comparable<Netlist> {
return true; return true;
} }
public String getSwitchSetupString() {
return getSwitchSetup().isEmpty() ? "[ ALL ]" : "[ " +
getSwitchSetup().stream().map(x -> x.toString()).collect(Collectors.joining(",")) + " ]";
}
@Override @Override
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("Switch setup: ").append(getSwitchSetup()).append("\n\n"); sb.append("Switch setup: ").append(getSwitchSetupString()).append("\n\n");
List<Group> list = getSortedGroups(); List<Group> list = getSortedGroups();
for (Group g : list) { for (Group g : list) {
sb.append("\t").append(g).append("\n"); sb.append("\t").append(g).append("\n");
@@ -19,15 +19,7 @@ package org.diylc.netlist;
import java.awt.geom.Area; import java.awt.geom.Area;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@@ -191,10 +183,29 @@ public class NetlistBuilder {
// sort everything alphabetically // sort everything alphabetically
List<Netlist> netlists = new ArrayList<Netlist>(result.keySet()); List<Netlist> netlists = new ArrayList<Netlist>(result.keySet());
Collections.sort(netlists); Collections.sort(netlists);
netlists.forEach(netlist -> cleanupRedundantSwitches(netlist.getSwitchSetup()));
return netlists; return netlists;
} }
public static void cleanupRedundantSwitches(List<SwitchSetup> switchSetups) {
Map<ISwitch, Set<Integer>> positionCountMap = new HashMap<>();
switchSetups.forEach(s -> s.getPositions().forEach(pos -> {
positionCountMap.computeIfAbsent(pos.getSwitch(), k -> new HashSet<Integer>()).add(pos.getPosition());
}));
// find switches that are here in all the positions, meaning that they don't affect the circuit
Set<ISwitch> switchesToPrune = positionCountMap.entrySet().stream()
.filter(e -> e.getKey().getPositionCount() == e.getValue().size())
.map(x -> x.getKey())
.collect(Collectors.toSet());
switchSetups.forEach(s -> s.getPositions().removeIf(x -> switchesToPrune.contains(x.getSwitch())));
switchSetups.removeIf(x -> x.getPositions().isEmpty());
HashSet<SwitchSetup> uniqueSetups = new HashSet<>(switchSetups);
switchSetups.clear();
switchSetups.addAll(uniqueSetups);
switchSetups.sort(Comparator.comparing(x -> x.toString()));
}
public static Netlist buildNetlist(List<IDIYComponent<?>> components, Collection<Node> nodes, public static Netlist buildNetlist(List<IDIYComponent<?>> components, Collection<Node> nodes,
Collection<ContinuityArea> continuityAreas, Collection<Connection> connections) { Collection<ContinuityArea> continuityAreas, Collection<Connection> connections) {
ImmutableGraph<ProjectGraphNode> graph = buildGraph(nodes, continuityAreas, connections); ImmutableGraph<ProjectGraphNode> graph = buildGraph(nodes, continuityAreas, connections);
@@ -172,10 +172,10 @@ public class Tree {
} }
public String toAsciiString() { public String toAsciiString() {
return String.join("<br>", toAscii()); return String.join("<br>", toAsciiLines());
} }
private List<String> toAscii() { private List<String> toAsciiLines() {
if (leaf != null) { if (leaf != null) {
return Arrays.asList(TreeAsciiUtil.generateString(TreeAsciiUtil.BOXH, return Arrays.asList(TreeAsciiUtil.generateString(TreeAsciiUtil.BOXH,
1) + " " + leaf.toHTML() + " " + TreeAsciiUtil.generateString(TreeAsciiUtil.BOXH, 1)); 1) + " " + leaf.toHTML() + " " + TreeAsciiUtil.generateString(TreeAsciiUtil.BOXH, 1));
@@ -184,7 +184,7 @@ public class Tree {
List<Tree> children = getOrderedChildren(); List<Tree> children = getOrderedChildren();
List<List<String>> childrenAscii = List<List<String>> childrenAscii =
children.stream().map(c -> c.toAscii()).collect(Collectors.toList()); children.stream().map(c -> c.toAsciiLines()).collect(Collectors.toList());
if (TreeConnectionType.Series.equals(connectionType)) { if (TreeConnectionType.Series.equals(connectionType)) {
return TreeAsciiUtil.concatenateMultiLineSerial( return TreeAsciiUtil.concatenateMultiLineSerial(
@@ -36,11 +36,7 @@ import org.apache.log4j.Logger;
import org.diylc.appframework.miscutils.ConfigurationManager; import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.clipboard.ComponentTransferable; import org.diylc.clipboard.ComponentTransferable;
import org.diylc.common.ComponentType; import org.diylc.common.*;
import org.diylc.common.IPlugInPort;
import org.diylc.common.Orientation;
import org.diylc.common.OrientationHV;
import org.diylc.common.PropertyWrapper;
import org.diylc.core.Angle; import org.diylc.core.Angle;
import org.diylc.core.CreationMethod; import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent; import org.diylc.core.IDIYComponent;
@@ -437,6 +433,7 @@ public class InstantiationManager {
for (PropertyWrapper propertyWrapper : properties) { for (PropertyWrapper propertyWrapper : properties) {
if (propertyWrapper.getType().getName().equals(Orientation.class.getName()) if (propertyWrapper.getType().getName().equals(Orientation.class.getName())
|| propertyWrapper.getType().getName().equals(OrientationHV.class.getName()) || propertyWrapper.getType().getName().equals(OrientationHV.class.getName())
|| propertyWrapper.getType().getName().equals(Orientation45.class.getName())
|| propertyWrapper.getName().equalsIgnoreCase("angle")) { || propertyWrapper.getName().equalsIgnoreCase("angle")) {
angleProperty = propertyWrapper; angleProperty = propertyWrapper;
break; break;
@@ -456,6 +453,9 @@ public class InstantiationManager {
} else if (value instanceof OrientationHV) { } else if (value instanceof OrientationHV) {
angleProperty.setValue(OrientationHV.values()[(((OrientationHV) value).ordinal() + 1) angleProperty.setValue(OrientationHV.values()[(((OrientationHV) value).ordinal() + 1)
% OrientationHV.values().length]); % OrientationHV.values().length]);
} else if (value instanceof Orientation45) {
angleProperty.setValue(Orientation45.values()[(((Orientation45) value).ordinal() + 1)
% Orientation45.values().length]);
} else if (value instanceof Angle) { } else if (value instanceof Angle) {
Angle angle = (Angle) angleProperty.getValue(); Angle angle = (Angle) angleProperty.getValue();
Angle newAngle = angle.rotate(1); Angle newAngle = angle.rotate(1);
@@ -32,7 +32,6 @@ import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@@ -50,7 +49,6 @@ import javax.swing.JOptionPane;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.diylc.appframework.miscutils.IConfigListener; import org.diylc.appframework.miscutils.IConfigListener;
import org.diylc.appframework.miscutils.IConfigurationManager; import org.diylc.appframework.miscutils.IConfigurationManager;
import org.diylc.appframework.miscutils.JarScanner;
import org.diylc.appframework.miscutils.Utils; import org.diylc.appframework.miscutils.Utils;
import org.diylc.appframework.simplemq.MessageDispatcher; import org.diylc.appframework.simplemq.MessageDispatcher;
import org.diylc.appframework.update.Version; import org.diylc.appframework.update.Version;
@@ -88,7 +86,7 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.lang.LangUtil; import org.diylc.lang.LangUtil;
import org.diylc.netlist.INetlistParser; import org.diylc.netlist.INetlistParser;
import org.diylc.netlist.Netlist; import org.diylc.netlist.Netlist;
import org.diylc.netlist.NetlistAnalyzer; import org.diylc.netlist.AbstractNetlistAnalyzer;
import org.diylc.netlist.NetlistBuilder; import org.diylc.netlist.NetlistBuilder;
import org.diylc.netlist.NetlistException; import org.diylc.netlist.NetlistException;
import org.diylc.serialization.ProjectFileManager; import org.diylc.serialization.ProjectFileManager;
@@ -2030,7 +2028,7 @@ public class Presenter implements IPlugInPort, IConfigListener {
if (netlists == null) if (netlists == null)
return; return;
List<Set<IDIYComponent<?>>> allGroups = NetlistAnalyzer.extractComponentGroups(netlists); List<Set<IDIYComponent<?>>> allGroups = AbstractNetlistAnalyzer.extractComponentGroups(netlists);
// Find control points of all selected components and all types // Find control points of all selected components and all types
Set<String> selectedNamePrefixes = new HashSet<String>(); Set<String> selectedNamePrefixes = new HashSet<String>();
if (expansionMode == ExpansionMode.SAME_TYPE) { if (expansionMode == ExpansionMode.SAME_TYPE) {
@@ -56,4 +56,15 @@ public class TreeAsciiUtilTest {
// assertEquals("yy-yyy", result.get(1)); // assertEquals("yy-yyy", result.get(1));
// assertEquals("&nbsp;&nbsp;&nbsp;aaa", result.get(2)); // assertEquals("&nbsp;&nbsp;&nbsp;aaa", result.get(2));
} }
@Test
public void testSimpleParallel() {
List<String> result = TreeAsciiUtil.concatenateMultiLineParallel(
Arrays.asList(Arrays.asList("xx"), Arrays.asList("yy")));
assertNotNull(result);
assertEquals(3, result.size());
assertEquals("&nbsp;&#x250C;xx&#x2510;&nbsp;", result.get(0));
assertEquals("&#x2500;&#x2524;&nbsp;&nbsp;&#x251C;&#x2500;", result.get(1));
assertEquals("&nbsp;&#x2514;yy&#x2518;&nbsp;", result.get(2));
}
} }
@@ -0,0 +1,243 @@
/*
*
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
*
* This file is part of DIYLC.
*
* DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with DIYLC. If not, see
* <http://www.gnu.org/licenses/>.
*
*/
package org.diylc.components.connectivity;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation45;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.components.transform.SimpleComponentTransformer;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.KeywordPolicy;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Multimeter Probe", category = "Connectivity",
author = "Branislav Stojkovic", description = "Multimeter Probe", instanceNamePrefix = "Probe",
zOrder = IDIYComponent.TEXT, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false,
keywordPolicy = KeywordPolicy.SHOW_TYPE_NAME, transformer = SimpleComponentTransformer.class,
enableCache = true)
public class MultimeterProbe extends AbstractTransparentComponent<Color> {
private static final long serialVersionUID = 1L;
public static Size PROBE_DIAMETER = new Size(0.05d, SizeUnit.in);
public static Size PROBE_LENGTH = new Size(0.4d, SizeUnit.in);
public static Color PROBE_COLOR = METAL_COLOR;
public static Size HANDLE_DIAMETER = new Size(0.2d, SizeUnit.in);
public static Size HANDLE_LENGTH = new Size(0.4d, SizeUnit.in);
public static Color HANDLE_COLOR = Color.red;
private Point2D.Double point = new Point2D.Double(0, 0);
private Color handleColor = HANDLE_COLOR;
private Orientation45 orientation = Orientation45._315;
private transient Shape[] body = null;
public MultimeterProbe() {
this.alpha = (byte) (MAX_ALPHA / 2);
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
Project project, IDrawingObserver drawingObserver) {
Shape[] shapes = getBody();
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1f));
if (!outlineMode) {
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
}
g2d.setColor(PROBE_COLOR);
g2d.fill(shapes[0]);
g2d.setColor(handleColor);
g2d.fill(shapes[1]);
g2d.setComposite(oldComposite);
}
g2d.setColor(
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING
? SELECTION_COLOR
: handleColor.darker());
g2d.draw(shapes[1]);
g2d.setColor(
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING
? SELECTION_COLOR
: PROBE_COLOR.darker());
g2d.draw(shapes[0]);
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
double probeDiameter = 2;
double probeLength = height / 2 + 2;
double handleDiameter = width / 4;
double handleLength = height / 2 + 2;
double x = 2;
double y = height - 2;
Shape probe = buildProbeShape(probeDiameter, probeLength, x, y);
Shape handle = buildHandleShape(probeDiameter, probeLength, handleDiameter, handleLength, x, y);
double theta = Math.PI / 4;
AffineTransform tx = AffineTransform.getRotateInstance(theta, x, y);
probe = tx.createTransformedShape(probe);
handle = tx.createTransformedShape(handle);
g2d.setColor(PROBE_COLOR);
g2d.fill(probe);
g2d.setColor(HANDLE_COLOR);
g2d.fill(handle);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.setColor(PROBE_COLOR.darker());
g2d.draw(probe);
g2d.setColor(HANDLE_COLOR.darker());
g2d.draw(handle);
}
public Shape[] getBody() {
if (body == null) {
double probeDiameter = PROBE_DIAMETER.convertToPixels();
double probeLength = PROBE_LENGTH.convertToPixels();
double handleDiameter = HANDLE_DIAMETER.convertToPixels();
double handleLength = HANDLE_LENGTH.convertToPixels();
double x = point.getX();
double y = point.getY();
body = new Shape[2];
Path2D probe = buildProbeShape(probeDiameter, probeLength, x, y);
body[0] = probe;
Path2D handle =
buildHandleShape(probeDiameter, probeLength, handleDiameter, handleLength, x, y);
body[1] = handle;
double theta = orientation.toRadians();
if (theta != 0) {
AffineTransform tx = AffineTransform.getRotateInstance(theta, x, y);
body[0] = tx.createTransformedShape(body[0]);
body[1] = tx.createTransformedShape(body[1]);
}
}
return body;
}
private Path2D buildHandleShape(double probeDiameter, double probeLength, double handleDiameter,
double handleLength, double x, double y) {
Path2D handle = new Path2D.Double();
handle.moveTo(x + probeDiameter, y - probeLength);
handle.lineTo(x + handleDiameter / 2, y - handleLength - probeLength);
handle.lineTo(x - handleDiameter / 2, y - handleLength - probeLength);
handle.lineTo(x - probeDiameter, y - probeLength);
handle.moveTo(x + probeDiameter, y - probeLength);
handle.closePath();
return handle;
}
private Path2D buildProbeShape(double probeDiameter, double probeLength, double x, double y) {
Path2D probe = new Path2D.Double();
probe.moveTo(x, y);
probe.lineTo(x - probeDiameter / 2, y - probeDiameter);
probe.lineTo(x - probeDiameter / 2, y - probeLength);
probe.lineTo(x + probeDiameter / 2, y - probeLength);
probe.lineTo(x + probeDiameter / 2, y - probeDiameter);
probe.lineTo(x, y);
probe.closePath();
return probe;
}
@Override
public int getControlPointCount() {
return 1;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@Override
public Point2D getControlPoint(int index) {
return point;
}
@Override
public void setControlPoint(Point2D point, int index) {
this.point.setLocation(point);
this.body = null;
}
@Override
@EditableProperty(name = "Color")
public Color getValue() {
return handleColor;
}
public void setValue(Color color) {
this.handleColor = color;
}
@EditableProperty(name = "Angle")
public Orientation45 getOrientation() {
return orientation;
}
public void setOrientation(Orientation45 orientation) {
this.orientation = orientation;
this.body = null;
}
@Override
public String getControlPointNodeName(int index) {
return "Tip";
}
@Override
public Rectangle2D getCachingBounds() {
Shape[] shapes = getBody();
Rectangle2D bounds1 = shapes[0].getBounds2D();
Rectangle2D bounds2 = shapes[1].getBounds2D();
double minX = Math.min(bounds1.getMinX(), bounds2.getMinX());
double minY = Math.min(bounds1.getMinY(), bounds2.getMinY());
double maxX = Math.max(bounds1.getMaxX(), bounds2.getMaxX());
double maxY = Math.max(bounds1.getMaxY(), bounds2.getMaxY());
return new Rectangle2D.Double(minX - 1, minY - 1, maxX - minX + 2, maxY - minY + 2);
}
}
@@ -46,17 +46,9 @@ import org.diylc.components.passive.RadialFilmCapacitor;
import org.diylc.components.passive.RadialMicaCapacitor; import org.diylc.components.passive.RadialMicaCapacitor;
import org.diylc.components.passive.Resistor; import org.diylc.components.passive.Resistor;
import org.diylc.core.IDIYComponent; import org.diylc.core.IDIYComponent;
import org.diylc.netlist.Netlist;
import org.diylc.netlist.NetlistAnalyzer;
import org.diylc.netlist.Node;
import org.diylc.netlist.Summary;
import org.diylc.netlist.Tree;
import org.diylc.netlist.TreeConnectionType;
import org.diylc.netlist.TreeException;
import org.diylc.netlist.TreeLeaf;
import org.diylc.netlist.Tree.ITreeWalker; import org.diylc.netlist.Tree.ITreeWalker;
public class GuitarDiagramAnalyzer extends NetlistAnalyzer implements INetlistAnalyzer { public class GuitarDiagramAnalyzer extends AbstractNetlistAnalyzer implements INetlistAnalyzer {
private static Set<String> JACK_TYPES = new HashSet<String>(); private static Set<String> JACK_TYPES = new HashSet<String>();
private static Set<String> POT_TYPES = new HashSet<String>(); private static Set<String> POT_TYPES = new HashSet<String>();
@@ -0,0 +1,91 @@
/*
*
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
*
* This file is part of DIYLC.
*
* DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with DIYLC. If not, see
* <http://www.gnu.org/licenses/>.
*
*/
package org.diylc.netlist;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.swing.JLabel;
import org.diylc.common.INetlistAnalyzer;
import org.diylc.components.connectivity.MultimeterProbe;
public class MultimeterAnalyzer extends AbstractNetlistAnalyzer implements INetlistAnalyzer {
@Override
public String getName() {
return "Virtual Multimeter";
}
@Override
public String getShortName() {
return "multimeter";
}
@Override
public String getIconName() {
return "Multimeter";
}
@Override
public String getFontName() {
return new JLabel().getFont().getName();
}
protected Summary summarize(Netlist netlist, Node preferredOutput) throws TreeException {
Tree tree = constructTree(netlist);
if (tree == null) {
return new Summary(netlist, "No components found connecting the two multimeter probes.");
}
List<String> notes = new ArrayList<String>();
StringBuilder sb = new StringBuilder();
String asciiTree = tree.toAsciiString();
sb.append("<br><br>")
.append("<font face='Courier New'>")
.append(asciiTree)
.append("</font>");
if (!notes.isEmpty()) {
Collections.sort(notes);
sb.append("<br><br>");
for (String v : notes) {
sb.append(v).append("<br>");
}
}
return new Summary(netlist, sb.toString());
}
public Tree constructTree(Netlist netlist) throws TreeException {
List<Node> probeNodes = find(Set.of(MultimeterProbe.class.getCanonicalName()), null, netlist);
if (probeNodes.isEmpty()) {
throw new TreeException("No multimeter probes are placed on the circuit.");
} else if (probeNodes.size() != 2) {
throw new TreeException(
"Place exactly two multimeter probes on the circuit in order to run the analysis.");
} else {
return constructTreeBetween(netlist, probeNodes.get(0), probeNodes.get(1));
}
}
}
@@ -27,14 +27,8 @@ import java.util.stream.Collectors;
import org.diylc.common.INetlistAnalyzer; import org.diylc.common.INetlistAnalyzer;
import org.diylc.core.IDIYComponent; import org.diylc.core.IDIYComponent;
import org.diylc.netlist.Group;
import org.diylc.netlist.Netlist;
import org.diylc.netlist.NetlistAnalyzer;
import org.diylc.netlist.Node;
import org.diylc.netlist.Summary;
import org.diylc.netlist.TreeException;
public class SpiceAnalyzer extends NetlistAnalyzer implements INetlistAnalyzer { public class SpiceAnalyzer extends AbstractNetlistAnalyzer implements INetlistAnalyzer {
public SpiceAnalyzer() { public SpiceAnalyzer() {
} }
@@ -34,7 +34,7 @@ import org.diylc.netlist.Netlist;
import org.diylc.netlist.Tree; import org.diylc.netlist.Tree;
import org.diylc.netlist.TreeException; import org.diylc.netlist.TreeException;
public class GuitarNetlistAnalyzerTests { public class GuitarAbstractNetlistAnalyzerTests {
@Test @Test
public void testOneSinglePickup() throws TreeException { public void testOneSinglePickup() throws TreeException {
@@ -71,7 +71,7 @@ public enum IconLoader {
SnapToComponents("snap_to_components.png"), SnapToNone("snap_to_none.png"), TraceProximity("trace_proximity.png"), SnapToComponents("snap_to_components.png"), SnapToNone("snap_to_none.png"), TraceProximity("trace_proximity.png"),
ComponentLarge("component_large.png"), ImportNetlist("import_netlist.png"), SplashIC("splash_ic.png"), ComponentLarge("component_large.png"), ImportNetlist("import_netlist.png"), SplashIC("splash_ic.png"),
ComponentPreferences("component_preferences.png"), ComponentReplace("component_replace.png"), Barcode("barcode.png"), ComponentPreferences("component_preferences.png"), ComponentReplace("component_replace.png"), Barcode("barcode.png"),
DocumentGerber("document_gerber.png"), DocumentX2("document_x2.png"), Export("export.png"); DocumentGerber("document_gerber.png"), DocumentX2("document_x2.png"), Export("export.png"), Multimeter("multimeter.png");
protected String name; protected String name;
Binary file not shown.

After

Width:  |  Height:  |  Size: 864 B