diff --git a/.classpath b/.classpath deleted file mode 100644 index 39a9721..0000000 --- a/.classpath +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.gitignore b/.gitignore index e012f5b..8963733 100644 --- a/.gitignore +++ b/.gitignore @@ -6,12 +6,14 @@ bin target doc *.jar +.settings +.classpath # Editor specific files and folders *~ .project -# Project speicific files and folders +# Project specific files and folders *.mapfg *.mapgr *.path diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index d59e09c..0000000 --- a/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,5 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index 14b697b..0000000 --- a/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/be-graphes-algos/pom.xml b/be-graphes-algos/pom.xml new file mode 100644 index 0000000..15a8f1c --- /dev/null +++ b/be-graphes-algos/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + + org.insa.graphs + be-graphes-all + 0.0.1-SNAPSHOT + + be-graphes-algos + be-graphes-algos + http://maven.apache.org + + UTF-8 + + + + org.insa.graphs + be-graphes-model + ${project.version} + + + diff --git a/src/main/org/insa/algo/AbstractAlgorithm.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/AbstractAlgorithm.java similarity index 98% rename from src/main/org/insa/algo/AbstractAlgorithm.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/AbstractAlgorithm.java index 0b7ac32..10fe8c4 100644 --- a/src/main/org/insa/algo/AbstractAlgorithm.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/AbstractAlgorithm.java @@ -1,4 +1,4 @@ -package org.insa.algo; +package org.insa.graphs.algorithm; import java.time.Duration; import java.time.Instant; diff --git a/src/main/org/insa/algo/AbstractInputData.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/AbstractInputData.java similarity index 94% rename from src/main/org/insa/algo/AbstractInputData.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/AbstractInputData.java index d5296a5..a2a1b1f 100644 --- a/src/main/org/insa/algo/AbstractInputData.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/AbstractInputData.java @@ -1,8 +1,8 @@ -package org.insa.algo; +package org.insa.graphs.algorithm; -import org.insa.graph.Arc; -import org.insa.graph.Graph; -import org.insa.graph.GraphStatistics; +import org.insa.graphs.model.Arc; +import org.insa.graphs.model.Graph; +import org.insa.graphs.model.GraphStatistics; /** * Base class for algorithm input data classes. This class contains the basic diff --git a/src/main/org/insa/algo/AbstractSolution.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/AbstractSolution.java similarity index 95% rename from src/main/org/insa/algo/AbstractSolution.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/AbstractSolution.java index 813c04b..0d271eb 100644 --- a/src/main/org/insa/algo/AbstractSolution.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/AbstractSolution.java @@ -1,4 +1,4 @@ -package org.insa.algo; +package org.insa.graphs.algorithm; import java.time.Duration; @@ -38,6 +38,11 @@ public abstract class AbstractSolution { this.status = Status.UNKNOWN; } + /** + * + * @param data + * @param status + */ protected AbstractSolution(AbstractInputData data, Status status) { this.data = data; this.status = status; diff --git a/src/main/org/insa/algo/AlgorithmFactory.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/AlgorithmFactory.java similarity index 81% rename from src/main/org/insa/algo/AlgorithmFactory.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/AlgorithmFactory.java index 9ce8036..4dde531 100644 --- a/src/main/org/insa/algo/AlgorithmFactory.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/AlgorithmFactory.java @@ -1,4 +1,4 @@ -package org.insa.algo; +package org.insa.graphs.algorithm; import java.lang.reflect.Constructor; import java.util.IdentityHashMap; @@ -7,11 +7,11 @@ import java.util.Map; import java.util.Set; import java.util.TreeSet; -import org.insa.algo.shortestpath.AStarAlgorithm; -import org.insa.algo.shortestpath.BellmanFordAlgorithm; -import org.insa.algo.shortestpath.DijkstraAlgorithm; -import org.insa.algo.shortestpath.ShortestPathAlgorithm; -import org.insa.algo.weakconnectivity.WeaklyConnectedComponentsAlgorithm; +import org.insa.graphs.algorithm.shortestpath.AStarAlgorithm; +import org.insa.graphs.algorithm.shortestpath.BellmanFordAlgorithm; +import org.insa.graphs.algorithm.shortestpath.DijkstraAlgorithm; +import org.insa.graphs.algorithm.shortestpath.ShortestPathAlgorithm; +import org.insa.graphs.algorithm.weakconnectivity.WeaklyConnectedComponentsAlgorithm; /** * Factory class used to register and retrieve algorithms based on their common @@ -43,10 +43,10 @@ public class AlgorithmFactory { * the given base algorithm. * * @param baseAlgorithm Base algorithm class that corresponds to the newly - * registered algorithm class (e.g., generic algorithm class for the - * problem). - * @param name Name for the registered algorithm class. - * @param algoClass Algorithm class to register. + * registered algorithm class (e.g., generic algorithm + * class for the problem). + * @param name Name for the registered algorithm class. + * @param algoClass Algorithm class to register. */ public static void registerAlgorithm(Class> baseAlgorithm, String name, Class> algoClass) { @@ -62,14 +62,14 @@ public class AlgorithmFactory { * an object equivalent to `new Algorithm(data)`. * * @param algorithm Class of the algorithm to create. - * @param data Input data for the algorithm. + * @param data Input data for the algorithm. * * @return A new instance of the given algorithm class using the given data. * * @throws Exception if something wrong happens when constructing the object, - * i.e. the given input data does not correspond to the given algorithm - * and/or no constructor that takes a single parameter of type - * (data.getClass()) exists. + * i.e. the given input data does not correspond to the given + * algorithm and/or no constructor that takes a single + * parameter of type (data.getClass()) exists. */ public static AbstractAlgorithm createAlgorithm( Class> algorithm, AbstractInputData data) @@ -96,7 +96,7 @@ public class AlgorithmFactory { * registerAlgorithm. * * @param baseAlgorithm Base algorithm class for the algorithm to retrieve. - * @param name Name of the algorithm to retrieve. + * @param name Name of the algorithm to retrieve. * * @return Class corresponding to the given name. * @@ -112,7 +112,7 @@ public class AlgorithmFactory { * for the given base algorithm class. * * @param baseAlgorithm Base algorithm class for the algorithm class names to - * retrieve. + * retrieve. * * @return Names of the currently registered algorithms. * diff --git a/src/main/org/insa/algo/ArcInspector.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/ArcInspector.java similarity index 82% rename from src/main/org/insa/algo/ArcInspector.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/ArcInspector.java index 663af31..18e6f2a 100644 --- a/src/main/org/insa/algo/ArcInspector.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/ArcInspector.java @@ -1,8 +1,8 @@ -package org.insa.algo; +package org.insa.graphs.algorithm; -import org.insa.algo.AbstractInputData.Mode; -import org.insa.graph.Arc; -import org.insa.graph.GraphStatistics; +import org.insa.graphs.algorithm.AbstractInputData.Mode; +import org.insa.graphs.model.Arc; +import org.insa.graphs.model.GraphStatistics; /** * This class can be used to indicate to an algorithm which arcs can be used and diff --git a/src/main/org/insa/algo/ArcInspectorFactory.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/ArcInspectorFactory.java similarity index 94% rename from src/main/org/insa/algo/ArcInspectorFactory.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/ArcInspectorFactory.java index aa1f8f7..d43df60 100644 --- a/src/main/org/insa/algo/ArcInspectorFactory.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/ArcInspectorFactory.java @@ -1,14 +1,14 @@ -package org.insa.algo; +package org.insa.graphs.algorithm; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; -import org.insa.algo.AbstractInputData.Mode; -import org.insa.graph.AccessRestrictions.AccessMode; -import org.insa.graph.AccessRestrictions.AccessRestriction; -import org.insa.graph.Arc; -import org.insa.graph.GraphStatistics; +import org.insa.graphs.algorithm.AbstractInputData.Mode; +import org.insa.graphs.model.Arc; +import org.insa.graphs.model.GraphStatistics; +import org.insa.graphs.model.AccessRestrictions.AccessMode; +import org.insa.graphs.model.AccessRestrictions.AccessRestriction; public class ArcInspectorFactory { diff --git a/src/main/org/insa/algo/carpooling/CarPoolingAlgorithm.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/carpooling/CarPoolingAlgorithm.java similarity index 82% rename from src/main/org/insa/algo/carpooling/CarPoolingAlgorithm.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/carpooling/CarPoolingAlgorithm.java index 36f7a04..a895e38 100644 --- a/src/main/org/insa/algo/carpooling/CarPoolingAlgorithm.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/carpooling/CarPoolingAlgorithm.java @@ -1,6 +1,6 @@ -package org.insa.algo.carpooling; +package org.insa.graphs.algorithm.carpooling; -import org.insa.algo.AbstractAlgorithm; +import org.insa.graphs.algorithm.AbstractAlgorithm; public abstract class CarPoolingAlgorithm extends AbstractAlgorithm { diff --git a/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/carpooling/CarPoolingData.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/carpooling/CarPoolingData.java new file mode 100644 index 0000000..d281f72 --- /dev/null +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/carpooling/CarPoolingData.java @@ -0,0 +1,13 @@ +package org.insa.graphs.algorithm.carpooling; + +import org.insa.graphs.algorithm.AbstractInputData; +import org.insa.graphs.algorithm.ArcInspector; +import org.insa.graphs.model.Graph; + +public class CarPoolingData extends AbstractInputData { + + protected CarPoolingData(Graph graph, ArcInspector arcFilter) { + super(graph, arcFilter); + } + +} diff --git a/src/main/org/insa/algo/carpooling/CarPoolingGraphicObserver.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/carpooling/CarPoolingGraphicObserver.java similarity index 61% rename from src/main/org/insa/algo/carpooling/CarPoolingGraphicObserver.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/carpooling/CarPoolingGraphicObserver.java index a0ee5d9..eaffac6 100644 --- a/src/main/org/insa/algo/carpooling/CarPoolingGraphicObserver.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/carpooling/CarPoolingGraphicObserver.java @@ -1,4 +1,4 @@ -package org.insa.algo.carpooling; +package org.insa.graphs.algorithm.carpooling; public class CarPoolingGraphicObserver implements CarPoolingObserver { diff --git a/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/carpooling/CarPoolingObserver.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/carpooling/CarPoolingObserver.java new file mode 100644 index 0000000..7726e92 --- /dev/null +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/carpooling/CarPoolingObserver.java @@ -0,0 +1,5 @@ +package org.insa.graphs.algorithm.carpooling; + +public interface CarPoolingObserver { + +} diff --git a/src/main/org/insa/algo/carpooling/CarPoolingSolution.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/carpooling/CarPoolingSolution.java similarity index 63% rename from src/main/org/insa/algo/carpooling/CarPoolingSolution.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/carpooling/CarPoolingSolution.java index 07efa75..701c47b 100644 --- a/src/main/org/insa/algo/carpooling/CarPoolingSolution.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/carpooling/CarPoolingSolution.java @@ -1,6 +1,6 @@ -package org.insa.algo.carpooling; +package org.insa.graphs.algorithm.carpooling; -import org.insa.algo.AbstractSolution; +import org.insa.graphs.algorithm.AbstractSolution; public class CarPoolingSolution extends AbstractSolution { diff --git a/src/main/org/insa/algo/carpooling/CarPoolingTextObserver.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/carpooling/CarPoolingTextObserver.java similarity index 61% rename from src/main/org/insa/algo/carpooling/CarPoolingTextObserver.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/carpooling/CarPoolingTextObserver.java index 386664e..0327a95 100644 --- a/src/main/org/insa/algo/carpooling/CarPoolingTextObserver.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/carpooling/CarPoolingTextObserver.java @@ -1,4 +1,4 @@ -package org.insa.algo.carpooling; +package org.insa.graphs.algorithm.carpooling; public class CarPoolingTextObserver implements CarPoolingObserver { diff --git a/src/main/org/insa/algo/packageswitch/PackageSwitchAlgorithm.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/packageswitch/PackageSwitchAlgorithm.java similarity index 85% rename from src/main/org/insa/algo/packageswitch/PackageSwitchAlgorithm.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/packageswitch/PackageSwitchAlgorithm.java index 76d4786..191e927 100644 --- a/src/main/org/insa/algo/packageswitch/PackageSwitchAlgorithm.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/packageswitch/PackageSwitchAlgorithm.java @@ -1,6 +1,6 @@ -package org.insa.algo.packageswitch; +package org.insa.graphs.algorithm.packageswitch; -import org.insa.algo.AbstractAlgorithm; +import org.insa.graphs.algorithm.AbstractAlgorithm; public abstract class PackageSwitchAlgorithm extends AbstractAlgorithm { diff --git a/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/packageswitch/PackageSwitchData.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/packageswitch/PackageSwitchData.java new file mode 100644 index 0000000..cc9e6d5 --- /dev/null +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/packageswitch/PackageSwitchData.java @@ -0,0 +1,13 @@ +package org.insa.graphs.algorithm.packageswitch; + +import org.insa.graphs.algorithm.AbstractInputData; +import org.insa.graphs.algorithm.ArcInspector; +import org.insa.graphs.model.Graph; + +public class PackageSwitchData extends AbstractInputData { + + protected PackageSwitchData(Graph graph, ArcInspector arcFilter) { + super(graph, arcFilter); + } + +} diff --git a/src/main/org/insa/algo/packageswitch/PackageSwitchGraphicObserver.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/packageswitch/PackageSwitchGraphicObserver.java similarity index 62% rename from src/main/org/insa/algo/packageswitch/PackageSwitchGraphicObserver.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/packageswitch/PackageSwitchGraphicObserver.java index 1750ae6..6b4af91 100644 --- a/src/main/org/insa/algo/packageswitch/PackageSwitchGraphicObserver.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/packageswitch/PackageSwitchGraphicObserver.java @@ -1,4 +1,4 @@ -package org.insa.algo.packageswitch; +package org.insa.graphs.algorithm.packageswitch; public class PackageSwitchGraphicObserver implements PackageSwitchObserver { diff --git a/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/packageswitch/PackageSwitchObserver.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/packageswitch/PackageSwitchObserver.java new file mode 100644 index 0000000..c7313b7 --- /dev/null +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/packageswitch/PackageSwitchObserver.java @@ -0,0 +1,5 @@ +package org.insa.graphs.algorithm.packageswitch; + +public interface PackageSwitchObserver { + +} diff --git a/src/main/org/insa/algo/packageswitch/PackageSwitchSolution.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/packageswitch/PackageSwitchSolution.java similarity index 64% rename from src/main/org/insa/algo/packageswitch/PackageSwitchSolution.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/packageswitch/PackageSwitchSolution.java index 5fa2f07..93562bb 100644 --- a/src/main/org/insa/algo/packageswitch/PackageSwitchSolution.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/packageswitch/PackageSwitchSolution.java @@ -1,6 +1,6 @@ -package org.insa.algo.packageswitch; +package org.insa.graphs.algorithm.packageswitch; -import org.insa.algo.AbstractSolution; +import org.insa.graphs.algorithm.AbstractSolution; public class PackageSwitchSolution extends AbstractSolution { diff --git a/src/main/org/insa/algo/packageswitch/PackageSwitchTextObserver.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/packageswitch/PackageSwitchTextObserver.java similarity index 61% rename from src/main/org/insa/algo/packageswitch/PackageSwitchTextObserver.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/packageswitch/PackageSwitchTextObserver.java index ba5b584..d0225d5 100644 --- a/src/main/org/insa/algo/packageswitch/PackageSwitchTextObserver.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/packageswitch/PackageSwitchTextObserver.java @@ -1,4 +1,4 @@ -package org.insa.algo.packageswitch; +package org.insa.graphs.algorithm.packageswitch; public class PackageSwitchTextObserver implements PackageSwitchObserver { diff --git a/src/main/org/insa/algo/shortestpath/AStarAlgorithm.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/AStarAlgorithm.java similarity index 74% rename from src/main/org/insa/algo/shortestpath/AStarAlgorithm.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/AStarAlgorithm.java index 4b12c24..fd172f0 100644 --- a/src/main/org/insa/algo/shortestpath/AStarAlgorithm.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/AStarAlgorithm.java @@ -1,4 +1,4 @@ -package org.insa.algo.shortestpath; +package org.insa.graphs.algorithm.shortestpath; public class AStarAlgorithm extends DijkstraAlgorithm { diff --git a/src/main/org/insa/algo/shortestpath/BellmanFordAlgorithm.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/BellmanFordAlgorithm.java similarity index 92% rename from src/main/org/insa/algo/shortestpath/BellmanFordAlgorithm.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/BellmanFordAlgorithm.java index 666d5c8..42986aa 100644 --- a/src/main/org/insa/algo/shortestpath/BellmanFordAlgorithm.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/BellmanFordAlgorithm.java @@ -1,14 +1,14 @@ -package org.insa.algo.shortestpath; +package org.insa.graphs.algorithm.shortestpath; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import org.insa.algo.AbstractSolution.Status; -import org.insa.graph.Arc; -import org.insa.graph.Graph; -import org.insa.graph.Node; -import org.insa.graph.Path; +import org.insa.graphs.algorithm.AbstractSolution.Status; +import org.insa.graphs.model.Arc; +import org.insa.graphs.model.Graph; +import org.insa.graphs.model.Node; +import org.insa.graphs.model.Path; public class BellmanFordAlgorithm extends ShortestPathAlgorithm { diff --git a/src/main/org/insa/algo/shortestpath/DijkstraAlgorithm.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/DijkstraAlgorithm.java similarity index 74% rename from src/main/org/insa/algo/shortestpath/DijkstraAlgorithm.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/DijkstraAlgorithm.java index 4f84150..bacb8e3 100644 --- a/src/main/org/insa/algo/shortestpath/DijkstraAlgorithm.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/DijkstraAlgorithm.java @@ -1,4 +1,4 @@ -package org.insa.algo.shortestpath; +package org.insa.graphs.algorithm.shortestpath; public class DijkstraAlgorithm extends ShortestPathAlgorithm { @@ -8,7 +8,7 @@ public class DijkstraAlgorithm extends ShortestPathAlgorithm { @Override protected ShortestPathSolution doRun() { - ShortestPathData data = getInputData(); + final ShortestPathData data = getInputData(); ShortestPathSolution solution = null; // TODO: return solution; diff --git a/src/main/org/insa/algo/shortestpath/ShortestPathAlgorithm.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ShortestPathAlgorithm.java similarity index 92% rename from src/main/org/insa/algo/shortestpath/ShortestPathAlgorithm.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ShortestPathAlgorithm.java index 6890a0e..005e40c 100644 --- a/src/main/org/insa/algo/shortestpath/ShortestPathAlgorithm.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ShortestPathAlgorithm.java @@ -1,7 +1,7 @@ -package org.insa.algo.shortestpath; +package org.insa.graphs.algorithm.shortestpath; -import org.insa.algo.AbstractAlgorithm; -import org.insa.graph.Node; +import org.insa.graphs.algorithm.AbstractAlgorithm; +import org.insa.graphs.model.Node; public abstract class ShortestPathAlgorithm extends AbstractAlgorithm { diff --git a/src/main/org/insa/algo/shortestpath/ShortestPathData.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ShortestPathData.java similarity index 84% rename from src/main/org/insa/algo/shortestpath/ShortestPathData.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ShortestPathData.java index e0c453a..7b3d014 100644 --- a/src/main/org/insa/algo/shortestpath/ShortestPathData.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ShortestPathData.java @@ -1,9 +1,9 @@ -package org.insa.algo.shortestpath; +package org.insa.graphs.algorithm.shortestpath; -import org.insa.algo.AbstractInputData; -import org.insa.algo.ArcInspector; -import org.insa.graph.Graph; -import org.insa.graph.Node; +import org.insa.graphs.algorithm.AbstractInputData; +import org.insa.graphs.algorithm.ArcInspector; +import org.insa.graphs.model.Graph; +import org.insa.graphs.model.Node; public class ShortestPathData extends AbstractInputData { diff --git a/src/main/org/insa/algo/shortestpath/ShortestPathObserver.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ShortestPathObserver.java similarity index 89% rename from src/main/org/insa/algo/shortestpath/ShortestPathObserver.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ShortestPathObserver.java index 8d9c8e0..d56d2dc 100644 --- a/src/main/org/insa/algo/shortestpath/ShortestPathObserver.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ShortestPathObserver.java @@ -1,6 +1,6 @@ -package org.insa.algo.shortestpath; +package org.insa.graphs.algorithm.shortestpath; -import org.insa.graph.Node; +import org.insa.graphs.model.Node; public interface ShortestPathObserver { diff --git a/src/main/org/insa/algo/shortestpath/ShortestPathSolution.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ShortestPathSolution.java similarity index 86% rename from src/main/org/insa/algo/shortestpath/ShortestPathSolution.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ShortestPathSolution.java index 3cb8c31..9122ac4 100644 --- a/src/main/org/insa/algo/shortestpath/ShortestPathSolution.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ShortestPathSolution.java @@ -1,21 +1,14 @@ -package org.insa.algo.shortestpath; +package org.insa.graphs.algorithm.shortestpath; -import org.insa.algo.AbstractInputData.Mode; -import org.insa.algo.AbstractSolution; -import org.insa.graph.Arc; -import org.insa.graph.Path; +import org.insa.graphs.algorithm.AbstractInputData.Mode; +import org.insa.graphs.model.Arc; +import org.insa.graphs.model.Path; +import org.insa.graphs.algorithm.AbstractSolution; public class ShortestPathSolution extends AbstractSolution { // Optimal solution. - private Path path; - - /** - * {@inheritDoc} - */ - public ShortestPathSolution(ShortestPathData data) { - super(data); - } + private final Path path; /** * Create a new infeasible shortest-path solution for the given input and @@ -26,6 +19,7 @@ public class ShortestPathSolution extends AbstractSolution { */ public ShortestPathSolution(ShortestPathData data, Status status) { super(data, status); + this.path = null; } /** diff --git a/src/main/org/insa/algo/shortestpath/ShortestPathTextObserver.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ShortestPathTextObserver.java similarity index 89% rename from src/main/org/insa/algo/shortestpath/ShortestPathTextObserver.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ShortestPathTextObserver.java index d2a08fd..e74cc0a 100644 --- a/src/main/org/insa/algo/shortestpath/ShortestPathTextObserver.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/shortestpath/ShortestPathTextObserver.java @@ -1,8 +1,8 @@ -package org.insa.algo.shortestpath; +package org.insa.graphs.algorithm.shortestpath; import java.io.PrintStream; -import org.insa.graph.Node; +import org.insa.graphs.model.Node; public class ShortestPathTextObserver implements ShortestPathObserver { diff --git a/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/utils/BinaryHeap.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/utils/BinaryHeap.java new file mode 100644 index 0000000..2c1a239 --- /dev/null +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/utils/BinaryHeap.java @@ -0,0 +1,205 @@ +package org.insa.graphs.algorithm.utils; + +import java.util.ArrayList; + +/** + * Implements a binary heap containing elements of type E. + * + * Note that all comparisons are based on the compareTo method, hence E must + * implement Comparable + * + * @author Mark Allen Weiss + * @author DLB + */ +public class BinaryHeap> implements PriorityQueue { + + // Number of elements in heap. + private int currentSize; + + // The heap array. + protected final ArrayList array; + + /** + * Construct a new empty binary heap. + */ + public BinaryHeap() { + this.currentSize = 0; + this.array = new ArrayList(); + } + + /** + * Construct a copy of the given heap. + * + * @param heap Binary heap to copy. + */ + public BinaryHeap(BinaryHeap heap) { + this.currentSize = heap.currentSize; + this.array = new ArrayList(heap.array); + } + + /** + * Set an element at the given index. + * + * @param index Index at which the element should be set. + * @param value Element to set. + */ + private void arraySet(int index, E value) { + if (index == this.array.size()) { + this.array.add(value); + } + else { + this.array.set(index, value); + } + } + + /** + * @return Index of the parent of the given index. + */ + protected int indexParent(int index) { + return (index - 1) / 2; + } + + /** + * @return Index of the left child of the given index. + */ + protected int indexLeft(int index) { + return index * 2 + 1; + } + + /** + * Internal method to percolate up in the heap. + * + * @param index Index at which the percolate begins. + */ + private void percolateUp(int index) { + E x = this.array.get(index); + + for (; index > 0 + && x.compareTo(this.array.get(indexParent(index))) < 0; index = indexParent( + index)) { + E moving_val = this.array.get(indexParent(index)); + this.arraySet(index, moving_val); + } + + this.arraySet(index, x); + } + + /** + * Internal method to percolate down in the heap. + * + * @param index Index at which the percolate begins. + */ + private void percolateDown(int index) { + int ileft = indexLeft(index); + int iright = ileft + 1; + + if (ileft < this.currentSize) { + E current = this.array.get(index); + E left = this.array.get(ileft); + boolean hasRight = iright < this.currentSize; + E right = (hasRight) ? this.array.get(iright) : null; + + if (!hasRight || left.compareTo(right) < 0) { + // Left is smaller + if (left.compareTo(current) < 0) { + this.arraySet(index, left); + this.arraySet(ileft, current); + this.percolateDown(ileft); + } + } + else { + // Right is smaller + if (right.compareTo(current) < 0) { + this.arraySet(index, right); + this.arraySet(iright, current); + this.percolateDown(iright); + } + } + } + } + + @Override + public boolean isEmpty() { + return this.currentSize == 0; + } + + @Override + public int size() { + return this.currentSize; + } + + @Override + public void insert(E x) { + int index = this.currentSize++; + this.arraySet(index, x); + this.percolateUp(index); + } + + @Override + public void remove(E x) throws ElementNotFoundException { + // TODO: + } + + @Override + public E findMin() throws EmptyPriorityQueueException { + if (isEmpty()) + throw new EmptyPriorityQueueException(); + return this.array.get(0); + } + + @Override + public E deleteMin() throws EmptyPriorityQueueException { + E minItem = findMin(); + E lastItem = this.array.get(--this.currentSize); + this.arraySet(0, lastItem); + this.percolateDown(0); + return minItem; + } + + /** + * Creates a multi-lines string representing a sorted view of this binary heap. + * + * @return a string containing a sorted view this binary heap. + */ + public String toStringSorted() { + return BinaryHeapFormatter.toStringSorted(this, -1); + } + + /** + * Creates a multi-lines string representing a sorted view of this binary heap. + * + * @param maxElement Maximum number of elements to display. or {@code -1} to + * display all the elements. + * + * @return a string containing a sorted view this binary heap. + */ + public String toStringSorted(int maxElement) { + return BinaryHeapFormatter.toStringSorted(this, maxElement); + } + + /** + * Creates a multi-lines string representing a tree view of this binary heap. + * + * @return a string containing a tree view of this binary heap. + */ + public String toStringTree() { + return BinaryHeapFormatter.toStringTree(this, Integer.MAX_VALUE); + } + + /** + * Creates a multi-lines string representing a tree view of this binary heap. + * + * @param maxDepth Maximum depth of the tree to display. + * + * @return a string containing a tree view of this binary heap. + */ + public String toStringTree(int maxDepth) { + return BinaryHeapFormatter.toStringTree(this, maxDepth); + } + + @Override + public String toString() { + return BinaryHeapFormatter.toStringTree(this, 8); + } + +} diff --git a/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/utils/BinaryHeapFormatter.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/utils/BinaryHeapFormatter.java new file mode 100644 index 0000000..adad622 --- /dev/null +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/utils/BinaryHeapFormatter.java @@ -0,0 +1,198 @@ +package org.insa.graphs.algorithm.utils; + +import java.util.ArrayList; + +public class BinaryHeapFormatter { + + /** + * This class is used by {@link #toStringTree}, and simply contains three string + * accumulating. This is an immutable class. + * + */ + private static class Context { + + // Output text: + public final String acu; + + // Margin to get back exactly under the current position: + public final String margin; + + // Last margin used for the last child of a node. The markers are different: + public final String lastmargin; + + /** + * Creaet a new {@code Context}. + * + * @param acu The accumulated string. + * @param margin The current margin. + * @param lastMargin The last margin used. + */ + public Context(String acu, String margin, String lastMargin) { + this.acu = acu; + this.margin = margin; + this.lastmargin = lastMargin; + } + + /** + * Creates a new context by appending newlines to this context. + * + * @param n Number of newlines to append. + * + * @return a new context with {@code n} newlines appended. + */ + public Context appendNewlines(int n) { + if (n <= 0) { + return this; + } + else { + return (new Context(this.acu + "\n" + this.margin, this.margin, this.lastmargin) + .appendNewlines(n - 1)); + } + } + + /** + * Creates a new context by appending the given string to this context. + * + * @param count Number of spaces to add to the margin, or {@code null} to use + * the length of the string. + * @param text String to append. + * + * @return a new context with {@code text} appended. + */ + public Context appendText(Integer count, String text) { + int cnt = (count == null) ? text.length() : count; + final String spaces = new String(new char[cnt]).replace('\0', ' '); + return new Context(this.acu + text, this.margin + spaces, this.lastmargin + spaces); + } + + /** + * Creates a new context by appending a branch to this context. + * + * @param n Number of spaces to add to the margin, or {@code null} to use + * the length of the string. + * @param label Name of the branch. + * + * @return a new context with the branch appended. + */ + public Context appendBranch(Integer count, String label) { + final Context ctxt = this.appendText(count, label); + + if (count == null) { + return new Context(ctxt.acu + "_", ctxt.margin + "|", ctxt.margin + " "); + } + else { + return new Context(ctxt.acu, ctxt.margin + "|", ctxt.margin + " ") + .appendNewlines(1); + + } + } + } + + /* + * Input : ready to write the current node at the current context position. + * Output : the last character of acu is the last character of the current node. + */ + protected static > Context toStringLoop(BinaryHeap heap, + Context ctxt, int node, int max_depth) { + + if (max_depth < 0) { + return ctxt.appendText(null, "..."); + } + else { + E nodeval = heap.array.get(node); + String nodevals = nodeval.toString(); + + ArrayList childs = new ArrayList(); + // Add childs + int index_left = heap.indexLeft(node); + int index_right = index_left + 1; + + if (index_left < heap.size()) { + childs.add(index_left); + } + if (index_right < heap.size()) { + childs.add(index_right); + } + + Context ctxt2 = childs.isEmpty() ? ctxt.appendText(null, nodevals) + : ctxt.appendBranch(1, nodevals); + + for (int ch = 0; ch < childs.size(); ch++) { + boolean is_last = (ch == childs.size() - 1); + int child = childs.get(ch); + + if (is_last) { + Context ctxt3 = new Context(ctxt2.acu, ctxt2.lastmargin, ctxt2.lastmargin); + ctxt2 = new Context(toStringLoop(heap, ctxt3.appendText(null, "___"), child, + max_depth - 1).acu, ctxt2.margin, ctxt2.lastmargin); + } + else { + ctxt2 = new Context(toStringLoop(heap, ctxt2.appendText(null, "___"), child, + max_depth - 1).acu, ctxt2.margin, ctxt2.lastmargin).appendNewlines(2); + } + } + + return ctxt2; + } + } + + /** + * Creates a multi-lines string representing a tree view of the given binary + * heap. + * + * @param heap The binary heap to display. + * @param maxDepth Maximum depth of the tree to display. + * + * @return a string containing a tree view of the given binary heap. + */ + public static > String toStringTree(BinaryHeap heap, int maxDepth) { + final Context init_context = new Context(" ", " ", " "); + final Context result = toStringLoop(heap, init_context, 0, maxDepth); + return result.acu; + } + + /** + * Creates a multi-lines string representing a sorted view of the given binary + * heap. + * + * @param heap The binary heap to display. + * @param maxElement Maximum number of elements to display. or {@code -1} to + * display all the elements. + * + * @return a string containing a sorted view the given binary heap. + */ + public static > String toStringSorted(BinaryHeap heap, + int max_elements) { + String result = ""; + final BinaryHeap copy = new BinaryHeap(heap); + + final String truncate; + if (max_elements < 0 || max_elements >= heap.size()) { + truncate = ""; + } + else { + truncate = ", only " + max_elements + " elements are shown"; + } + + result += "======== Sorted HEAP (size = " + heap.size() + truncate + ") ========\n\n"; + + while (!copy.isEmpty() && max_elements-- != 0) { + result += copy.deleteMin() + "\n"; + } + + result += "\n-------- End of heap --------"; + + return result; + } + + public static void main(String[] args) { + final BinaryHeap heap = new BinaryHeap(); + + for (int i = 0; i < 12; i++) { + heap.insert(i); + } + + System.out.println(heap.toStringSorted(-1)); + System.out.println(heap.toStringTree(6)); + } +} diff --git a/src/main/org/insa/algo/utils/BinarySearchTree.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/utils/BinarySearchTree.java similarity index 97% rename from src/main/org/insa/algo/utils/BinarySearchTree.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/utils/BinarySearchTree.java index 775257b..32dfbb1 100644 --- a/src/main/org/insa/algo/utils/BinarySearchTree.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/utils/BinarySearchTree.java @@ -1,4 +1,4 @@ -package org.insa.algo.utils; +package org.insa.graphs.algorithm.utils; import java.util.SortedSet; import java.util.TreeSet; diff --git a/src/main/org/insa/algo/utils/ElementNotFoundException.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/utils/ElementNotFoundException.java similarity index 93% rename from src/main/org/insa/algo/utils/ElementNotFoundException.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/utils/ElementNotFoundException.java index 7f2be3c..3fb2729 100644 --- a/src/main/org/insa/algo/utils/ElementNotFoundException.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/utils/ElementNotFoundException.java @@ -1,4 +1,4 @@ -package org.insa.algo.utils; +package org.insa.graphs.algorithm.utils; public class ElementNotFoundException extends RuntimeException { diff --git a/src/main/org/insa/algo/utils/EmptyPriorityQueueException.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/utils/EmptyPriorityQueueException.java similarity index 84% rename from src/main/org/insa/algo/utils/EmptyPriorityQueueException.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/utils/EmptyPriorityQueueException.java index 1dc4877..bf09c5d 100644 --- a/src/main/org/insa/algo/utils/EmptyPriorityQueueException.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/utils/EmptyPriorityQueueException.java @@ -1,4 +1,4 @@ -package org.insa.algo.utils; +package org.insa.graphs.algorithm.utils; public class EmptyPriorityQueueException extends RuntimeException { diff --git a/src/main/org/insa/algo/utils/PriorityQueue.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/utils/PriorityQueue.java similarity index 97% rename from src/main/org/insa/algo/utils/PriorityQueue.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/utils/PriorityQueue.java index 4f5bd25..104f79e 100644 --- a/src/main/org/insa/algo/utils/PriorityQueue.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/utils/PriorityQueue.java @@ -1,4 +1,4 @@ -package org.insa.algo.utils; +package org.insa.graphs.algorithm.utils; /** * Interface representing a basic priority queue. diff --git a/src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentObserver.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/weakconnectivity/WeaklyConnectedComponentObserver.java similarity index 88% rename from src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentObserver.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/weakconnectivity/WeaklyConnectedComponentObserver.java index 9347af6..e7b0a5a 100644 --- a/src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentObserver.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/weakconnectivity/WeaklyConnectedComponentObserver.java @@ -1,8 +1,8 @@ -package org.insa.algo.weakconnectivity; +package org.insa.graphs.algorithm.weakconnectivity; import java.util.ArrayList; -import org.insa.graph.Node; +import org.insa.graphs.model.Node; public interface WeaklyConnectedComponentObserver { diff --git a/src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentTextObserver.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/weakconnectivity/WeaklyConnectedComponentTextObserver.java similarity index 89% rename from src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentTextObserver.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/weakconnectivity/WeaklyConnectedComponentTextObserver.java index 0c4eaf6..1a725c7 100644 --- a/src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentTextObserver.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/weakconnectivity/WeaklyConnectedComponentTextObserver.java @@ -1,9 +1,9 @@ -package org.insa.algo.weakconnectivity; +package org.insa.graphs.algorithm.weakconnectivity; import java.io.PrintStream; import java.util.ArrayList; -import org.insa.graph.Node; +import org.insa.graphs.model.Node; public class WeaklyConnectedComponentTextObserver implements WeaklyConnectedComponentObserver { diff --git a/src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentsAlgorithm.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/weakconnectivity/WeaklyConnectedComponentsAlgorithm.java similarity index 94% rename from src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentsAlgorithm.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/weakconnectivity/WeaklyConnectedComponentsAlgorithm.java index 83f8946..42462bb 100644 --- a/src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentsAlgorithm.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/weakconnectivity/WeaklyConnectedComponentsAlgorithm.java @@ -1,4 +1,4 @@ -package org.insa.algo.weakconnectivity; +package org.insa.graphs.algorithm.weakconnectivity; import java.util.ArrayList; import java.util.Arrays; @@ -6,11 +6,11 @@ import java.util.HashSet; import java.util.LinkedList; import java.util.Queue; -import org.insa.algo.AbstractAlgorithm; -import org.insa.algo.AbstractSolution.Status; -import org.insa.graph.Arc; -import org.insa.graph.Graph; -import org.insa.graph.Node; +import org.insa.graphs.algorithm.AbstractAlgorithm; +import org.insa.graphs.algorithm.AbstractSolution.Status; +import org.insa.graphs.model.Arc; +import org.insa.graphs.model.Graph; +import org.insa.graphs.model.Node; public class WeaklyConnectedComponentsAlgorithm extends AbstractAlgorithm { diff --git a/src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentsData.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/weakconnectivity/WeaklyConnectedComponentsData.java similarity index 71% rename from src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentsData.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/weakconnectivity/WeaklyConnectedComponentsData.java index f64819b..553a40b 100644 --- a/src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentsData.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/weakconnectivity/WeaklyConnectedComponentsData.java @@ -1,7 +1,7 @@ -package org.insa.algo.weakconnectivity; +package org.insa.graphs.algorithm.weakconnectivity; -import org.insa.algo.AbstractInputData; -import org.insa.graph.Graph; +import org.insa.graphs.algorithm.AbstractInputData; +import org.insa.graphs.model.Graph; public class WeaklyConnectedComponentsData extends AbstractInputData { diff --git a/src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentsSolution.java b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/weakconnectivity/WeaklyConnectedComponentsSolution.java similarity index 91% rename from src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentsSolution.java rename to be-graphes-algos/src/main/java/org/insa/graphs/algorithm/weakconnectivity/WeaklyConnectedComponentsSolution.java index dae8530..a0b2d4a 100644 --- a/src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentsSolution.java +++ b/be-graphes-algos/src/main/java/org/insa/graphs/algorithm/weakconnectivity/WeaklyConnectedComponentsSolution.java @@ -1,9 +1,9 @@ -package org.insa.algo.weakconnectivity; +package org.insa.graphs.algorithm.weakconnectivity; import java.util.ArrayList; -import org.insa.algo.AbstractSolution; -import org.insa.graph.Node; +import org.insa.graphs.algorithm.AbstractSolution; +import org.insa.graphs.model.Node; public class WeaklyConnectedComponentsSolution extends AbstractSolution { diff --git a/src/test/org/insa/algo/utils/BinaryHeapTest.java b/be-graphes-algos/src/test/java/org/insa/graphs/algorithm/utils/BinaryHeapTest.java similarity index 89% rename from src/test/org/insa/algo/utils/BinaryHeapTest.java rename to be-graphes-algos/src/test/java/org/insa/graphs/algorithm/utils/BinaryHeapTest.java index 60b046b..df91636 100644 --- a/src/test/org/insa/algo/utils/BinaryHeapTest.java +++ b/be-graphes-algos/src/test/java/org/insa/graphs/algorithm/utils/BinaryHeapTest.java @@ -1,4 +1,4 @@ -package org.insa.algo.utils; +package org.insa.graphs.algorithm.utils; public class BinaryHeapTest extends PriorityQueueTest { diff --git a/src/test/org/insa/algo/utils/BinarySearchTreeTest.java b/be-graphes-algos/src/test/java/org/insa/graphs/algorithm/utils/BinarySearchTreeTest.java similarity index 90% rename from src/test/org/insa/algo/utils/BinarySearchTreeTest.java rename to be-graphes-algos/src/test/java/org/insa/graphs/algorithm/utils/BinarySearchTreeTest.java index e4c351b..803846d 100644 --- a/src/test/org/insa/algo/utils/BinarySearchTreeTest.java +++ b/be-graphes-algos/src/test/java/org/insa/graphs/algorithm/utils/BinarySearchTreeTest.java @@ -1,4 +1,4 @@ -package org.insa.algo.utils; +package org.insa.graphs.algorithm.utils; public class BinarySearchTreeTest extends PriorityQueueTest { diff --git a/src/test/org/insa/algo/utils/PriorityQueueTest.java b/be-graphes-algos/src/test/java/org/insa/graphs/algorithm/utils/PriorityQueueTest.java similarity index 99% rename from src/test/org/insa/algo/utils/PriorityQueueTest.java rename to be-graphes-algos/src/test/java/org/insa/graphs/algorithm/utils/PriorityQueueTest.java index 63f2bff..c796598 100644 --- a/src/test/org/insa/algo/utils/PriorityQueueTest.java +++ b/be-graphes-algos/src/test/java/org/insa/graphs/algorithm/utils/PriorityQueueTest.java @@ -1,4 +1,4 @@ -package org.insa.algo.utils; +package org.insa.graphs.algorithm.utils; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; diff --git a/be-graphes-gui/pom.xml b/be-graphes-gui/pom.xml new file mode 100644 index 0000000..a1dae40 --- /dev/null +++ b/be-graphes-gui/pom.xml @@ -0,0 +1,84 @@ + + + 4.0.0 + + org.insa.graphs + be-graphes-all + 0.0.1-SNAPSHOT + + + + 0.13.0 + + + be-graphes-gui + be-graphes-gui + + + + jitpack.io + https://jitpack.io + + + + + + org.insa.graphs + be-graphes-model + ${project.version} + + + org.insa.graphs + be-graphes-algos + ${project.version} + + + + + net.sf.kxml + kxml2 + 2.3.0 + + + + + org.mapsforge + mapsforge-themes + ${mapsforge.version} + + + + + org.mapsforge + mapsforge-map + ${mapsforge.version} + + + + + org.mapsforge + mapsforge-map-awt + ${mapsforge.version} + + + + + org.mapsforge + mapsforge-themes + ${mapsforge.version} + + + + + org.mapsforge + mapsforge-map-reader + ${mapsforge.version} + + + + + + diff --git a/src/main/org/insa/graphics/AlgorithmPanel.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/AlgorithmPanel.java similarity index 93% rename from src/main/org/insa/graphics/AlgorithmPanel.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/AlgorithmPanel.java index b1e7532..75da459 100644 --- a/src/main/org/insa/graphics/AlgorithmPanel.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/AlgorithmPanel.java @@ -1,4 +1,4 @@ -package org.insa.graphics; +package org.insa.graphs.gui; import java.awt.Color; import java.awt.Component; @@ -22,15 +22,14 @@ import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; -import org.insa.algo.AbstractAlgorithm; -import org.insa.algo.AlgorithmFactory; -import org.insa.algo.ArcInspector; -import org.insa.algo.ArcInspectorFactory; -import org.insa.graph.Node; -import org.insa.graphics.NodesInputPanel.InputChangedEvent; -import org.insa.graphics.drawing.Drawing; -import org.insa.graphics.drawing.components.MapViewDrawing; -import org.insa.graphics.utils.ColorUtils; +import org.insa.graphs.algorithm.AbstractAlgorithm; +import org.insa.graphs.algorithm.AlgorithmFactory; +import org.insa.graphs.algorithm.ArcInspector; +import org.insa.graphs.algorithm.ArcInspectorFactory; +import org.insa.graphs.gui.NodesInputPanel.InputChangedEvent; +import org.insa.graphs.gui.drawing.Drawing; +import org.insa.graphs.gui.utils.ColorUtils; +import org.insa.graphs.model.Node; public class AlgorithmPanel extends JPanel implements DrawingChangeListener { @@ -118,9 +117,6 @@ public class AlgorithmPanel extends JPanel implements DrawingChangeListener { // Graphic / Text checkbox observer private final JCheckBox graphicObserverCheckbox, textualObserverCheckbox; - // Drawing - private Drawing drawing = null; - private JButton startAlgoButton; // Start listeners @@ -360,7 +356,7 @@ public class AlgorithmPanel extends JPanel implements DrawingChangeListener { for (JComponent component: components) { component.setEnabled(enabled); } - graphicObserverCheckbox.setEnabled(enabled && !(drawing instanceof MapViewDrawing)); + graphicObserverCheckbox.setEnabled(enabled); enabled = enabled && allNotNull(this.nodesInputPanel.getNodeForInputs()); startAlgoButton.setEnabled(enabled); } @@ -376,15 +372,6 @@ public class AlgorithmPanel extends JPanel implements DrawingChangeListener { @Override public void onDrawingLoaded(Drawing oldDrawing, Drawing newDrawing) { - if (newDrawing instanceof MapViewDrawing) { - graphicObserverCheckbox.setSelected(false); - graphicObserverCheckbox.setEnabled(false); - } - else { - graphicObserverCheckbox.setSelected(true); - graphicObserverCheckbox.setEnabled(true); - } - this.drawing = newDrawing; } @Override diff --git a/src/main/org/insa/graphics/BlockingActionFactory.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/BlockingActionFactory.java similarity index 98% rename from src/main/org/insa/graphics/BlockingActionFactory.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/BlockingActionFactory.java index edd2e92..439c8cf 100644 --- a/src/main/org/insa/graphics/BlockingActionFactory.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/BlockingActionFactory.java @@ -1,4 +1,4 @@ -package org.insa.graphics; +package org.insa.graphs.gui; import java.awt.Component; import java.awt.event.ActionEvent; diff --git a/src/main/org/insa/graphics/DrawingChangeListener.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/DrawingChangeListener.java similarity index 89% rename from src/main/org/insa/graphics/DrawingChangeListener.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/DrawingChangeListener.java index 7b06ac4..40d6bfd 100644 --- a/src/main/org/insa/graphics/DrawingChangeListener.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/DrawingChangeListener.java @@ -1,6 +1,6 @@ -package org.insa.graphics; +package org.insa.graphs.gui; -import org.insa.graphics.drawing.Drawing; +import org.insa.graphs.gui.drawing.Drawing; public interface DrawingChangeListener { diff --git a/src/main/org/insa/graphics/GraphChangeListener.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/GraphChangeListener.java similarity index 75% rename from src/main/org/insa/graphics/GraphChangeListener.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/GraphChangeListener.java index 3cfb1fc..d438b7d 100644 --- a/src/main/org/insa/graphics/GraphChangeListener.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/GraphChangeListener.java @@ -1,6 +1,6 @@ -package org.insa.graphics; +package org.insa.graphs.gui; -import org.insa.graph.Graph; +import org.insa.graphs.model.Graph; public interface GraphChangeListener { diff --git a/src/main/org/insa/graphics/GraphReaderProgressBar.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/GraphReaderProgressBar.java similarity index 93% rename from src/main/org/insa/graphics/GraphReaderProgressBar.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/GraphReaderProgressBar.java index da223cf..8827a40 100644 --- a/src/main/org/insa/graphics/GraphReaderProgressBar.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/GraphReaderProgressBar.java @@ -1,4 +1,4 @@ -package org.insa.graphics; +package org.insa.graphs.gui; import java.awt.Component; @@ -11,10 +11,10 @@ import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.border.EmptyBorder; -import org.insa.graph.Arc; -import org.insa.graph.Node; -import org.insa.graph.RoadInformation; -import org.insa.graph.io.GraphReaderObserver; +import org.insa.graphs.model.Arc; +import org.insa.graphs.model.Node; +import org.insa.graphs.model.RoadInformation; +import org.insa.graphs.model.io.GraphReaderObserver; /** * One-time use GraphReaderObserver that display progress in three different diff --git a/src/main/org/insa/graphics/MainWindow.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/MainWindow.java similarity index 90% rename from src/main/org/insa/graphics/MainWindow.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/MainWindow.java index 8eb2eda..41ff400 100644 --- a/src/main/org/insa/graphics/MainWindow.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/MainWindow.java @@ -1,865 +1,862 @@ -package org.insa.graphics; - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.io.BufferedInputStream; -import java.io.DataInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.List; - -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JFileChooser; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JSplitPane; -import javax.swing.JTextArea; -import javax.swing.KeyStroke; -import javax.swing.SwingConstants; -import javax.swing.SwingUtilities; -import javax.swing.Timer; -import javax.swing.UIManager; -import javax.swing.border.CompoundBorder; -import javax.swing.border.EmptyBorder; - -import org.insa.algo.AbstractSolution; -import org.insa.algo.AlgorithmFactory; -import org.insa.algo.carpooling.CarPoolingAlgorithm; -import org.insa.algo.packageswitch.PackageSwitchAlgorithm; -import org.insa.algo.shortestpath.ShortestPathAlgorithm; -import org.insa.algo.shortestpath.ShortestPathData; -import org.insa.algo.shortestpath.ShortestPathGraphicObserver; -import org.insa.algo.shortestpath.ShortestPathSolution; -import org.insa.algo.shortestpath.ShortestPathTextObserver; -import org.insa.algo.weakconnectivity.WeaklyConnectedComponentGraphicObserver; -import org.insa.algo.weakconnectivity.WeaklyConnectedComponentTextObserver; -import org.insa.algo.weakconnectivity.WeaklyConnectedComponentsAlgorithm; -import org.insa.algo.weakconnectivity.WeaklyConnectedComponentsData; -import org.insa.graph.Graph; -import org.insa.graph.Path; -import org.insa.graph.io.BinaryGraphReader; -import org.insa.graph.io.BinaryPathReader; -import org.insa.graph.io.GraphReader; -import org.insa.graph.io.MapMismatchException; -import org.insa.graphics.AlgorithmPanel.StartActionEvent; -import org.insa.graphics.drawing.BasicGraphPalette; -import org.insa.graphics.drawing.BlackAndWhiteGraphPalette; -import org.insa.graphics.drawing.Drawing; -import org.insa.graphics.drawing.GraphPalette; -import org.insa.graphics.drawing.components.BasicDrawing; -import org.insa.graphics.drawing.components.MapViewDrawing; -import org.insa.graphics.utils.FileUtils; -import org.insa.graphics.utils.FileUtils.FolderType; - -public class MainWindow extends JFrame { - - /** - * - */ - private static final long serialVersionUID = 1L; - - /** - * - */ - private static final String WINDOW_TITLE = "BE Graphes INSA"; - - /** - * - */ - private static final int THREAD_TIMER_DELAY = 1000; // in milliseconds - - // Current graph. - protected Graph graph; - - // Path to the last opened graph file. - private String graphFilePath; - - // Drawing and click adapter. - protected Drawing drawing; - private final MapViewDrawing mapViewDrawing; - private final BasicDrawing basicDrawing; - - private final GraphPalette basicPalette, blackAndWhitePalette; - private GraphPalette currentPalette; - - // Main panel. - private final JSplitPane mainPanel; - - // Algorithm panels - private final List algoPanels = new ArrayList<>(); - private final AlgorithmPanel wccPanel, spPanel, cpPanel, psPanel; - - // Path panel - private final PathsPanel pathPanel; - - // List of items that cannot be used without a graph - private final ArrayList graphLockItems = new ArrayList(); - - // Label containing the map ID of the current graph. - private JLabel graphInfoPanel; - - // Thread information - private Timer threadTimer; - private JPanel threadPanel; - - // Log stream and print stream - private StreamCapturer logStream; - - private PrintStream printStream; - - // Current running thread - private ThreadWrapper currentThread; - - // Factory - private BlockingActionFactory baf; - - // Observers - private List drawingChangeListeners = new ArrayList<>(); - private List graphChangeListeneres = new ArrayList<>(); - - public MainWindow() { - super(WINDOW_TITLE); - - setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); - setLayout(new BorderLayout()); - - setMinimumSize(new Dimension(800, 600)); - - // Create drawing and action listeners... - this.basicDrawing = new BasicDrawing(); - this.mapViewDrawing = new MapViewDrawing(); - this.drawing = basicDrawing; - - // Createa palettes - this.basicPalette = new BasicGraphPalette(); - this.blackAndWhitePalette = new BlackAndWhiteGraphPalette(); - this.currentPalette = this.basicPalette; - - wccPanel = new AlgorithmPanel(this, WeaklyConnectedComponentsAlgorithm.class, - "Weakly-Connected Components", new String[]{}, false); - wccPanel.addStartActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - StartActionEvent evt = (StartActionEvent) e; - WeaklyConnectedComponentsData data = new WeaklyConnectedComponentsData(graph); - - WeaklyConnectedComponentsAlgorithm wccAlgorithm = null; - try { - wccAlgorithm = (WeaklyConnectedComponentsAlgorithm) AlgorithmFactory - .createAlgorithm(evt.getAlgorithmClass(), data); - } - catch (Exception e1) { - JOptionPane.showMessageDialog(MainWindow.this, - "An error occurred while creating the specified algorithm.", - "Internal error: Algorithm instantiation failure", - JOptionPane.ERROR_MESSAGE); - e1.printStackTrace(); - return; - } - - wccPanel.setEnabled(false); - - if (evt.isGraphicVisualizationEnabled()) { - wccAlgorithm.addObserver(new WeaklyConnectedComponentGraphicObserver(drawing)); - } - if (evt.isTextualVisualizationEnabled()) { - wccAlgorithm.addObserver(new WeaklyConnectedComponentTextObserver(printStream)); - } - - // We love Java... - final WeaklyConnectedComponentsAlgorithm copyAlgorithm = wccAlgorithm; - launchThread(new Runnable() { - @Override - public void run() { - AbstractSolution solution = copyAlgorithm.run(); - wccPanel.solutionPanel.addSolution(solution, false); - wccPanel.solutionPanel.setVisible(true); - wccPanel.setEnabled(true); - } - }); - } - }); - - spPanel = new AlgorithmPanel(this, ShortestPathAlgorithm.class, "Shortest-Path", - new String[]{ "Origin", "Destination" }, true); - spPanel.addStartActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - StartActionEvent evt = (StartActionEvent) e; - ShortestPathData data = new ShortestPathData(graph, evt.getNodes().get(0), - evt.getNodes().get(1), evt.getArcFilter()); - - ShortestPathAlgorithm spAlgorithm = null; - try { - spAlgorithm = (ShortestPathAlgorithm) AlgorithmFactory - .createAlgorithm(evt.getAlgorithmClass(), data); - } - catch (Exception e1) { - JOptionPane.showMessageDialog(MainWindow.this, - "An error occurred while creating the specified algorithm.", - "Internal error: Algorithm instantiation failure", - JOptionPane.ERROR_MESSAGE); - e1.printStackTrace(); - return; - } - - spPanel.setEnabled(false); - - if (evt.isGraphicVisualizationEnabled()) { - spAlgorithm.addObserver(new ShortestPathGraphicObserver(drawing)); - } - if (evt.isTextualVisualizationEnabled()) { - spAlgorithm.addObserver(new ShortestPathTextObserver(printStream)); - } - - final ShortestPathAlgorithm copyAlgorithm = spAlgorithm; - launchThread(new Runnable() { - @Override - public void run() { - // Run the algorithm. - ShortestPathSolution solution = copyAlgorithm.run(); - // Add the solution to the solution panel (but do not display - // overlay). - spPanel.solutionPanel.addSolution(solution, false); - // If the solution is feasible, add the path to the path panel. - if (solution.isFeasible()) { - pathPanel.addPath(solution.getPath()); - } - // Show the solution panel and enable the shortest-path panel. - spPanel.solutionPanel.setVisible(true); - spPanel.setEnabled(true); - } - }); - } - }); - - cpPanel = new AlgorithmPanel(this, CarPoolingAlgorithm.class, "Car-Pooling", new String[]{ - "Origin Car", "Origin Pedestrian", "Destination Car", "Destination Pedestrian" }, - true); - - psPanel = new AlgorithmPanel(this, PackageSwitchAlgorithm.class, "Car-Pooling", - new String[]{ "Oribin A", "Origin B", "Destination A", "Destination B" }, true); - - // add algorithm panels - algoPanels.add(wccPanel); - algoPanels.add(spPanel); - algoPanels.add(cpPanel); - algoPanels.add(psPanel); - - this.pathPanel = new PathsPanel(this); - - // Add click listeners to both drawing. - - for (AlgorithmPanel panel: algoPanels) { - this.basicDrawing.addDrawingClickListener(panel.nodesInputPanel); - this.mapViewDrawing.addDrawingClickListener(panel.nodesInputPanel); - this.graphChangeListeneres.add(panel.nodesInputPanel); - this.graphChangeListeneres.add(panel.solutionPanel); - this.drawingChangeListeners.add(panel.nodesInputPanel); - this.drawingChangeListeners.add(panel.solutionPanel); - this.drawingChangeListeners.add(panel); - } - - this.graphChangeListeneres.add(pathPanel); - this.drawingChangeListeners.add(pathPanel); - - // Create action factory. - this.currentThread = new ThreadWrapper(this); - this.baf = new BlockingActionFactory(this); - this.baf.addAction(currentThread); - - // Click adapter - ActionListener openMapActionListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - JFileChooser chooser = FileUtils.createFileChooser(FolderType.Map); - if (chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) { - graphFilePath = chooser.getSelectedFile().getAbsolutePath(); - DataInputStream stream; - try { - stream = new DataInputStream(new BufferedInputStream( - new FileInputStream(chooser.getSelectedFile()))); - } - catch (IOException e1) { - JOptionPane.showMessageDialog(MainWindow.this, - "Cannot open the selected file."); - return; - } - loadGraph(new BinaryGraphReader(stream)); - } - } - }; - - setJMenuBar(createMenuBar(openMapActionListener)); - - // Initial panel to show "Open Map... " - JPanel openPanel = new JPanel(); - openPanel.setLayout(new BoxLayout(openPanel, BoxLayout.PAGE_AXIS)); - JButton openButton = new JButton("Open Map... "); - openButton.setAlignmentX(Component.CENTER_ALIGNMENT); - openButton.addActionListener(openMapActionListener); - openButton.setFocusPainted(false); - openPanel.add(Box.createVerticalGlue()); - openPanel.add(openButton); - openPanel.add(Box.createVerticalGlue()); - - addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - int confirmed = JOptionPane.showConfirmDialog(MainWindow.this, - "Are you sure you want to close the application?", "Exit Confirmation", - JOptionPane.YES_NO_OPTION); - - if (confirmed == JOptionPane.YES_OPTION) { - dispose(); - System.exit(0); - } - } - }); - - // Create graph area - mainPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); - - JTextArea infoPanel = new JTextArea(); - infoPanel.setMinimumSize(new Dimension(200, 50)); - infoPanel.setBackground(Color.WHITE); - infoPanel.setLineWrap(true); - infoPanel.setEditable(false); - this.logStream = new StreamCapturer(infoPanel); - this.printStream = new PrintStream(this.logStream); - - JPanel rightComponent = new JPanel(); - rightComponent.setLayout(new GridBagLayout()); - - GridBagConstraints c = new GridBagConstraints(); - c.gridx = 0; - c.gridy = 0; - c.fill = GridBagConstraints.HORIZONTAL; - rightComponent.add(pathPanel, c); - - c.gridy = 1; - for (AlgorithmPanel panel: algoPanels) { - panel.setVisible(false); - rightComponent.add(panel, c); - } - - c = new GridBagConstraints(); - c.gridx = 0; - c.gridy = 2; - c.weightx = 1; - c.weighty = 1; - c.fill = GridBagConstraints.BOTH; - c.gridheight = GridBagConstraints.REMAINDER; - rightComponent.add(new JScrollPane(infoPanel), c); - - mainPanel.setResizeWeight(0.8); - mainPanel.setDividerSize(5); - - mainPanel.setBackground(Color.WHITE); - mainPanel.setLeftComponent(openPanel); - mainPanel.setRightComponent(rightComponent); - this.add(mainPanel, BorderLayout.CENTER); - - // Top Panel - this.add(createStatusBar(), BorderLayout.SOUTH); - - // Notify everythin - notifyDrawingLoaded(null, drawing); - } - - /** - * @param runnable - * @param canInterrupt - */ - private void launchThread(Runnable runnable, boolean canInterrupt) { - if (canInterrupt) { - currentThread.setThread(new Thread(new Runnable() { - @Override - public void run() { - threadTimer.restart(); - threadPanel.setVisible(true); - runnable.run(); - clearCurrentThread(); - } - })); - } - else { - currentThread.setThread(new Thread(runnable)); - } - currentThread.startThread(); - } - - private void launchThread(Runnable runnable) { - launchThread(runnable, true); - } - - protected void clearCurrentThread() { - threadTimer.stop(); - threadPanel.setVisible(false); - currentThread.setThread(null); - if (spPanel.isVisible()) { - spPanel.setEnabled(true); - } - } - - /** - * Notify all listeners that a new graph has been loaded. - */ - private void notifyNewGraphLoaded() { - for (GraphChangeListener listener: graphChangeListeneres) { - listener.newGraphLoaded(graph); - } - } - - /** - * Notify all listeners that a new drawing has been set up. - * - * @param oldDrawing - * @param newDrawing - */ - private void notifyDrawingLoaded(Drawing oldDrawing, Drawing newDrawing) { - for (DrawingChangeListener listener: drawingChangeListeners) { - listener.onDrawingLoaded(oldDrawing, newDrawing); - } - } - - /** - * Notify all listeners that a redraw request is emitted. - */ - private void notifyRedrawRequest() { - for (DrawingChangeListener listener: drawingChangeListeners) { - listener.onRedrawRequest(); - } - } - - /** - * Draw the stored graph on the drawing. - */ - private void drawGraph(Class newClass, GraphPalette palette) { - - // Save old divider location - int oldLocation = mainPanel.getDividerLocation(); - - // Set drawing if not set - if (!(mainPanel.getLeftComponent() instanceof Drawing)) { - mainPanel.setLeftComponent((Component) this.drawing); - mainPanel.setDividerLocation(oldLocation); - // Need to re-validate or the drawing will not have the - // correct size prior to drawing, which can cause issue. - this.revalidate(); - } - - boolean isNewGraph = newClass == null; - boolean isMapView = (isNewGraph && drawing == mapViewDrawing) - || (!isNewGraph && newClass.equals(MapViewDrawing.class)); - - // We need to draw MapView, we have to check if the file exists. - File mfile = null; - if (isMapView) { - String mfpath = graphFilePath.substring(0, graphFilePath.lastIndexOf(".map")) - + ".mapfg"; - mfile = new File(mfpath); - if (!mfile.exists()) { - if (JOptionPane.showConfirmDialog(this, - "The associated mapsforge (.mapfg) file has not been found, do you want to specify it manually?", - "File not found", - JOptionPane.YES_NO_CANCEL_OPTION) == JOptionPane.YES_OPTION) { - JFileChooser chooser = new JFileChooser(mfile.getParentFile()); - if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { - mfile = chooser.getSelectedFile(); - } - else { - mfile = null; - } - } - else { - mfile = null; - } - } - } - - Runnable runnable = null; - - if (isMapView && mfile != null) { - final File mfileFinal = mfile; - // It is a mapview drawing and the file was found, so: - // 1. We create the drawing if necessary. - if (drawing != mapViewDrawing) { - drawing.clear(); - drawing = mapViewDrawing; - mainPanel.setLeftComponent(mapViewDrawing); - mainPanel.setDividerLocation(oldLocation); - notifyDrawingLoaded(basicDrawing, mapViewDrawing); - drawing.clear(); - isNewGraph = true; - mainPanel.revalidate(); - } - if (isNewGraph) { - drawing.clear(); - runnable = new Runnable() { - public void run() { - ((MapViewDrawing) drawing).drawGraph(mfileFinal); - notifyRedrawRequest(); - } - }; - } - - } - else if (!isMapView || (isMapView && mfile == null && isNewGraph)) { - if (drawing == mapViewDrawing) { - mapViewDrawing.clear(); - drawing = basicDrawing; - mainPanel.setLeftComponent(basicDrawing); - mainPanel.setDividerLocation(oldLocation); - notifyDrawingLoaded(mapViewDrawing, basicDrawing); - isNewGraph = true; - } - if (isNewGraph || palette != this.currentPalette) { - this.currentPalette = palette; - drawing.clear(); - runnable = new Runnable() { - public void run() { - drawing.drawGraph(graph, palette); - notifyRedrawRequest(); - } - }; - } - } - - if (runnable != null) { - launchThread(runnable, false); - } - else { - drawing.clearOverlays(); - notifyRedrawRequest(); - } - - } - - /** - * @param newClass - */ - private void drawGraph(Class newClass) { - drawGraph(newClass, new BasicGraphPalette()); - } - - /** - * - */ - private void drawGraph() { - drawGraph(null, this.currentPalette); - } - - private void loadGraph(GraphReader reader) { - launchThread(new Runnable() { - @Override - public void run() { - GraphReaderProgressBar progressBar = new GraphReaderProgressBar(MainWindow.this); - progressBar.setLocationRelativeTo(mainPanel.getLeftComponent()); - reader.addObserver(progressBar); - try { - graph = reader.read(); - } - catch (Exception exception) { - progressBar.setVisible(false); - progressBar.dispose(); - progressBar = null; - JOptionPane.showMessageDialog(MainWindow.this, - "Unable to read graph from the selected file."); - exception.printStackTrace(System.out); - return; - } - - // In case of.... - progressBar.setVisible(false); - progressBar.dispose(); - progressBar = null; - - String info = graph.getMapId(); - if (graph.getMapName() != null && !graph.getMapName().isEmpty()) { - // The \u200e character is the left-to-right mark, we need to avoid issue with - // name that are right-to-left (e.g. arabic names). - info += " - " + graph.getMapName() + "\u200e"; - } - info += ", " + graph.size() + " nodes, " + graph.getGraphInformation().getArcCount() - + " arcs."; - graphInfoPanel.setText(info); - - drawGraph(); - - notifyNewGraphLoaded(); - - for (JMenuItem item: graphLockItems) { - item.setEnabled(true); - } - } - }, false); - } - - /** - * Show and enable the given AlgorithmPanel (and hide all others). - * - * @param algorithmPanel - */ - private void enableAlgorithmPanel(AlgorithmPanel algorithmPanel) { - int dividerLocation = mainPanel.getDividerLocation(); - for (AlgorithmPanel panel: algoPanels) { - panel.setVisible(panel == algorithmPanel); - } - mainPanel.setDividerLocation(dividerLocation); - } - - private JMenuBar createMenuBar(ActionListener openMapActionListener) { - - // Open Map item... - JMenuItem openMapItem = new JMenuItem("Open Map... ", KeyEvent.VK_O); - openMapItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.ALT_MASK)); - openMapItem.addActionListener(baf.createBlockingAction(openMapActionListener)); - - // Open Path item... - JMenuItem openPathItem = new JMenuItem("Open Path... ", KeyEvent.VK_P); - openPathItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.ALT_MASK)); - openPathItem.addActionListener(baf.createBlockingAction(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - JFileChooser chooser = FileUtils.createFileChooser(FolderType.PathInput); - if (chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) { - BinaryPathReader reader; - try { - reader = new BinaryPathReader(new DataInputStream(new BufferedInputStream( - new FileInputStream(chooser.getSelectedFile())))); - } - catch (IOException e1) { - JOptionPane.showMessageDialog(MainWindow.this, - "Cannot open the selected file."); - return; - } - try { - Path path = reader.readPath(graph); - pathPanel.addPath(path); - } - catch (MapMismatchException exception) { - JOptionPane.showMessageDialog(MainWindow.this, - "The selected file does not contain a path for the current graph."); - return; - } - catch (Exception exception) { - JOptionPane.showMessageDialog(MainWindow.this, - "Unable to read path from the selected file."); - return; - } - } - } - })); - graphLockItems.add(openPathItem); - - // Close item - JMenuItem closeItem = new JMenuItem("Quit", KeyEvent.VK_Q); - closeItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.ALT_MASK)); - closeItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - MainWindow.this.dispatchEvent( - new WindowEvent(MainWindow.this, WindowEvent.WINDOW_CLOSING)); - } - }); - - // Build the first menu. - JMenu fileMenu = new JMenu("File"); - fileMenu.add(openMapItem); - fileMenu.add(openPathItem); - fileMenu.addSeparator(); - fileMenu.add(closeItem); - - // Second menu - JMenuItem drawGraphItem = new JMenuItem("Redraw", KeyEvent.VK_R); - drawGraphItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.ALT_MASK)); - drawGraphItem.addActionListener(baf.createBlockingAction(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - drawGraph(BasicDrawing.class, basicPalette); - } - })); - graphLockItems.add(drawGraphItem); - JMenuItem drawGraphBWItem = new JMenuItem("Redraw (B&W)", KeyEvent.VK_B); - drawGraphBWItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, ActionEvent.ALT_MASK)); - drawGraphBWItem.addActionListener(baf.createBlockingAction(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - drawGraph(BasicDrawing.class, blackAndWhitePalette); - } - })); - graphLockItems.add(drawGraphBWItem); - JMenuItem drawGraphMapsforgeItem = new JMenuItem("Redraw (Map)", KeyEvent.VK_M); - drawGraphMapsforgeItem - .setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M, ActionEvent.ALT_MASK)); - drawGraphMapsforgeItem.addActionListener(baf.createBlockingAction(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - drawGraph(MapViewDrawing.class); - } - })); - graphLockItems.add(drawGraphMapsforgeItem); - - JMenu graphMenu = new JMenu("Graph"); - graphMenu.add(drawGraphItem); - graphMenu.add(drawGraphBWItem); - graphMenu.addSeparator(); - graphMenu.add(drawGraphMapsforgeItem); - - // Algo menu - JMenu algoMenu = new JMenu("Algorithms"); - - // Weakly connected components - JMenuItem wccItem = new JMenuItem("Weakly Connected Components"); - wccItem.addActionListener(baf.createBlockingAction(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - enableAlgorithmPanel(wccPanel); - } - })); - - // Shortest path - JMenuItem spItem = new JMenuItem("Shortest-Path"); - spItem.addActionListener(baf.createBlockingAction(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - enableAlgorithmPanel(spPanel); - } - })); - - // Car pooling - JMenuItem cpItem = new JMenuItem("Car Pooling"); - cpItem.addActionListener(baf.createBlockingAction(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - enableAlgorithmPanel(cpPanel); - } - })); - - // Car pooling - JMenuItem psItem = new JMenuItem("Package Switch"); - psItem.addActionListener(baf.createBlockingAction(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - enableAlgorithmPanel(psPanel); - } - })); - - graphLockItems.add(wccItem); - graphLockItems.add(spItem); - graphLockItems.add(cpItem); - graphLockItems.add(psItem); - - algoMenu.add(wccItem); - algoMenu.addSeparator(); - algoMenu.add(spItem); - algoMenu.add(cpItem); - algoMenu.add(psItem); - - // Create the menu bar. - JMenuBar menuBar = new JMenuBar(); - - menuBar.add(fileMenu); - menuBar.add(graphMenu); - menuBar.add(algoMenu); - - for (JMenuItem item: graphLockItems) { - item.setEnabled(false); - } - - return menuBar; - } - - private JPanel createStatusBar() { - // create the status bar panel and shove it down the bottom of the frame - JPanel statusPanel = new JPanel(); - statusPanel.setBorder( - new CompoundBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.GRAY), - new EmptyBorder(0, 15, 0, 15))); - statusPanel.setPreferredSize(new Dimension(getWidth(), 38)); - statusPanel.setLayout(new BorderLayout()); - - graphInfoPanel = new JLabel(); - graphInfoPanel.setHorizontalAlignment(SwingConstants.LEFT); - statusPanel.add(graphInfoPanel, BorderLayout.WEST); - - JLabel threadInfo = new JLabel("Thread running... "); - JLabel threadTimerLabel = new JLabel("00:00:00"); - JButton threadButton = new JButton("Stop"); - threadButton.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - if (currentThread.isRunning()) { - int confirmed = JOptionPane.showConfirmDialog(MainWindow.this, - "Are you sure you want to kill the running thread?", - "Kill Confirmation", JOptionPane.YES_NO_OPTION); - if (confirmed == JOptionPane.YES_OPTION) { - currentThread.interrupt(); - } - } - } - }); - - threadTimer = new Timer(THREAD_TIMER_DELAY, new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - long seconds = currentThread.getDuration().getSeconds(); - threadTimerLabel.setText(String.format("%02d:%02d:%02d", seconds / 3600, - seconds / 60 % 60, seconds % 60)); - } - }); - threadTimer.setInitialDelay(0); - - threadPanel = new JPanel(); - threadPanel.add(threadInfo); - threadPanel.add(threadTimerLabel); - threadPanel.add(threadButton); - threadPanel.setVisible(false); - statusPanel.add(threadPanel, BorderLayout.EAST); - - return statusPanel; - } - - public static void main(final String[] args) { - - // Try to set system look and feel. - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } - catch (Exception e) { - } - - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - MainWindow w = new MainWindow(); - w.setExtendedState(JFrame.MAXIMIZED_BOTH); - w.setVisible(true); - } - }); - } - -} +package org.insa.graphs.gui; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTextArea; +import javax.swing.KeyStroke; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.Timer; +import javax.swing.UIManager; +import javax.swing.border.CompoundBorder; +import javax.swing.border.EmptyBorder; + +import org.insa.graphs.algorithm.AbstractSolution; +import org.insa.graphs.algorithm.AlgorithmFactory; +import org.insa.graphs.algorithm.carpooling.CarPoolingAlgorithm; +import org.insa.graphs.algorithm.packageswitch.PackageSwitchAlgorithm; +import org.insa.graphs.algorithm.shortestpath.ShortestPathAlgorithm; +import org.insa.graphs.algorithm.shortestpath.ShortestPathData; +import org.insa.graphs.algorithm.shortestpath.ShortestPathSolution; +import org.insa.graphs.algorithm.shortestpath.ShortestPathTextObserver; +import org.insa.graphs.algorithm.weakconnectivity.WeaklyConnectedComponentTextObserver; +import org.insa.graphs.algorithm.weakconnectivity.WeaklyConnectedComponentsAlgorithm; +import org.insa.graphs.algorithm.weakconnectivity.WeaklyConnectedComponentsData; +import org.insa.graphs.gui.AlgorithmPanel.StartActionEvent; +import org.insa.graphs.gui.drawing.BasicGraphPalette; +import org.insa.graphs.gui.drawing.BlackAndWhiteGraphPalette; +import org.insa.graphs.gui.drawing.Drawing; +import org.insa.graphs.gui.drawing.GraphPalette; +import org.insa.graphs.gui.drawing.components.BasicDrawing; +import org.insa.graphs.gui.drawing.components.MapViewDrawing; +import org.insa.graphs.gui.observers.ShortestPathGraphicObserver; +import org.insa.graphs.gui.observers.WeaklyConnectedComponentGraphicObserver; +import org.insa.graphs.gui.utils.FileUtils; +import org.insa.graphs.gui.utils.FileUtils.FolderType; +import org.insa.graphs.model.Graph; +import org.insa.graphs.model.Path; +import org.insa.graphs.model.io.BinaryGraphReader; +import org.insa.graphs.model.io.BinaryPathReader; +import org.insa.graphs.model.io.GraphReader; +import org.insa.graphs.model.io.MapMismatchException; + +public class MainWindow extends JFrame { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * + */ + private static final String WINDOW_TITLE = "BE Graphes INSA"; + + /** + * + */ + private static final int THREAD_TIMER_DELAY = 1000; // in milliseconds + + // Current graph. + protected Graph graph; + + // Path to the last opened graph file. + private String graphFilePath; + + // Drawing and click adapter. + protected Drawing drawing; + private final MapViewDrawing mapViewDrawing; + private final BasicDrawing basicDrawing; + + private final GraphPalette basicPalette, blackAndWhitePalette; + private GraphPalette currentPalette; + + // Main panel. + private final JSplitPane mainPanel; + + // Algorithm panels + private final List algoPanels = new ArrayList<>(); + private final AlgorithmPanel wccPanel, spPanel, cpPanel, psPanel; + + // Path panel + private final PathsPanel pathPanel; + + // List of items that cannot be used without a graph + private final ArrayList graphLockItems = new ArrayList(); + + // Label containing the map ID of the current graph. + private JLabel graphInfoPanel; + + // Thread information + private Timer threadTimer; + private JPanel threadPanel; + + // Log stream and print stream + private StreamCapturer logStream; + + private PrintStream printStream; + + // Current running thread + private ThreadWrapper currentThread; + + // Factory + private BlockingActionFactory baf; + + // Observers + private List drawingChangeListeners = new ArrayList<>(); + private List graphChangeListeneres = new ArrayList<>(); + + public MainWindow() { + super(WINDOW_TITLE); + + setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + setLayout(new BorderLayout()); + + setMinimumSize(new Dimension(800, 600)); + + // Create drawing and action listeners... + this.basicDrawing = new BasicDrawing(); + this.mapViewDrawing = new MapViewDrawing(); + this.drawing = basicDrawing; + + // Createa palettes + this.basicPalette = new BasicGraphPalette(); + this.blackAndWhitePalette = new BlackAndWhiteGraphPalette(); + this.currentPalette = this.basicPalette; + + wccPanel = new AlgorithmPanel(this, WeaklyConnectedComponentsAlgorithm.class, + "Weakly-Connected Components", new String[] {}, false); + wccPanel.addStartActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + StartActionEvent evt = (StartActionEvent) e; + WeaklyConnectedComponentsData data = new WeaklyConnectedComponentsData(graph); + + WeaklyConnectedComponentsAlgorithm wccAlgorithm = null; + try { + wccAlgorithm = (WeaklyConnectedComponentsAlgorithm) AlgorithmFactory + .createAlgorithm(evt.getAlgorithmClass(), data); + } + catch (Exception e1) { + JOptionPane.showMessageDialog(MainWindow.this, + "An error occurred while creating the specified algorithm.", + "Internal error: Algorithm instantiation failure", + JOptionPane.ERROR_MESSAGE); + e1.printStackTrace(); + return; + } + + wccPanel.setEnabled(false); + + if (evt.isGraphicVisualizationEnabled()) { + wccAlgorithm.addObserver(new WeaklyConnectedComponentGraphicObserver(drawing)); + } + if (evt.isTextualVisualizationEnabled()) { + wccAlgorithm.addObserver(new WeaklyConnectedComponentTextObserver(printStream)); + } + + // We love Java... + final WeaklyConnectedComponentsAlgorithm copyAlgorithm = wccAlgorithm; + launchThread(new Runnable() { + @Override + public void run() { + AbstractSolution solution = copyAlgorithm.run(); + wccPanel.solutionPanel.addSolution(solution, false); + wccPanel.solutionPanel.setVisible(true); + wccPanel.setEnabled(true); + } + }); + } + }); + + spPanel = new AlgorithmPanel(this, ShortestPathAlgorithm.class, "Shortest-Path", + new String[] { "Origin", "Destination" }, true); + spPanel.addStartActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + StartActionEvent evt = (StartActionEvent) e; + ShortestPathData data = new ShortestPathData(graph, evt.getNodes().get(0), + evt.getNodes().get(1), evt.getArcFilter()); + + ShortestPathAlgorithm spAlgorithm = null; + try { + spAlgorithm = (ShortestPathAlgorithm) AlgorithmFactory + .createAlgorithm(evt.getAlgorithmClass(), data); + } + catch (Exception e1) { + JOptionPane.showMessageDialog(MainWindow.this, + "An error occurred while creating the specified algorithm.", + "Internal error: Algorithm instantiation failure", + JOptionPane.ERROR_MESSAGE); + e1.printStackTrace(); + return; + } + + spPanel.setEnabled(false); + + if (evt.isGraphicVisualizationEnabled()) { + spAlgorithm.addObserver(new ShortestPathGraphicObserver(drawing)); + } + if (evt.isTextualVisualizationEnabled()) { + spAlgorithm.addObserver(new ShortestPathTextObserver(printStream)); + } + + final ShortestPathAlgorithm copyAlgorithm = spAlgorithm; + launchThread(new Runnable() { + @Override + public void run() { + // Run the algorithm. + ShortestPathSolution solution = copyAlgorithm.run(); + // Add the solution to the solution panel (but do not display + // overlay). + spPanel.solutionPanel.addSolution(solution, false); + // If the solution is feasible, add the path to the path panel. + if (solution.isFeasible()) { + pathPanel.addPath(solution.getPath()); + } + // Show the solution panel and enable the shortest-path panel. + spPanel.solutionPanel.setVisible(true); + spPanel.setEnabled(true); + } + }); + } + }); + + cpPanel = new AlgorithmPanel(this, CarPoolingAlgorithm.class, "Car-Pooling", new String[] { + "Origin Car", "Origin Pedestrian", "Destination Car", "Destination Pedestrian" }, + true); + + psPanel = new AlgorithmPanel(this, PackageSwitchAlgorithm.class, "Car-Pooling", + new String[] { "Oribin A", "Origin B", "Destination A", "Destination B" }, true); + + // add algorithm panels + algoPanels.add(wccPanel); + algoPanels.add(spPanel); + algoPanels.add(cpPanel); + algoPanels.add(psPanel); + + this.pathPanel = new PathsPanel(this); + + // Add click listeners to both drawing. + + for (AlgorithmPanel panel: algoPanels) { + this.basicDrawing.addDrawingClickListener(panel.nodesInputPanel); + this.mapViewDrawing.addDrawingClickListener(panel.nodesInputPanel); + this.graphChangeListeneres.add(panel.nodesInputPanel); + this.graphChangeListeneres.add(panel.solutionPanel); + this.drawingChangeListeners.add(panel.nodesInputPanel); + this.drawingChangeListeners.add(panel.solutionPanel); + this.drawingChangeListeners.add(panel); + } + + this.graphChangeListeneres.add(pathPanel); + this.drawingChangeListeners.add(pathPanel); + + // Create action factory. + this.currentThread = new ThreadWrapper(this); + this.baf = new BlockingActionFactory(this); + this.baf.addAction(currentThread); + + // Click adapter + ActionListener openMapActionListener = new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JFileChooser chooser = FileUtils.createFileChooser(FolderType.Map); + if (chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) { + graphFilePath = chooser.getSelectedFile().getAbsolutePath(); + + // Note: Don't use a try-resources block since loadGraph is asynchronous. + final DataInputStream stream; + try { + stream = new DataInputStream(new BufferedInputStream( + new FileInputStream(chooser.getSelectedFile()))); + } + catch (IOException e1) { + JOptionPane.showMessageDialog(MainWindow.this, + "Cannot open the selected file."); + return; + } + loadGraph(new BinaryGraphReader(stream)); + } + } + }; + + setJMenuBar(createMenuBar(openMapActionListener)); + + // Initial panel to show "Open Map... " + JPanel openPanel = new JPanel(); + openPanel.setLayout(new BoxLayout(openPanel, BoxLayout.PAGE_AXIS)); + JButton openButton = new JButton("Open Map... "); + openButton.setAlignmentX(Component.CENTER_ALIGNMENT); + openButton.addActionListener(openMapActionListener); + openButton.setFocusPainted(false); + openPanel.add(Box.createVerticalGlue()); + openPanel.add(openButton); + openPanel.add(Box.createVerticalGlue()); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + int confirmed = JOptionPane.showConfirmDialog(MainWindow.this, + "Are you sure you want to close the application?", "Exit Confirmation", + JOptionPane.YES_NO_OPTION); + + if (confirmed == JOptionPane.YES_OPTION) { + dispose(); + System.exit(0); + } + } + }); + + // Create graph area + mainPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); + + JTextArea infoPanel = new JTextArea(); + infoPanel.setMinimumSize(new Dimension(200, 50)); + infoPanel.setBackground(Color.WHITE); + infoPanel.setLineWrap(true); + infoPanel.setEditable(false); + this.logStream = new StreamCapturer(infoPanel); + this.printStream = new PrintStream(this.logStream); + + JPanel rightComponent = new JPanel(); + rightComponent.setLayout(new GridBagLayout()); + + GridBagConstraints c = new GridBagConstraints(); + c.gridx = 0; + c.gridy = 0; + c.fill = GridBagConstraints.HORIZONTAL; + rightComponent.add(pathPanel, c); + + c.gridy = 1; + for (AlgorithmPanel panel: algoPanels) { + panel.setVisible(false); + rightComponent.add(panel, c); + } + + c = new GridBagConstraints(); + c.gridx = 0; + c.gridy = 2; + c.weightx = 1; + c.weighty = 1; + c.fill = GridBagConstraints.BOTH; + c.gridheight = GridBagConstraints.REMAINDER; + rightComponent.add(new JScrollPane(infoPanel), c); + + mainPanel.setResizeWeight(0.8); + mainPanel.setDividerSize(5); + + mainPanel.setBackground(Color.WHITE); + mainPanel.setLeftComponent(openPanel); + mainPanel.setRightComponent(rightComponent); + this.add(mainPanel, BorderLayout.CENTER); + + // Top Panel + this.add(createStatusBar(), BorderLayout.SOUTH); + + // Notify everythin + notifyDrawingLoaded(null, drawing); + } + + /** + * @param runnable + * @param canInterrupt + */ + private void launchThread(Runnable runnable, boolean canInterrupt) { + if (canInterrupt) { + currentThread.setThread(new Thread(new Runnable() { + @Override + public void run() { + threadTimer.restart(); + threadPanel.setVisible(true); + runnable.run(); + clearCurrentThread(); + } + })); + } + else { + currentThread.setThread(new Thread(runnable)); + } + currentThread.startThread(); + } + + private void launchThread(Runnable runnable) { + launchThread(runnable, true); + } + + protected void clearCurrentThread() { + threadTimer.stop(); + threadPanel.setVisible(false); + currentThread.setThread(null); + if (spPanel.isVisible()) { + spPanel.setEnabled(true); + } + } + + /** + * Notify all listeners that a new graph has been loaded. + */ + private void notifyNewGraphLoaded() { + for (GraphChangeListener listener: graphChangeListeneres) { + listener.newGraphLoaded(graph); + } + } + + /** + * Notify all listeners that a new drawing has been set up. + * + * @param oldDrawing + * @param newDrawing + */ + private void notifyDrawingLoaded(Drawing oldDrawing, Drawing newDrawing) { + for (DrawingChangeListener listener: drawingChangeListeners) { + listener.onDrawingLoaded(oldDrawing, newDrawing); + } + } + + /** + * Notify all listeners that a redraw request is emitted. + */ + private void notifyRedrawRequest() { + for (DrawingChangeListener listener: drawingChangeListeners) { + listener.onRedrawRequest(); + } + } + + /** + * Draw the stored graph on the drawing. + */ + private void drawGraph(Class newClass, GraphPalette palette) { + + // Save old divider location + int oldLocation = mainPanel.getDividerLocation(); + + // Set drawing if not set + if (!(mainPanel.getLeftComponent() instanceof Drawing)) { + mainPanel.setLeftComponent((Component) this.drawing); + mainPanel.setDividerLocation(oldLocation); + // Need to re-validate or the drawing will not have the + // correct size prior to drawing, which can cause issue. + this.revalidate(); + } + + boolean isNewGraph = newClass == null; + boolean isMapView = (isNewGraph && drawing == mapViewDrawing) + || (!isNewGraph && newClass.equals(MapViewDrawing.class)); + + // We need to draw MapView, we have to check if the file exists. + File mfile = null; + if (isMapView) { + String mfpath = graphFilePath.substring(0, graphFilePath.lastIndexOf(".map")) + + ".mapfg"; + mfile = new File(mfpath); + if (!mfile.exists()) { + if (JOptionPane.showConfirmDialog(this, + "The associated mapsforge (.mapfg) file has not been found, do you want to specify it manually?", + "File not found", + JOptionPane.YES_NO_CANCEL_OPTION) == JOptionPane.YES_OPTION) { + JFileChooser chooser = new JFileChooser(mfile.getParentFile()); + if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { + mfile = chooser.getSelectedFile(); + } + else { + mfile = null; + } + } + else { + mfile = null; + } + } + } + + Runnable runnable = null; + + if (isMapView && mfile != null) { + final File mfileFinal = mfile; + // It is a mapview drawing and the file was found, so: + // 1. We create the drawing if necessary. + if (drawing != mapViewDrawing) { + drawing.clear(); + drawing = mapViewDrawing; + mainPanel.setLeftComponent(mapViewDrawing); + mainPanel.setDividerLocation(oldLocation); + notifyDrawingLoaded(basicDrawing, mapViewDrawing); + drawing.clear(); + isNewGraph = true; + mainPanel.revalidate(); + } + if (isNewGraph) { + drawing.clear(); + runnable = new Runnable() { + public void run() { + ((MapViewDrawing) drawing).drawGraph(mfileFinal); + notifyRedrawRequest(); + } + }; + } + + } + else if (!isMapView || (isMapView && mfile == null && isNewGraph)) { + if (drawing == mapViewDrawing) { + mapViewDrawing.clear(); + drawing = basicDrawing; + mainPanel.setLeftComponent(basicDrawing); + mainPanel.setDividerLocation(oldLocation); + notifyDrawingLoaded(mapViewDrawing, basicDrawing); + isNewGraph = true; + } + if (isNewGraph || palette != this.currentPalette) { + this.currentPalette = palette; + drawing.clear(); + runnable = new Runnable() { + public void run() { + drawing.drawGraph(graph, palette); + notifyRedrawRequest(); + } + }; + } + } + + if (runnable != null) { + launchThread(runnable, false); + } + else { + drawing.clearOverlays(); + notifyRedrawRequest(); + } + + } + + /** + * @param newClass + */ + private void drawGraph(Class newClass) { + drawGraph(newClass, new BasicGraphPalette()); + } + + /** + * + */ + private void drawGraph() { + drawGraph(null, this.currentPalette); + } + + private void loadGraph(GraphReader reader) { + launchThread(new Runnable() { + @Override + public void run() { + GraphReaderProgressBar progressBar = new GraphReaderProgressBar(MainWindow.this); + progressBar.setLocationRelativeTo(mainPanel.getLeftComponent()); + reader.addObserver(progressBar); + try { + graph = reader.read(); + reader.close(); + } + catch (Exception exception) { + progressBar.setVisible(false); + progressBar.dispose(); + progressBar = null; + JOptionPane.showMessageDialog(MainWindow.this, + "

Unable to read graph from the selected file:

" + + exception.getMessage() + "

"); + exception.printStackTrace(System.out); + return; + } + + // In case of.... + progressBar.setVisible(false); + progressBar.dispose(); + progressBar = null; + + String info = graph.getMapId(); + if (graph.getMapName() != null && !graph.getMapName().isEmpty()) { + // The \u200e character is the left-to-right mark, we need to avoid issue with + // name that are right-to-left (e.g. arabic names). + info += " - " + graph.getMapName() + "\u200e"; + } + info += ", " + graph.size() + " nodes, " + graph.getGraphInformation().getArcCount() + + " arcs."; + graphInfoPanel.setText(info); + + drawGraph(); + + notifyNewGraphLoaded(); + + for (JMenuItem item: graphLockItems) { + item.setEnabled(true); + } + } + }, false); + } + + /** + * Show and enable the given AlgorithmPanel (and hide all others). + * + * @param algorithmPanel + */ + private void enableAlgorithmPanel(AlgorithmPanel algorithmPanel) { + int dividerLocation = mainPanel.getDividerLocation(); + for (AlgorithmPanel panel: algoPanels) { + panel.setVisible(panel == algorithmPanel); + } + mainPanel.setDividerLocation(dividerLocation); + } + + private JMenuBar createMenuBar(ActionListener openMapActionListener) { + + // Open Map item... + JMenuItem openMapItem = new JMenuItem("Open Map... ", KeyEvent.VK_O); + openMapItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.ALT_MASK)); + openMapItem.addActionListener(baf.createBlockingAction(openMapActionListener)); + + // Open Path item... + JMenuItem openPathItem = new JMenuItem("Open Path... ", KeyEvent.VK_P); + openPathItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.ALT_MASK)); + openPathItem.addActionListener(baf.createBlockingAction(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + JFileChooser chooser = FileUtils.createFileChooser(FolderType.PathInput); + if (chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) { + try (BinaryPathReader reader = new BinaryPathReader(new DataInputStream(new BufferedInputStream( + new FileInputStream(chooser.getSelectedFile()))))){ + Path path = reader.readPath(graph); + pathPanel.addPath(path); + } + catch (MapMismatchException exception) { + JOptionPane.showMessageDialog(MainWindow.this, + "The selected file does not contain a path for the current graph."); + } + catch (IOException e1) { + JOptionPane.showMessageDialog(MainWindow.this, + "Cannot open the selected file."); + } + catch (Exception exception) { + JOptionPane.showMessageDialog(MainWindow.this, + "Unable to read path from the selected file."); + } + } + } + })); + graphLockItems.add(openPathItem); + + // Close item + JMenuItem closeItem = new JMenuItem("Quit", KeyEvent.VK_Q); + closeItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.ALT_MASK)); + closeItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + MainWindow.this.dispatchEvent( + new WindowEvent(MainWindow.this, WindowEvent.WINDOW_CLOSING)); + } + }); + + // Build the first menu. + JMenu fileMenu = new JMenu("File"); + fileMenu.add(openMapItem); + fileMenu.add(openPathItem); + fileMenu.addSeparator(); + fileMenu.add(closeItem); + + // Second menu + JMenuItem drawGraphItem = new JMenuItem("Redraw", KeyEvent.VK_R); + drawGraphItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.ALT_MASK)); + drawGraphItem.addActionListener(baf.createBlockingAction(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + drawGraph(BasicDrawing.class, basicPalette); + } + })); + graphLockItems.add(drawGraphItem); + JMenuItem drawGraphBWItem = new JMenuItem("Redraw (B&W)", KeyEvent.VK_B); + drawGraphBWItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, ActionEvent.ALT_MASK)); + drawGraphBWItem.addActionListener(baf.createBlockingAction(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + drawGraph(BasicDrawing.class, blackAndWhitePalette); + } + })); + graphLockItems.add(drawGraphBWItem); + JMenuItem drawGraphMapsforgeItem = new JMenuItem("Redraw (Map)", KeyEvent.VK_M); + drawGraphMapsforgeItem + .setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M, ActionEvent.ALT_MASK)); + drawGraphMapsforgeItem.addActionListener(baf.createBlockingAction(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + drawGraph(MapViewDrawing.class); + } + })); + graphLockItems.add(drawGraphMapsforgeItem); + + JMenu graphMenu = new JMenu("Graph"); + graphMenu.add(drawGraphItem); + graphMenu.add(drawGraphBWItem); + graphMenu.addSeparator(); + graphMenu.add(drawGraphMapsforgeItem); + + // Algo menu + JMenu algoMenu = new JMenu("Algorithms"); + + // Weakly connected components + JMenuItem wccItem = new JMenuItem("Weakly Connected Components"); + wccItem.addActionListener(baf.createBlockingAction(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + enableAlgorithmPanel(wccPanel); + } + })); + + // Shortest path + JMenuItem spItem = new JMenuItem("Shortest-Path"); + spItem.addActionListener(baf.createBlockingAction(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + enableAlgorithmPanel(spPanel); + } + })); + + // Car pooling + JMenuItem cpItem = new JMenuItem("Car Pooling"); + cpItem.addActionListener(baf.createBlockingAction(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + enableAlgorithmPanel(cpPanel); + } + })); + + // Car pooling + JMenuItem psItem = new JMenuItem("Package Switch"); + psItem.addActionListener(baf.createBlockingAction(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + enableAlgorithmPanel(psPanel); + } + })); + + graphLockItems.add(wccItem); + graphLockItems.add(spItem); + graphLockItems.add(cpItem); + graphLockItems.add(psItem); + + algoMenu.add(wccItem); + algoMenu.addSeparator(); + algoMenu.add(spItem); + algoMenu.add(cpItem); + algoMenu.add(psItem); + + // Create the menu bar. + JMenuBar menuBar = new JMenuBar(); + + menuBar.add(fileMenu); + menuBar.add(graphMenu); + menuBar.add(algoMenu); + + for (JMenuItem item: graphLockItems) { + item.setEnabled(false); + } + + return menuBar; + } + + private JPanel createStatusBar() { + // create the status bar panel and shove it down the bottom of the frame + JPanel statusPanel = new JPanel(); + statusPanel.setBorder( + new CompoundBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.GRAY), + new EmptyBorder(0, 15, 0, 15))); + statusPanel.setPreferredSize(new Dimension(getWidth(), 38)); + statusPanel.setLayout(new BorderLayout()); + + graphInfoPanel = new JLabel(); + graphInfoPanel.setHorizontalAlignment(SwingConstants.LEFT); + statusPanel.add(graphInfoPanel, BorderLayout.WEST); + + JLabel threadInfo = new JLabel("Thread running... "); + JLabel threadTimerLabel = new JLabel("00:00:00"); + JButton threadButton = new JButton("Stop"); + threadButton.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + if (currentThread.isRunning()) { + int confirmed = JOptionPane.showConfirmDialog(MainWindow.this, + "Are you sure you want to kill the running thread?", + "Kill Confirmation", JOptionPane.YES_NO_OPTION); + if (confirmed == JOptionPane.YES_OPTION) { + currentThread.interrupt(); + } + } + } + }); + + threadTimer = new Timer(THREAD_TIMER_DELAY, new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + long seconds = currentThread.getDuration().getSeconds(); + threadTimerLabel.setText(String.format("%02d:%02d:%02d", seconds / 3600, + seconds / 60 % 60, seconds % 60)); + } + }); + threadTimer.setInitialDelay(0); + + threadPanel = new JPanel(); + threadPanel.add(threadInfo); + threadPanel.add(threadTimerLabel); + threadPanel.add(threadButton); + threadPanel.setVisible(false); + statusPanel.add(threadPanel, BorderLayout.EAST); + + return statusPanel; + } + + public static void main(final String[] args) { + + // Try to set system look and feel. + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } + catch (Exception e) { + } + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + MainWindow w = new MainWindow(); + w.setExtendedState(JFrame.MAXIMIZED_BOTH); + w.setVisible(true); + } + }); + } + +} diff --git a/src/main/org/insa/graphics/NodesInputPanel.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/NodesInputPanel.java similarity index 97% rename from src/main/org/insa/graphics/NodesInputPanel.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/NodesInputPanel.java index f5dc5e9..0c41fe7 100644 --- a/src/main/org/insa/graphics/NodesInputPanel.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/NodesInputPanel.java @@ -1,4 +1,4 @@ -package org.insa.graphics; +package org.insa.graphs.gui; import java.awt.Color; import java.awt.Font; @@ -21,13 +21,13 @@ import javax.swing.JTextField; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; -import org.insa.graph.Graph; -import org.insa.graph.Node; -import org.insa.graph.Point; -import org.insa.graphics.drawing.Drawing; -import org.insa.graphics.drawing.Drawing.AlphaMode; -import org.insa.graphics.drawing.DrawingClickListener; -import org.insa.graphics.drawing.overlays.MarkerOverlay; +import org.insa.graphs.gui.drawing.Drawing; +import org.insa.graphs.gui.drawing.Drawing.AlphaMode; +import org.insa.graphs.gui.drawing.DrawingClickListener; +import org.insa.graphs.gui.drawing.overlays.MarkerOverlay; +import org.insa.graphs.model.Graph; +import org.insa.graphs.model.Node; +import org.insa.graphs.model.Point; public class NodesInputPanel extends JPanel implements DrawingClickListener, DrawingChangeListener, GraphChangeListener { diff --git a/src/main/org/insa/graphics/PathsPanel.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/PathsPanel.java similarity index 95% rename from src/main/org/insa/graphics/PathsPanel.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/PathsPanel.java index 3e687a4..29ea418 100644 --- a/src/main/org/insa/graphics/PathsPanel.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/PathsPanel.java @@ -1,4 +1,4 @@ -package org.insa.graphics; +package org.insa.graphs.gui; import java.awt.Color; import java.awt.Component; @@ -32,14 +32,14 @@ import javax.swing.border.EmptyBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import org.insa.graph.Graph; -import org.insa.graph.Path; -import org.insa.graph.io.BinaryPathWriter; -import org.insa.graphics.drawing.Drawing; -import org.insa.graphics.drawing.overlays.PathOverlay; -import org.insa.graphics.utils.ColorUtils; -import org.insa.graphics.utils.FileUtils; -import org.insa.graphics.utils.FileUtils.FolderType; +import org.insa.graphs.gui.drawing.Drawing; +import org.insa.graphs.gui.drawing.overlays.PathOverlay; +import org.insa.graphs.gui.utils.ColorUtils; +import org.insa.graphs.gui.utils.FileUtils; +import org.insa.graphs.gui.utils.FileUtils.FolderType; +import org.insa.graphs.model.Graph; +import org.insa.graphs.model.Path; +import org.insa.graphs.model.io.BinaryPathWriter; public class PathsPanel extends JPanel implements DrawingChangeListener, GraphChangeListener { @@ -232,9 +232,8 @@ public class PathsPanel extends JPanel implements DrawingChangeListener, GraphCh if (chooser .showSaveDialog(getTopLevelAncestor()) == JFileChooser.APPROVE_OPTION) { File file = chooser.getSelectedFile(); - try { - BinaryPathWriter writer = new BinaryPathWriter(new DataOutputStream( - new BufferedOutputStream(new FileOutputStream(file)))); + try (BinaryPathWriter writer = new BinaryPathWriter(new DataOutputStream( + new BufferedOutputStream(new FileOutputStream(file))))) { writer.writePath(path); } catch (IOException e1) { diff --git a/src/main/org/insa/graphics/RunningAction.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/RunningAction.java similarity index 95% rename from src/main/org/insa/graphics/RunningAction.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/RunningAction.java index a19aa1a..8cca834 100644 --- a/src/main/org/insa/graphics/RunningAction.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/RunningAction.java @@ -1,4 +1,4 @@ -package org.insa.graphics; +package org.insa.graphs.gui; import java.time.Duration; import java.time.Instant; diff --git a/src/main/org/insa/graphics/SolutionPanel.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/SolutionPanel.java similarity index 96% rename from src/main/org/insa/graphics/SolutionPanel.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/SolutionPanel.java index 2d81569..e96bcef 100644 --- a/src/main/org/insa/graphics/SolutionPanel.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/SolutionPanel.java @@ -1,4 +1,4 @@ -package org.insa.graphics; +package org.insa.graphs.gui; import java.awt.Color; import java.awt.Component; @@ -19,12 +19,12 @@ import javax.swing.JPanel; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; -import org.insa.algo.AbstractInputData; -import org.insa.algo.AbstractSolution; -import org.insa.graph.Graph; -import org.insa.graph.Path; -import org.insa.graphics.drawing.Drawing; -import org.insa.graphics.drawing.overlays.PathOverlay; +import org.insa.graphs.algorithm.AbstractInputData; +import org.insa.graphs.algorithm.AbstractSolution; +import org.insa.graphs.gui.drawing.Drawing; +import org.insa.graphs.gui.drawing.overlays.PathOverlay; +import org.insa.graphs.model.Graph; +import org.insa.graphs.model.Path; public class SolutionPanel extends JPanel implements DrawingChangeListener, GraphChangeListener { @@ -122,6 +122,7 @@ public class SolutionPanel extends JPanel implements DrawingChangeListener, Grap /* * (non-Javadoc) + * * @see java.lang.Object#toString() */ public String toString() { diff --git a/src/main/org/insa/graphics/StreamCapturer.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/StreamCapturer.java similarity index 97% rename from src/main/org/insa/graphics/StreamCapturer.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/StreamCapturer.java index d7f47d2..0a7d010 100644 --- a/src/main/org/insa/graphics/StreamCapturer.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/StreamCapturer.java @@ -1,4 +1,4 @@ -package org.insa.graphics; +package org.insa.graphs.gui; import java.io.IOException; import java.io.OutputStream; diff --git a/src/main/org/insa/graphics/ThreadWrapper.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/ThreadWrapper.java similarity index 97% rename from src/main/org/insa/graphics/ThreadWrapper.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/ThreadWrapper.java index e824e22..e5e9cfc 100644 --- a/src/main/org/insa/graphics/ThreadWrapper.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/ThreadWrapper.java @@ -1,4 +1,4 @@ -package org.insa.graphics; +package org.insa.graphs.gui; import java.time.Duration; import java.time.Instant; diff --git a/src/main/org/insa/graphics/drawing/BasicGraphPalette.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/BasicGraphPalette.java similarity index 93% rename from src/main/org/insa/graphics/drawing/BasicGraphPalette.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/BasicGraphPalette.java index ffe47d3..7c7d26e 100644 --- a/src/main/org/insa/graphics/drawing/BasicGraphPalette.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/BasicGraphPalette.java @@ -1,9 +1,9 @@ -package org.insa.graphics.drawing; +package org.insa.graphs.gui.drawing; import java.awt.Color; -import org.insa.graph.Arc; -import org.insa.graph.RoadInformation.RoadType; +import org.insa.graphs.model.Arc; +import org.insa.graphs.model.RoadInformation.RoadType; public class BasicGraphPalette implements GraphPalette { diff --git a/src/main/org/insa/graphics/drawing/BlackAndWhiteGraphPalette.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/BlackAndWhiteGraphPalette.java similarity index 86% rename from src/main/org/insa/graphics/drawing/BlackAndWhiteGraphPalette.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/BlackAndWhiteGraphPalette.java index 71d5b50..3141227 100644 --- a/src/main/org/insa/graphics/drawing/BlackAndWhiteGraphPalette.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/BlackAndWhiteGraphPalette.java @@ -1,8 +1,8 @@ -package org.insa.graphics.drawing; +package org.insa.graphs.gui.drawing; import java.awt.Color; -import org.insa.graph.Arc; +import org.insa.graphs.model.Arc; public class BlackAndWhiteGraphPalette extends BasicGraphPalette { diff --git a/src/main/org/insa/graphics/drawing/Drawing.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/Drawing.java similarity index 93% rename from src/main/org/insa/graphics/drawing/Drawing.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/Drawing.java index 01cff5f..ee2a018 100644 --- a/src/main/org/insa/graphics/drawing/Drawing.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/Drawing.java @@ -1,13 +1,13 @@ -package org.insa.graphics.drawing; +package org.insa.graphs.gui.drawing; import java.awt.Color; -import org.insa.graph.Graph; -import org.insa.graph.Path; -import org.insa.graph.Point; -import org.insa.graphics.drawing.overlays.MarkerOverlay; -import org.insa.graphics.drawing.overlays.PathOverlay; -import org.insa.graphics.drawing.overlays.PointSetOverlay; +import org.insa.graphs.gui.drawing.overlays.MarkerOverlay; +import org.insa.graphs.gui.drawing.overlays.PathOverlay; +import org.insa.graphs.gui.drawing.overlays.PointSetOverlay; +import org.insa.graphs.model.Graph; +import org.insa.graphs.model.Path; +import org.insa.graphs.model.Point; public interface Drawing { diff --git a/src/main/org/insa/graphics/drawing/DrawingClickListener.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/DrawingClickListener.java similarity index 74% rename from src/main/org/insa/graphics/drawing/DrawingClickListener.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/DrawingClickListener.java index 496d841..fddfd9a 100644 --- a/src/main/org/insa/graphics/drawing/DrawingClickListener.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/DrawingClickListener.java @@ -1,14 +1,14 @@ -package org.insa.graphics.drawing; - -import org.insa.graph.Point; - -public interface DrawingClickListener { - - /** - * Event triggered when a click is made on the map. - * - * @param point Position (on the map) of the mouse click. - */ - public void mouseClicked(Point point); - -} +package org.insa.graphs.gui.drawing; + +import org.insa.graphs.model.Point; + +public interface DrawingClickListener { + + /** + * Event triggered when a click is made on the map. + * + * @param point Position (on the map) of the mouse click. + */ + public void mouseClicked(Point point); + +} diff --git a/src/main/org/insa/graphics/drawing/GraphPalette.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/GraphPalette.java similarity index 85% rename from src/main/org/insa/graphics/drawing/GraphPalette.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/GraphPalette.java index 78a2d1e..00af58d 100644 --- a/src/main/org/insa/graphics/drawing/GraphPalette.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/GraphPalette.java @@ -1,8 +1,8 @@ -package org.insa.graphics.drawing; +package org.insa.graphs.gui.drawing; import java.awt.Color; -import org.insa.graph.Arc; +import org.insa.graphs.model.Arc; public interface GraphPalette { diff --git a/src/main/org/insa/graphics/drawing/MercatorProjection.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/MercatorProjection.java similarity index 97% rename from src/main/org/insa/graphics/drawing/MercatorProjection.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/MercatorProjection.java index e393507..374c20d 100644 --- a/src/main/org/insa/graphics/drawing/MercatorProjection.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/MercatorProjection.java @@ -1,8 +1,8 @@ -package org.insa.graphics.drawing; +package org.insa.graphs.gui.drawing; import java.awt.Dimension; -import org.insa.graph.GraphStatistics.BoundingBox; +import org.insa.graphs.model.GraphStatistics.BoundingBox; public class MercatorProjection implements Projection { diff --git a/src/main/org/insa/graphics/drawing/PlateCarreProjection.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/PlateCarreProjection.java similarity index 95% rename from src/main/org/insa/graphics/drawing/PlateCarreProjection.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/PlateCarreProjection.java index bd3b9dd..0b15490 100644 --- a/src/main/org/insa/graphics/drawing/PlateCarreProjection.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/PlateCarreProjection.java @@ -1,6 +1,6 @@ -package org.insa.graphics.drawing; +package org.insa.graphs.gui.drawing; -import org.insa.graph.GraphStatistics.BoundingBox; +import org.insa.graphs.model.GraphStatistics.BoundingBox; public class PlateCarreProjection implements Projection { diff --git a/src/main/org/insa/graphics/drawing/Projection.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/Projection.java similarity index 97% rename from src/main/org/insa/graphics/drawing/Projection.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/Projection.java index 078991a..f05dd9c 100644 --- a/src/main/org/insa/graphics/drawing/Projection.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/Projection.java @@ -1,4 +1,4 @@ -package org.insa.graphics.drawing; +package org.insa.graphs.gui.drawing; public interface Projection { diff --git a/src/main/org/insa/graphics/drawing/components/BasicDrawing.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/components/BasicDrawing.java similarity index 96% rename from src/main/org/insa/graphics/drawing/components/BasicDrawing.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/components/BasicDrawing.java index 200665f..6d51a05 100644 --- a/src/main/org/insa/graphics/drawing/components/BasicDrawing.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/components/BasicDrawing.java @@ -1,4 +1,4 @@ -package org.insa.graphics.drawing.components; +package org.insa.graphs.gui.drawing.components; import java.awt.BasicStroke; import java.awt.Color; @@ -20,24 +20,24 @@ import java.util.List; import javax.swing.JPanel; -import org.insa.graph.Arc; -import org.insa.graph.Graph; -import org.insa.graph.GraphStatistics.BoundingBox; -import org.insa.graph.Node; -import org.insa.graph.Path; -import org.insa.graph.Point; -import org.insa.graphics.drawing.BasicGraphPalette; -import org.insa.graphics.drawing.Drawing; -import org.insa.graphics.drawing.DrawingClickListener; -import org.insa.graphics.drawing.GraphPalette; -import org.insa.graphics.drawing.MercatorProjection; -import org.insa.graphics.drawing.PlateCarreProjection; -import org.insa.graphics.drawing.Projection; -import org.insa.graphics.drawing.overlays.MarkerOverlay; -import org.insa.graphics.drawing.overlays.MarkerUtils; -import org.insa.graphics.drawing.overlays.Overlay; -import org.insa.graphics.drawing.overlays.PathOverlay; -import org.insa.graphics.drawing.overlays.PointSetOverlay; +import org.insa.graphs.gui.drawing.BasicGraphPalette; +import org.insa.graphs.gui.drawing.Drawing; +import org.insa.graphs.gui.drawing.DrawingClickListener; +import org.insa.graphs.gui.drawing.GraphPalette; +import org.insa.graphs.gui.drawing.MercatorProjection; +import org.insa.graphs.gui.drawing.PlateCarreProjection; +import org.insa.graphs.gui.drawing.Projection; +import org.insa.graphs.gui.drawing.overlays.MarkerOverlay; +import org.insa.graphs.gui.drawing.overlays.MarkerUtils; +import org.insa.graphs.gui.drawing.overlays.Overlay; +import org.insa.graphs.gui.drawing.overlays.PathOverlay; +import org.insa.graphs.gui.drawing.overlays.PointSetOverlay; +import org.insa.graphs.model.Arc; +import org.insa.graphs.model.Graph; +import org.insa.graphs.model.Node; +import org.insa.graphs.model.Path; +import org.insa.graphs.model.Point; +import org.insa.graphs.model.GraphStatistics.BoundingBox; /** * diff --git a/src/main/org/insa/graphics/drawing/components/MapViewDrawing.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/components/MapViewDrawing.java similarity index 82% rename from src/main/org/insa/graphics/drawing/components/MapViewDrawing.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/components/MapViewDrawing.java index d28aa4f..604a6db 100644 --- a/src/main/org/insa/graphics/drawing/components/MapViewDrawing.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/components/MapViewDrawing.java @@ -1,465 +1,521 @@ -package org.insa.graphics.drawing.components; - -import java.awt.Color; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.UUID; - -import org.insa.graph.Arc; -import org.insa.graph.Graph; -import org.insa.graph.Path; -import org.insa.graph.Point; -import org.insa.graphics.drawing.Drawing; -import org.insa.graphics.drawing.DrawingClickListener; -import org.insa.graphics.drawing.GraphPalette; -import org.insa.graphics.drawing.overlays.MarkerAutoScaling; -import org.insa.graphics.drawing.overlays.MarkerOverlay; -import org.insa.graphics.drawing.overlays.MarkerUtils; -import org.insa.graphics.drawing.overlays.Overlay; -import org.insa.graphics.drawing.overlays.PathOverlay; -import org.insa.graphics.drawing.overlays.PointSetOverlay; -import org.insa.graphics.drawing.overlays.PolylineAutoScaling; -import org.mapsforge.core.graphics.GraphicFactory; -import org.mapsforge.core.model.BoundingBox; -import org.mapsforge.core.model.LatLong; -import org.mapsforge.core.model.MapPosition; -import org.mapsforge.core.util.LatLongUtils; -import org.mapsforge.core.util.Parameters; -import org.mapsforge.map.awt.graphics.AwtGraphicFactory; -import org.mapsforge.map.awt.util.AwtUtil; -import org.mapsforge.map.awt.view.MapView; -import org.mapsforge.map.datastore.MapDataStore; -import org.mapsforge.map.layer.Layer; -import org.mapsforge.map.layer.Layers; -import org.mapsforge.map.layer.cache.TileCache; -import org.mapsforge.map.layer.hills.HillsRenderConfig; -import org.mapsforge.map.layer.overlay.Marker; -import org.mapsforge.map.layer.renderer.TileRendererLayer; -import org.mapsforge.map.model.DisplayModel; -import org.mapsforge.map.model.MapViewPosition; -import org.mapsforge.map.model.Model; -import org.mapsforge.map.reader.MapFile; -import org.mapsforge.map.rendertheme.InternalRenderTheme; - -/** - * - */ -public class MapViewDrawing extends MapView implements Drawing { - - /** - * - */ - private static final long serialVersionUID = 8606967833704938092L; - - /** - * Base Overlay for MapViewDrawing overlays. - * - */ - private abstract class MapViewOverlay implements Overlay { - - // Marker associated. - protected Layer[] layers; - - // Current color - protected Color color; - - public MapViewOverlay(Layer[] layers, Color color) { - this.layers = layers; - for (Layer layer: this.layers) { - MapViewDrawing.this.getLayerManager().getLayers().add(layer); - } - this.color = color; - } - - @Override - public void setColor(Color color) { - this.color = color; - } - - @Override - public Color getColor() { - return this.color; - } - - @Override - public void setVisible(boolean visible) { - for (Layer layer: layers) { - layer.setVisible(visible); - } - } - - @Override - public boolean isVisible() { - if (this.layers.length == 0) { - return true; - } - return this.layers[0].isVisible(); - } - - @Override - public void delete() { - Layers mlayers = MapViewDrawing.this.getLayerManager().getLayers(); - for (Layer layer: layers) { - mlayers.remove(layer); - } - } - - @Override - public void redraw() { - MapViewDrawing.this.getLayerManager().redrawLayers(); - } - }; - - /** - * MarkerOverlay for MapViewDrawing. - * - */ - private class MapViewMarkerOverlay extends MapViewOverlay implements MarkerOverlay { - - private final AlphaMode alphaMode; - private Color innerColor; - - public MapViewMarkerOverlay(Marker marker, Color outer, Color innerColor, - AlphaMode alphaMode) { - super(new Layer[] { marker }, outer); - this.innerColor = innerColor; - this.alphaMode = alphaMode; - } - - @Override - public Point getPoint() { - Marker marker = (Marker) super.layers[0]; - return new Point((float) marker.getLatLong().getLongitude(), - (float) marker.getLatLong().getLatitude()); - } - - @Override - public void setColor(Color outer) { - this.innerColor = this.innerColor.equals(this.color) ? outer : this.innerColor; - super.setColor(color); - MarkerAutoScaling marker = (MarkerAutoScaling) super.layers[0]; - marker.setImage(MarkerUtils.getMarkerForColor(color, this.innerColor, this.alphaMode)); - } - - @Override - public void moveTo(Point point) { - MarkerAutoScaling marker = (MarkerAutoScaling) this.layers[0]; - this.delete(); - marker = new MarkerAutoScaling(convertPoint(point), marker.getImage()); - this.layers[0] = marker; - MapViewDrawing.this.getLayerManager().getLayers().add(marker); - } - - }; - - /** - * PathOverlay for MapViewDrawing. - * - */ - private class MapViewPathOverlay extends MapViewOverlay implements PathOverlay { - - public MapViewPathOverlay(PolylineAutoScaling path, MarkerAutoScaling origin, - MarkerAutoScaling destination) { - super(new Layer[] { path, origin, destination }, path.getColor()); - } - - public MapViewPathOverlay(PolylineAutoScaling path) { - super(new Layer[] { path }, path.getColor()); - } - - @Override - public void setColor(Color color) { - super.setColor(color); - ((PolylineAutoScaling) this.layers[0]).setColor(color); - ((MarkerAutoScaling) this.layers[1]) - .setImage(MarkerUtils.getMarkerForColor(color, color, AlphaMode.TRANSPARENT)); - ((MarkerAutoScaling) this.layers[2]) - .setImage(MarkerUtils.getMarkerForColor(color, color, AlphaMode.TRANSPARENT)); - } - - } - - /** - * PointSetOverlay for MapViewDrawing - Not currently implemented. - * - */ - private class MapViewPointSetOverlay extends MapViewOverlay implements PointSetOverlay { - - public MapViewPointSetOverlay() { - super(new Layer[0], Color.BLACK); - } - - @Override - public void setWidth(int width) { - } - - @Override - public void setWidthAndColor(int width, Color color) { - setWidth(width); - setColor(color); - } - - @Override - public void addPoint(Point point) { - } - - @Override - public void addPoint(Point point, int width) { - setWidth(width); - addPoint(point); - } - - @Override - public void addPoint(Point point, Color color) { - setColor(color); - addPoint(point); - } - - @Override - public void addPoint(Point point, int width, Color color) { - setWidth(width); - setColor(color); - addPoint(point); - } - - }; - - // Default path color. - public static final Color DEFAULT_PATH_COLOR = new Color(66, 134, 244); - - // Graphic factory. - private static final GraphicFactory GRAPHIC_FACTORY = AwtGraphicFactory.INSTANCE; - - // Default tile size. - private static final int DEFAULT_TILE_SIZE = 512; - - // List of listeners. - private ArrayList drawingClickListeners = new ArrayList<>(); - - // Tile size - private int tileSize; - - // Zoom controls - private MapZoomControls zoomControls; - - public MapViewDrawing() { - super(); - Parameters.NUMBER_OF_THREADS = 2; - Parameters.SQUARE_FRAME_BUFFER = false; - - getMapScaleBar().setVisible(true); - DisplayModel model = getModel().displayModel; - this.tileSize = DEFAULT_TILE_SIZE; - model.setFixedTileSize(this.tileSize); - - this.setZoomLevelMin((byte) 0); - this.setZoomLevelMax((byte) 20); - - // Try... - try { - this.zoomControls = new MapZoomControls(this, 0, 0, 20); - this.zoomControls.addZoomInListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - getModel().mapViewPosition.zoomIn(); - } - }); - this.zoomControls.addZoomOutListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - getModel().mapViewPosition.zoomOut(); - } - }); - } - catch (IOException e) { - e.printStackTrace(); - } - } - - /* - * (non-Javadoc) - * - * @see org.mapsforge.map.awt.view.MapView#paint(java.awt.Graphics) - */ - @Override - public void paint(Graphics graphics) { - super.paint(graphics); - if (this.zoomControls != null) { - this.zoomControls.setZoomLevel(this.getModel().mapViewPosition.getZoomLevel()); - this.zoomControls.draw((Graphics2D) graphics, - getWidth() - this.zoomControls.getWidth() - 20, - this.getHeight() - this.zoomControls.getHeight() - 10, this); - } - - } - - /* - * (non-Javadoc) - * - * @see org.insa.graphics.drawing.Drawing#clear() - */ - @Override - public void clear() { - getLayerManager().getLayers().clear(); - repaint(); - } - - /* - * (non-Javadoc) - * - * @see org.insa.graphics.drawing.Drawing#clearOverlays() - */ - @Override - public void clearOverlays() { - Layers layers = getLayerManager().getLayers(); - for (Layer layer: layers) { - if (layer instanceof PolylineAutoScaling || layer instanceof MarkerAutoScaling) { - getLayerManager().getLayers().remove(layer, false); - } - } - repaint(); - } - - protected LatLong convertPoint(Point point) { - return new LatLong(point.getLatitude(), point.getLongitude()); - } - - private TileRendererLayer createTileRendererLayer(TileCache tileCache, - MapDataStore mapDataStore, MapViewPosition mapViewPosition, - HillsRenderConfig hillsRenderConfig) { - TileRendererLayer tileRendererLayer = new TileRendererLayer(tileCache, mapDataStore, - mapViewPosition, false, true, false, GRAPHIC_FACTORY, hillsRenderConfig) { - @Override - public boolean onTap(LatLong tapLatLong, org.mapsforge.core.model.Point layerXY, - org.mapsforge.core.model.Point tapXY) { - if (zoomControls.contains(new java.awt.Point((int) tapXY.x, (int) tapXY.y))) { - return false; - } - Point pt = new Point((float) tapLatLong.getLongitude(), - (float) tapLatLong.getLatitude()); - for (DrawingClickListener listener: MapViewDrawing.this.drawingClickListeners) { - listener.mouseClicked(pt); - } - return true; - } - }; - tileRendererLayer.setXmlRenderTheme(InternalRenderTheme.DEFAULT); - return tileRendererLayer; - } - - @Override - public void addDrawingClickListener(DrawingClickListener listener) { - this.drawingClickListeners.add(listener); - } - - @Override - public void removeDrawingClickListener(DrawingClickListener listener) { - this.drawingClickListeners.remove(listener); - } - - protected MarkerAutoScaling createMarker(Point point, Color outer, Color inner, - AlphaMode mode) { - Image image = MarkerUtils.getMarkerForColor(outer, inner, mode); - return new MarkerAutoScaling(convertPoint(point), image); - } - - @Override - public MarkerOverlay drawMarker(Point point, Color outer, Color inner, AlphaMode mode) { - return new MapViewMarkerOverlay(createMarker(point, outer, inner, mode), outer, inner, - mode); - } - - @Override - public PointSetOverlay createPointSetOverlay() { - return new MapViewPointSetOverlay(); - } - - @Override - public PointSetOverlay createPointSetOverlay(int width, Color color) { - PointSetOverlay ps = new MapViewPointSetOverlay(); - ps.setWidthAndColor(width, color); - return ps; - } - - public void drawGraph(File file) { - - // Tile cache - TileCache tileCache = AwtUtil.createTileCache(tileSize, - getModel().frameBufferModel.getOverdrawFactor(), 1024, - new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString())); - - // Layers - Layers layers = getLayerManager().getLayers(); - - MapDataStore mapDataStore = new MapFile(file); - TileRendererLayer tileRendererLayer = createTileRendererLayer(tileCache, mapDataStore, - getModel().mapViewPosition, null); - layers.add(tileRendererLayer); - BoundingBox boundingBox = mapDataStore.boundingBox(); - - final Model model = getModel(); - if (model.mapViewPosition.getZoomLevel() == 0 - || !boundingBox.contains(model.mapViewPosition.getCenter())) { - byte zoomLevel = LatLongUtils.zoomForBounds(model.mapViewDimension.getDimension(), - boundingBox, model.displayModel.getTileSize()); - model.mapViewPosition - .setMapPosition(new MapPosition(boundingBox.getCenterPoint(), zoomLevel)); - zoomControls.setZoomLevel(zoomLevel); - } - - } - - @Override - public void drawGraph(Graph graph, GraphPalette palette) { - throw new RuntimeException("Not implemented, use drawGraph(File)."); - } - - @Override - public void drawGraph(Graph graph) { - throw new RuntimeException("Not implemented, use drawGraph(File)."); - } - - @Override - public PathOverlay drawPath(Path path, Color color, boolean markers) { - PolylineAutoScaling line = new PolylineAutoScaling(1, color); - ArrayList points = new ArrayList<>(path.getArcs().size() * 4); - for (Arc arc: path.getArcs()) { - points.addAll(arc.getPoints()); - } - line.addAll(points); - PathOverlay overlay = null; - if (markers) { - MarkerAutoScaling origin = createMarker(path.getOrigin().getPoint(), color, color, - AlphaMode.TRANSPARENT), - destination = createMarker(path.getDestination().getPoint(), color, color, - AlphaMode.TRANSPARENT); - overlay = new MapViewPathOverlay(line, origin, destination); - } - else { - overlay = new MapViewPathOverlay(line); - } - return overlay; - } - - @Override - public PathOverlay drawPath(Path path, Color color) { - return drawPath(path, color, true); - } - - @Override - public PathOverlay drawPath(Path path) { - return drawPath(path, DEFAULT_PATH_COLOR, true); - } - - @Override - public PathOverlay drawPath(Path path, boolean markers) { - return drawPath(path, DEFAULT_PATH_COLOR, markers); - } - -} +package org.insa.graphs.gui.drawing.components; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +import org.insa.graphs.gui.drawing.Drawing; +import org.insa.graphs.gui.drawing.DrawingClickListener; +import org.insa.graphs.gui.drawing.GraphPalette; +import org.insa.graphs.gui.drawing.overlays.MarkerAutoScaling; +import org.insa.graphs.gui.drawing.overlays.MarkerOverlay; +import org.insa.graphs.gui.drawing.overlays.MarkerUtils; +import org.insa.graphs.gui.drawing.overlays.Overlay; +import org.insa.graphs.gui.drawing.overlays.PathOverlay; +import org.insa.graphs.gui.drawing.overlays.PointSetOverlay; +import org.insa.graphs.gui.drawing.overlays.PolylineAutoScaling; +import org.insa.graphs.model.Arc; +import org.insa.graphs.model.Graph; +import org.insa.graphs.model.Path; +import org.insa.graphs.model.Point; +import org.mapsforge.core.graphics.GraphicFactory; +import org.mapsforge.core.model.BoundingBox; +import org.mapsforge.core.model.LatLong; +import org.mapsforge.core.model.MapPosition; +import org.mapsforge.core.util.LatLongUtils; +import org.mapsforge.core.util.Parameters; +import org.mapsforge.map.awt.graphics.AwtGraphicFactory; +import org.mapsforge.map.awt.util.AwtUtil; +import org.mapsforge.map.awt.view.MapView; +import org.mapsforge.map.datastore.MapDataStore; +import org.mapsforge.map.layer.Layer; +import org.mapsforge.map.layer.Layers; +import org.mapsforge.map.layer.cache.TileCache; +import org.mapsforge.map.layer.hills.HillsRenderConfig; +import org.mapsforge.map.layer.overlay.Marker; +import org.mapsforge.map.layer.overlay.Polygon; +import org.mapsforge.map.layer.renderer.TileRendererLayer; +import org.mapsforge.map.model.DisplayModel; +import org.mapsforge.map.model.IMapViewPosition; +import org.mapsforge.map.model.Model; +import org.mapsforge.map.reader.MapFile; +import org.mapsforge.map.rendertheme.InternalRenderTheme; + +/** + * + */ +public class MapViewDrawing extends MapView implements Drawing { + + /** + * + */ + private static final long serialVersionUID = 8606967833704938092L; + + /** + * Base Overlay for MapViewDrawing overlays. + * + */ + private abstract class MapViewOverlay implements Overlay { + + // Marker associated. + protected Layer[] layers; + + // Current color + protected Color color; + + public MapViewOverlay(Layer[] layers, Color color) { + this.layers = layers; + for (Layer layer: this.layers) { + MapViewDrawing.this.getLayerManager().getLayers().add(layer); + } + this.color = color; + } + + @Override + public void setColor(Color color) { + this.color = color; + } + + @Override + public Color getColor() { + return this.color; + } + + @Override + public void setVisible(boolean visible) { + for (Layer layer: layers) { + layer.setVisible(visible); + } + } + + @Override + public boolean isVisible() { + if (this.layers.length == 0) { + return true; + } + return this.layers[0].isVisible(); + } + + @Override + public void delete() { + Layers mlayers = MapViewDrawing.this.getLayerManager().getLayers(); + for (Layer layer: layers) { + mlayers.remove(layer); + } + } + + @Override + public void redraw() { + MapViewDrawing.this.getLayerManager().redrawLayers(); + } + }; + + /** + * MarkerOverlay for MapViewDrawing. + * + */ + private class MapViewMarkerOverlay extends MapViewOverlay implements MarkerOverlay { + + private final AlphaMode alphaMode; + private Color innerColor; + + public MapViewMarkerOverlay(Marker marker, Color outer, Color innerColor, + AlphaMode alphaMode) { + super(new Layer[] { marker }, outer); + this.innerColor = innerColor; + this.alphaMode = alphaMode; + } + + @Override + public Point getPoint() { + Marker marker = (Marker) super.layers[0]; + return new Point((float) marker.getLatLong().getLongitude(), + (float) marker.getLatLong().getLatitude()); + } + + @Override + public void setColor(Color outer) { + this.innerColor = this.innerColor.equals(this.color) ? outer : this.innerColor; + super.setColor(color); + MarkerAutoScaling marker = (MarkerAutoScaling) super.layers[0]; + marker.setImage(MarkerUtils.getMarkerForColor(color, this.innerColor, this.alphaMode)); + } + + @Override + public void moveTo(Point point) { + MarkerAutoScaling marker = (MarkerAutoScaling) this.layers[0]; + this.delete(); + marker = new MarkerAutoScaling(convertPoint(point), marker.getImage()); + this.layers[0] = marker; + MapViewDrawing.this.getLayerManager().getLayers().add(marker); + } + + }; + + /** + * PathOverlay for MapViewDrawing. + * + */ + private class MapViewPathOverlay extends MapViewOverlay implements PathOverlay { + + public MapViewPathOverlay(PolylineAutoScaling path, MarkerAutoScaling origin, + MarkerAutoScaling destination) { + super(new Layer[] { path, origin, destination }, path.getColor()); + } + + public MapViewPathOverlay(PolylineAutoScaling path) { + super(new Layer[] { path }, path.getColor()); + } + + @Override + public void setColor(Color color) { + super.setColor(color); + ((PolylineAutoScaling) this.layers[0]).setColor(color); + ((MarkerAutoScaling) this.layers[1]) + .setImage(MarkerUtils.getMarkerForColor(color, color, AlphaMode.TRANSPARENT)); + ((MarkerAutoScaling) this.layers[2]) + .setImage(MarkerUtils.getMarkerForColor(color, color, AlphaMode.TRANSPARENT)); + } + + } + + /** + * PointSetOverlay for MapViewDrawing - Not currently implemented. + * + */ + private class MapViewPointSetOverlay extends MapViewOverlay implements PointSetOverlay { + + private List points = new ArrayList<>(); + private final Polygon polygon; + + private List convexHull(List p) { + if (p.isEmpty()) { + return new ArrayList<>(); + } + p.sort((p1, p2) -> Float.compare(p1.getLongitude(), p2.getLongitude())); + List h = new ArrayList<>(); + + // lower hull + for (Point pt: p) { + while (h.size() >= 2 && !ccw(h.get(h.size() - 2), h.get(h.size() - 1), pt)) { + h.remove(h.size() - 1); + } + h.add(pt); + } + + // upper hull + int t = h.size() + 1; + for (int i = p.size() - 1; i >= 0; i--) { + Point pt = p.get(i); + while (h.size() >= t && !ccw(h.get(h.size() - 2), h.get(h.size() - 1), pt)) { + h.remove(h.size() - 1); + } + h.add(pt); + } + + h.remove(h.size() - 1); + return h; + } + + // ccw returns true if the three points make a counter-clockwise turn + private boolean ccw(Point a, Point b, Point c) { + return ((b.getLongitude() - a.getLongitude()) + * (c.getLatitude() - a.getLatitude())) > ((b.getLatitude() - a.getLatitude()) + * (c.getLongitude() - a.getLongitude())); + } + + public MapViewPointSetOverlay() { + super(new Layer[] { new Polygon(GRAPHIC_FACTORY.createPaint(), null, GRAPHIC_FACTORY) }, + Color.BLACK); + polygon = (Polygon) this.layers[0]; + } + + @Override + public void setColor(Color color) { + super.setColor(color); + polygon.getPaintFill().setColor(GRAPHIC_FACTORY.createColor(100, color.getRed(), + color.getGreen(), color.getBlue())); + } + + @Override + public void setWidth(int width) { + } + + @Override + public void setWidthAndColor(int width, Color color) { + setWidth(width); + setColor(color); + } + + @Override + public void addPoint(Point point) { + points.add(point); + this.points = convexHull(points); + polygon.setPoints(this.points.stream().map(MapViewDrawing.this::convertPoint) + .collect(Collectors.toList())); + polygon.requestRedraw(); + } + + @Override + public void addPoint(Point point, int width) { + setWidth(width); + addPoint(point); + } + + @Override + public void addPoint(Point point, Color color) { + setColor(color); + addPoint(point); + } + + @Override + public void addPoint(Point point, int width, Color color) { + setWidth(width); + setColor(color); + addPoint(point); + } + + }; + + // Default path color. + public static final Color DEFAULT_PATH_COLOR = new Color(66, 134, 244); + + // Graphic factory. + private static final GraphicFactory GRAPHIC_FACTORY = AwtGraphicFactory.INSTANCE; + + // Default tile size. + private static final int DEFAULT_TILE_SIZE = 512; + + // List of listeners. + private ArrayList drawingClickListeners = new ArrayList<>(); + + // Tile size + private int tileSize; + + // Zoom controls + private MapZoomControls zoomControls; + + public MapViewDrawing() { + super(); + Parameters.NUMBER_OF_THREADS = 2; + Parameters.SQUARE_FRAME_BUFFER = false; + + getMapScaleBar().setVisible(true); + DisplayModel model = getModel().displayModel; + this.tileSize = DEFAULT_TILE_SIZE; + model.setFixedTileSize(this.tileSize); + + this.setZoomLevelMin((byte) 0); + this.setZoomLevelMax((byte) 20); + + // Try... + try { + this.zoomControls = new MapZoomControls(this, 0, 0, 20); + this.zoomControls.addZoomInListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + getModel().mapViewPosition.zoomIn(); + } + }); + this.zoomControls.addZoomOutListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + getModel().mapViewPosition.zoomOut(); + } + }); + } + catch (IOException e) { + e.printStackTrace(); + } + } + + /* + * (non-Javadoc) + * + * @see org.mapsforge.map.awt.view.MapView#paint(java.awt.Graphics) + */ + @Override + public void paint(Graphics graphics) { + super.paint(graphics); + if (this.zoomControls != null) { + this.zoomControls.setZoomLevel(this.getModel().mapViewPosition.getZoomLevel()); + this.zoomControls.draw((Graphics2D) graphics, + getWidth() - this.zoomControls.getWidth() - 20, + this.getHeight() - this.zoomControls.getHeight() - 10, this); + } + + } + + /* + * (non-Javadoc) + * + * @see org.insa.graphics.drawing.Drawing#clear() + */ + @Override + public void clear() { + getLayerManager().getLayers().clear(); + repaint(); + } + + /* + * (non-Javadoc) + * + * @see org.insa.graphics.drawing.Drawing#clearOverlays() + */ + @Override + public void clearOverlays() { + Layers layers = getLayerManager().getLayers(); + for (Layer layer: layers) { + if (layer instanceof PolylineAutoScaling || layer instanceof MarkerAutoScaling) { + getLayerManager().getLayers().remove(layer, false); + } + } + repaint(); + } + + protected LatLong convertPoint(Point point) { + return new LatLong(point.getLatitude(), point.getLongitude()); + } + + private TileRendererLayer createTileRendererLayer(TileCache tileCache, + MapDataStore mapDataStore, IMapViewPosition mapViewPosition, + HillsRenderConfig hillsRenderConfig) { + TileRendererLayer tileRendererLayer = new TileRendererLayer(tileCache, mapDataStore, + mapViewPosition, false, true, false, GRAPHIC_FACTORY, hillsRenderConfig) { + @Override + public boolean onTap(LatLong tapLatLong, org.mapsforge.core.model.Point layerXY, + org.mapsforge.core.model.Point tapXY) { + if (zoomControls.contains(new java.awt.Point((int) tapXY.x, (int) tapXY.y))) { + return false; + } + Point pt = new Point((float) tapLatLong.getLongitude(), + (float) tapLatLong.getLatitude()); + for (DrawingClickListener listener: MapViewDrawing.this.drawingClickListeners) { + listener.mouseClicked(pt); + } + return true; + } + }; + tileRendererLayer.setXmlRenderTheme(InternalRenderTheme.DEFAULT); + return tileRendererLayer; + } + + @Override + public void addDrawingClickListener(DrawingClickListener listener) { + this.drawingClickListeners.add(listener); + } + + @Override + public void removeDrawingClickListener(DrawingClickListener listener) { + this.drawingClickListeners.remove(listener); + } + + protected MarkerAutoScaling createMarker(Point point, Color outer, Color inner, + AlphaMode mode) { + Image image = MarkerUtils.getMarkerForColor(outer, inner, mode); + return new MarkerAutoScaling(convertPoint(point), image); + } + + @Override + public MarkerOverlay drawMarker(Point point, Color outer, Color inner, AlphaMode mode) { + return new MapViewMarkerOverlay(createMarker(point, outer, inner, mode), outer, inner, + mode); + } + + @Override + public PointSetOverlay createPointSetOverlay() { + return new MapViewPointSetOverlay(); + } + + @Override + public PointSetOverlay createPointSetOverlay(int width, Color color) { + PointSetOverlay ps = new MapViewPointSetOverlay(); + ps.setWidthAndColor(width, color); + return ps; + } + + public void drawGraph(File file) { + + // Tile cache + TileCache tileCache = AwtUtil.createTileCache(tileSize, + getModel().frameBufferModel.getOverdrawFactor(), 1024, + new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString())); + + // Layers + Layers layers = getLayerManager().getLayers(); + + MapDataStore mapDataStore = new MapFile(file); + TileRendererLayer tileRendererLayer = createTileRendererLayer(tileCache, mapDataStore, + getModel().mapViewPosition, null); + layers.add(tileRendererLayer); + BoundingBox boundingBox = mapDataStore.boundingBox(); + + final Model model = getModel(); + if (model.mapViewPosition.getZoomLevel() == 0 + || !boundingBox.contains(model.mapViewPosition.getCenter())) { + byte zoomLevel = LatLongUtils.zoomForBounds(model.mapViewDimension.getDimension(), + boundingBox, model.displayModel.getTileSize()); + model.mapViewPosition + .setMapPosition(new MapPosition(boundingBox.getCenterPoint(), zoomLevel)); + zoomControls.setZoomLevel(zoomLevel); + } + + } + + @Override + public void drawGraph(Graph graph, GraphPalette palette) { + throw new RuntimeException("Not implemented, use drawGraph(File)."); + } + + @Override + public void drawGraph(Graph graph) { + throw new RuntimeException("Not implemented, use drawGraph(File)."); + } + + @Override + public PathOverlay drawPath(Path path, Color color, boolean markers) { + PolylineAutoScaling line = new PolylineAutoScaling(1, color); + ArrayList points = new ArrayList<>(path.getArcs().size() * 4); + for (Arc arc: path.getArcs()) { + points.addAll(arc.getPoints()); + } + line.addAll(points); + PathOverlay overlay = null; + if (markers) { + MarkerAutoScaling origin = createMarker(path.getOrigin().getPoint(), color, color, + AlphaMode.TRANSPARENT), + destination = createMarker(path.getDestination().getPoint(), color, color, + AlphaMode.TRANSPARENT); + overlay = new MapViewPathOverlay(line, origin, destination); + } + else { + overlay = new MapViewPathOverlay(line); + } + return overlay; + } + + @Override + public PathOverlay drawPath(Path path, Color color) { + return drawPath(path, color, true); + } + + @Override + public PathOverlay drawPath(Path path) { + return drawPath(path, DEFAULT_PATH_COLOR, true); + } + + @Override + public PathOverlay drawPath(Path path, boolean markers) { + return drawPath(path, DEFAULT_PATH_COLOR, markers); + } + +} diff --git a/src/main/org/insa/graphics/drawing/components/MapZoomControls.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/components/MapZoomControls.java similarity index 99% rename from src/main/org/insa/graphics/drawing/components/MapZoomControls.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/components/MapZoomControls.java index 05447c4..0db6628 100644 --- a/src/main/org/insa/graphics/drawing/components/MapZoomControls.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/components/MapZoomControls.java @@ -1,4 +1,4 @@ -package org.insa.graphics.drawing.components; +package org.insa.graphs.gui.drawing.components; import java.awt.BasicStroke; import java.awt.Color; diff --git a/src/main/org/insa/graphics/drawing/components/ZoomAndPanListener.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/components/ZoomAndPanListener.java similarity index 99% rename from src/main/org/insa/graphics/drawing/components/ZoomAndPanListener.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/components/ZoomAndPanListener.java index 041061f..fc43671 100644 --- a/src/main/org/insa/graphics/drawing/components/ZoomAndPanListener.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/components/ZoomAndPanListener.java @@ -1,4 +1,4 @@ -package org.insa.graphics.drawing.components; +package org.insa.graphs.gui.drawing.components; import java.awt.Component; import java.awt.Point; diff --git a/src/main/org/insa/graphics/drawing/overlays/MarkerAutoScaling.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/MarkerAutoScaling.java similarity index 98% rename from src/main/org/insa/graphics/drawing/overlays/MarkerAutoScaling.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/MarkerAutoScaling.java index d512b59..6d6b097 100644 --- a/src/main/org/insa/graphics/drawing/overlays/MarkerAutoScaling.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/MarkerAutoScaling.java @@ -1,4 +1,4 @@ -package org.insa.graphics.drawing.overlays; +package org.insa.graphs.gui.drawing.overlays; import java.awt.Graphics2D; import java.awt.Image; diff --git a/src/main/org/insa/graphics/drawing/overlays/MarkerOverlay.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/MarkerOverlay.java similarity index 79% rename from src/main/org/insa/graphics/drawing/overlays/MarkerOverlay.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/MarkerOverlay.java index 23baf29..75b01b5 100644 --- a/src/main/org/insa/graphics/drawing/overlays/MarkerOverlay.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/MarkerOverlay.java @@ -1,6 +1,6 @@ -package org.insa.graphics.drawing.overlays; +package org.insa.graphs.gui.drawing.overlays; -import org.insa.graph.Point; +import org.insa.graphs.model.Point; public interface MarkerOverlay extends Overlay { diff --git a/src/main/org/insa/graphics/drawing/overlays/MarkerUtils.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/MarkerUtils.java similarity index 95% rename from src/main/org/insa/graphics/drawing/overlays/MarkerUtils.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/MarkerUtils.java index 5af89ca..523d5d9 100644 --- a/src/main/org/insa/graphics/drawing/overlays/MarkerUtils.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/MarkerUtils.java @@ -1,97 +1,97 @@ -package org.insa.graphics.drawing.overlays; - -import java.awt.Color; -import java.awt.Image; -import java.awt.image.BufferedImage; -import java.io.DataInputStream; - -import org.insa.graphics.drawing.Drawing.AlphaMode; - -public class MarkerUtils { - - /** - * Create an image to represent a marker using the given color for the outer and - * inner part, and the given mode for the inner part. - * - * @param outer Outer color of the marker. - * @param inner Inner color of the marker. - * @param mode Mode to use to fill the inner part of the marker. - * - * @return An image representing a marker. - */ - public static Image getMarkerForColor(Color outer, Color inner, AlphaMode mode) { - // create image - int[][] mask = readMarkerMask(); - BufferedImage image = new BufferedImage(mask[0].length, mask.length, - BufferedImage.TYPE_4BYTE_ABGR); - - // Color[] map = getColorMapping(color); - int outerRGB = outer.getRGB() & 0x00ffffff; - for (int i = 0; i < image.getHeight(); ++i) { - for (int j = 0; j < image.getWidth(); ++j) { - - // If we are in the "inner" part of the marker... - if (i >= MIN_Y_CENTER && i < MAX_Y_CENTER && j >= MIN_X_CENTER && j < MAX_X_CENTER - && mask[i][j] != MAXIMUM_INNER_MASK_VALUE) { - // Don't ask... https://stackoverflow.com/a/29321264/2666289 - // Basically, this compute a "middle" color between outer and inner depending on - // the current mask value. - double t = 1 - (mask[i][j] - MINIMUM_INNER_MASK_VALUE) - / (double) (MAXIMUM_INNER_MASK_VALUE - MINIMUM_INNER_MASK_VALUE); - int r = (int) Math.sqrt((1 - t) * outer.getRed() * outer.getRed() - + t * inner.getRed() * inner.getRed()); - int g = (int) Math.sqrt((1 - t) * outer.getGreen() * outer.getGreen() - + t * inner.getGreen() * inner.getGreen()); - int b = (int) Math.sqrt((1 - t) * outer.getBlue() * outer.getBlue() - + t * inner.getBlue() * inner.getBlue()); - int a = mode == AlphaMode.OPAQUE ? MAXIMUM_INNER_MASK_VALUE : mask[i][j]; - image.setRGB(j, i, (a << 24) | (r << 16) | (g << 8) | b); - } - // Otherwize, just fill with the outer color and set the alpha value properly. - else { - image.setRGB(j, i, outerRGB | (mask[i][j] << 24)); - } - } - } - - return image; - } - - // Mask cache - private static int[][] MASK_CACHE = null; - - // Hand-made... These defines the "center" of the marker, that can be filled - // with a different color. - private static final int MIN_X_CENTER = 40, MAX_X_CENTER = 101, MIN_Y_CENTER = 40, - MAX_Y_CENTER = 100; - private static final int MINIMUM_INNER_MASK_VALUE = 116, MAXIMUM_INNER_MASK_VALUE = 249; - - /** - * @return Retrieve the mask from the mask file or from the cache. - */ - private static int[][] readMarkerMask() { - if (MASK_CACHE == null) { - try { - DataInputStream dis = new DataInputStream( - MarkerUtils.class.getResourceAsStream("/marker_mask.bin")); - - int nrows = dis.readInt(); - int ncols = dis.readInt(); - - MASK_CACHE = new int[nrows][ncols]; - for (int i = 0; i < nrows; ++i) { - for (int j = 0; j < ncols; ++j) { - MASK_CACHE[i][j] = dis.readUnsignedByte(); - } - } - dis.close(); - } - catch (Exception e) { - e.printStackTrace(); - MASK_CACHE = null; - } - } - return MASK_CACHE; - } - -} +package org.insa.graphs.gui.drawing.overlays; + +import java.awt.Color; +import java.awt.Image; +import java.awt.image.BufferedImage; +import java.io.DataInputStream; + +import org.insa.graphs.gui.drawing.Drawing.AlphaMode; + +public class MarkerUtils { + + /** + * Create an image to represent a marker using the given color for the outer and + * inner part, and the given mode for the inner part. + * + * @param outer Outer color of the marker. + * @param inner Inner color of the marker. + * @param mode Mode to use to fill the inner part of the marker. + * + * @return An image representing a marker. + */ + public static Image getMarkerForColor(Color outer, Color inner, AlphaMode mode) { + // create image + int[][] mask = readMarkerMask(); + BufferedImage image = new BufferedImage(mask[0].length, mask.length, + BufferedImage.TYPE_4BYTE_ABGR); + + // Color[] map = getColorMapping(color); + int outerRGB = outer.getRGB() & 0x00ffffff; + for (int i = 0; i < image.getHeight(); ++i) { + for (int j = 0; j < image.getWidth(); ++j) { + + // If we are in the "inner" part of the marker... + if (i >= MIN_Y_CENTER && i < MAX_Y_CENTER && j >= MIN_X_CENTER && j < MAX_X_CENTER + && mask[i][j] != MAXIMUM_INNER_MASK_VALUE) { + // Don't ask... https://stackoverflow.com/a/29321264/2666289 + // Basically, this compute a "middle" color between outer and inner depending on + // the current mask value. + double t = 1 - (mask[i][j] - MINIMUM_INNER_MASK_VALUE) + / (double) (MAXIMUM_INNER_MASK_VALUE - MINIMUM_INNER_MASK_VALUE); + int r = (int) Math.sqrt((1 - t) * outer.getRed() * outer.getRed() + + t * inner.getRed() * inner.getRed()); + int g = (int) Math.sqrt((1 - t) * outer.getGreen() * outer.getGreen() + + t * inner.getGreen() * inner.getGreen()); + int b = (int) Math.sqrt((1 - t) * outer.getBlue() * outer.getBlue() + + t * inner.getBlue() * inner.getBlue()); + int a = mode == AlphaMode.OPAQUE ? MAXIMUM_INNER_MASK_VALUE : mask[i][j]; + image.setRGB(j, i, (a << 24) | (r << 16) | (g << 8) | b); + } + // Otherwize, just fill with the outer color and set the alpha value properly. + else { + image.setRGB(j, i, outerRGB | (mask[i][j] << 24)); + } + } + } + + return image; + } + + // Mask cache + private static int[][] MASK_CACHE = null; + + // Hand-made... These defines the "center" of the marker, that can be filled + // with a different color. + private static final int MIN_X_CENTER = 40, MAX_X_CENTER = 101, MIN_Y_CENTER = 40, + MAX_Y_CENTER = 100; + private static final int MINIMUM_INNER_MASK_VALUE = 116, MAXIMUM_INNER_MASK_VALUE = 249; + + /** + * @return Retrieve the mask from the mask file or from the cache. + */ + private static int[][] readMarkerMask() { + if (MASK_CACHE == null) { + try { + DataInputStream dis = new DataInputStream( + MarkerUtils.class.getResourceAsStream("/marker_mask.bin")); + + int nrows = dis.readInt(); + int ncols = dis.readInt(); + + MASK_CACHE = new int[nrows][ncols]; + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < ncols; ++j) { + MASK_CACHE[i][j] = dis.readUnsignedByte(); + } + } + dis.close(); + } + catch (Exception e) { + e.printStackTrace(); + MASK_CACHE = null; + } + } + return MASK_CACHE; + } + +} diff --git a/src/main/org/insa/graphics/drawing/overlays/Overlay.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/Overlay.java similarity index 94% rename from src/main/org/insa/graphics/drawing/overlays/Overlay.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/Overlay.java index 26ad6b5..8815c57 100644 --- a/src/main/org/insa/graphics/drawing/overlays/Overlay.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/Overlay.java @@ -1,4 +1,4 @@ -package org.insa.graphics.drawing.overlays; +package org.insa.graphs.gui.drawing.overlays; import java.awt.Color; diff --git a/src/main/org/insa/graphics/drawing/overlays/PaintUtils.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/PaintUtils.java similarity index 97% rename from src/main/org/insa/graphics/drawing/overlays/PaintUtils.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/PaintUtils.java index 59413ed..a2c4929 100644 --- a/src/main/org/insa/graphics/drawing/overlays/PaintUtils.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/PaintUtils.java @@ -1,4 +1,4 @@ -package org.insa.graphics.drawing.overlays; +package org.insa.graphs.gui.drawing.overlays; import java.awt.Color; diff --git a/src/main/org/insa/graphics/drawing/overlays/PathOverlay.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/PathOverlay.java similarity index 52% rename from src/main/org/insa/graphics/drawing/overlays/PathOverlay.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/PathOverlay.java index b004456..9622967 100644 --- a/src/main/org/insa/graphics/drawing/overlays/PathOverlay.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/PathOverlay.java @@ -1,4 +1,4 @@ -package org.insa.graphics.drawing.overlays; +package org.insa.graphs.gui.drawing.overlays; public interface PathOverlay extends Overlay { diff --git a/src/main/org/insa/graphics/drawing/overlays/PointSetOverlay.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/PointSetOverlay.java similarity index 95% rename from src/main/org/insa/graphics/drawing/overlays/PointSetOverlay.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/PointSetOverlay.java index fbae987..ec105a6 100644 --- a/src/main/org/insa/graphics/drawing/overlays/PointSetOverlay.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/PointSetOverlay.java @@ -1,8 +1,8 @@ -package org.insa.graphics.drawing.overlays; +package org.insa.graphs.gui.drawing.overlays; import java.awt.Color; -import org.insa.graph.Point; +import org.insa.graphs.model.Point; public interface PointSetOverlay extends Overlay { diff --git a/src/main/org/insa/graphics/drawing/overlays/PolylineAutoScaling.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/PolylineAutoScaling.java similarity index 97% rename from src/main/org/insa/graphics/drawing/overlays/PolylineAutoScaling.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/PolylineAutoScaling.java index cbcec47..e18d0ae 100644 --- a/src/main/org/insa/graphics/drawing/overlays/PolylineAutoScaling.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/drawing/overlays/PolylineAutoScaling.java @@ -1,10 +1,10 @@ -package org.insa.graphics.drawing.overlays; +package org.insa.graphs.gui.drawing.overlays; import java.awt.Color; import java.util.ArrayList; import java.util.Collection; -import org.insa.graph.Point; +import org.insa.graphs.model.Point; import org.mapsforge.core.graphics.Canvas; import org.mapsforge.core.graphics.GraphicFactory; import org.mapsforge.core.graphics.Style; diff --git a/src/main/org/insa/algo/shortestpath/ShortestPathGraphicObserver.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/observers/ShortestPathGraphicObserver.java similarity index 79% rename from src/main/org/insa/algo/shortestpath/ShortestPathGraphicObserver.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/observers/ShortestPathGraphicObserver.java index 8079910..12963b4 100644 --- a/src/main/org/insa/algo/shortestpath/ShortestPathGraphicObserver.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/observers/ShortestPathGraphicObserver.java @@ -1,10 +1,11 @@ -package org.insa.algo.shortestpath; +package org.insa.graphs.gui.observers; import java.awt.Color; -import org.insa.graph.Node; -import org.insa.graphics.drawing.Drawing; -import org.insa.graphics.drawing.overlays.PointSetOverlay; +import org.insa.graphs.algorithm.shortestpath.ShortestPathObserver; +import org.insa.graphs.gui.drawing.Drawing; +import org.insa.graphs.gui.drawing.overlays.PointSetOverlay; +import org.insa.graphs.model.Node; public class ShortestPathGraphicObserver implements ShortestPathObserver { diff --git a/src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentGraphicObserver.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/observers/WeaklyConnectedComponentGraphicObserver.java similarity index 73% rename from src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentGraphicObserver.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/observers/WeaklyConnectedComponentGraphicObserver.java index 46e96b3..426e3ff 100644 --- a/src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentGraphicObserver.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/observers/WeaklyConnectedComponentGraphicObserver.java @@ -1,15 +1,17 @@ -package org.insa.algo.weakconnectivity; +package org.insa.graphs.gui.observers; import java.awt.Color; import java.util.ArrayList; -import org.insa.graph.Node; -import org.insa.graphics.drawing.Drawing; -import org.insa.graphics.drawing.overlays.PointSetOverlay; +import org.insa.graphs.algorithm.weakconnectivity.WeaklyConnectedComponentObserver; +import org.insa.graphs.gui.drawing.Drawing; +import org.insa.graphs.gui.drawing.overlays.PointSetOverlay; +import org.insa.graphs.model.Node; public class WeaklyConnectedComponentGraphicObserver implements WeaklyConnectedComponentObserver { - private static final Color[] COLORS = { Color.BLUE, Color.ORANGE, Color.GREEN, Color.YELLOW, Color.RED }; + private static final Color[] COLORS = { Color.BLUE, Color.ORANGE, Color.GREEN, Color.YELLOW, + Color.RED }; // Drawing + Graph drawing private PointSetOverlay grPoints; diff --git a/src/main/org/insa/base/Launch.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/simple/Launch.java similarity index 66% rename from src/main/org/insa/base/Launch.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/simple/Launch.java index c377b0c..7be58b3 100644 --- a/src/main/org/insa/base/Launch.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/simple/Launch.java @@ -1,4 +1,4 @@ -package org.insa.base; +package org.insa.graphs.gui.simple; import java.awt.BorderLayout; import java.awt.Dimension; @@ -9,13 +9,13 @@ import java.io.FileInputStream; import javax.swing.JFrame; import javax.swing.SwingUtilities; -import org.insa.graph.Graph; -import org.insa.graph.Path; -import org.insa.graph.io.BinaryGraphReader; -import org.insa.graph.io.GraphReader; -import org.insa.graph.io.PathReader; -import org.insa.graphics.drawing.Drawing; -import org.insa.graphics.drawing.components.BasicDrawing; +import org.insa.graphs.gui.drawing.Drawing; +import org.insa.graphs.gui.drawing.components.BasicDrawing; +import org.insa.graphs.model.Graph; +import org.insa.graphs.model.Path; +import org.insa.graphs.model.io.BinaryGraphReader; +import org.insa.graphs.model.io.GraphReader; +import org.insa.graphs.model.io.PathReader; public class Launch { @@ -46,29 +46,28 @@ public class Launch { public static void main(String[] args) throws Exception { // Visit these directory to see the list of available files on Commetud. - String mapName = "/home/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Maps/insa.mapgr"; - String pathName = "/home/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Paths/path_fr31insa_rangueil_r2.path"; + final String mapName = "/home/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Maps/insa.mapgr"; + final String pathName = "/home/commetud/3eme Annee MIC/Graphes-et-Algorithmes/Paths/path_fr31insa_rangueil_r2.path"; // Create a graph reader. - GraphReader reader = new BinaryGraphReader( + final GraphReader reader = new BinaryGraphReader( new DataInputStream(new BufferedInputStream(new FileInputStream(mapName)))); // TODO: Read the graph. - Graph graph = null; + final Graph graph = null; // Create the drawing: - Drawing drawing = createDrawing(); + final Drawing drawing = createDrawing(); // TODO: Draw the graph on the drawing. // TODO: Create a PathReader. - PathReader pathReader = null; + final PathReader pathReader = null; // TODO: Read the path. - Path path = null; + final Path path = null; // TODO: Draw the path. - } } diff --git a/src/main/org/insa/graphics/utils/ColorUtils.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/utils/ColorUtils.java similarity index 94% rename from src/main/org/insa/graphics/utils/ColorUtils.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/utils/ColorUtils.java index 1f4e422..1676699 100644 --- a/src/main/org/insa/graphics/utils/ColorUtils.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/utils/ColorUtils.java @@ -1,4 +1,4 @@ -package org.insa.graphics.utils; +package org.insa.graphs.gui.utils; import java.awt.Color; diff --git a/src/main/org/insa/graphics/utils/FileUtils.java b/be-graphes-gui/src/main/java/org/insa/graphs/gui/utils/FileUtils.java similarity index 99% rename from src/main/org/insa/graphics/utils/FileUtils.java rename to be-graphes-gui/src/main/java/org/insa/graphs/gui/utils/FileUtils.java index 3584f6e..301cfc9 100644 --- a/src/main/org/insa/graphics/utils/FileUtils.java +++ b/be-graphes-gui/src/main/java/org/insa/graphs/gui/utils/FileUtils.java @@ -1,4 +1,4 @@ -package org.insa.graphics.utils; +package org.insa.graphs.gui.utils; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; diff --git a/res/delete-icon.png b/be-graphes-gui/src/main/resources/delete-icon.png similarity index 100% rename from res/delete-icon.png rename to be-graphes-gui/src/main/resources/delete-icon.png diff --git a/res/marker_mask.bin b/be-graphes-gui/src/main/resources/marker_mask.bin similarity index 100% rename from res/marker_mask.bin rename to be-graphes-gui/src/main/resources/marker_mask.bin diff --git a/res/save-icon.png b/be-graphes-gui/src/main/resources/save-icon.png similarity index 100% rename from res/save-icon.png rename to be-graphes-gui/src/main/resources/save-icon.png diff --git a/res/zoomIn.png b/be-graphes-gui/src/main/resources/zoomIn.png similarity index 100% rename from res/zoomIn.png rename to be-graphes-gui/src/main/resources/zoomIn.png diff --git a/res/zoomOut.png b/be-graphes-gui/src/main/resources/zoomOut.png similarity index 100% rename from res/zoomOut.png rename to be-graphes-gui/src/main/resources/zoomOut.png diff --git a/be-graphes-model/pom.xml b/be-graphes-model/pom.xml new file mode 100644 index 0000000..9d596fd --- /dev/null +++ b/be-graphes-model/pom.xml @@ -0,0 +1,14 @@ + + + 4.0.0 + + org.insa.graphs + be-graphes-all + 0.0.1-SNAPSHOT + + be-graphes-model + be-graphes-model + diff --git a/src/main/org/insa/graph/AccessRestrictions.java b/be-graphes-model/src/main/java/org/insa/graphs/model/AccessRestrictions.java similarity index 99% rename from src/main/org/insa/graph/AccessRestrictions.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/AccessRestrictions.java index 2c5a1cd..78d8689 100644 --- a/src/main/org/insa/graph/AccessRestrictions.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/AccessRestrictions.java @@ -1,4 +1,4 @@ -package org.insa.graph; +package org.insa.graphs.model; import java.util.EnumMap; import java.util.EnumSet; diff --git a/src/main/org/insa/graph/Arc.java b/be-graphes-model/src/main/java/org/insa/graphs/model/Arc.java similarity index 98% rename from src/main/org/insa/graph/Arc.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/Arc.java index 3985ffc..2bbed68 100644 --- a/src/main/org/insa/graph/Arc.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/Arc.java @@ -1,4 +1,4 @@ -package org.insa.graph; +package org.insa.graphs.model; import java.util.List; diff --git a/src/main/org/insa/graph/ArcBackward.java b/be-graphes-model/src/main/java/org/insa/graphs/model/ArcBackward.java similarity index 97% rename from src/main/org/insa/graph/ArcBackward.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/ArcBackward.java index 7ce9fca..051fc34 100644 --- a/src/main/org/insa/graph/ArcBackward.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/ArcBackward.java @@ -1,4 +1,4 @@ -package org.insa.graph; +package org.insa.graphs.model; import java.util.ArrayList; import java.util.Collections; diff --git a/src/main/org/insa/graph/ArcForward.java b/be-graphes-model/src/main/java/org/insa/graphs/model/ArcForward.java similarity index 98% rename from src/main/org/insa/graph/ArcForward.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/ArcForward.java index 5bf947d..df5871e 100644 --- a/src/main/org/insa/graph/ArcForward.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/ArcForward.java @@ -1,4 +1,4 @@ -package org.insa.graph; +package org.insa.graphs.model; import java.util.Collections; import java.util.List; diff --git a/src/main/org/insa/graph/Graph.java b/be-graphes-model/src/main/java/org/insa/graphs/model/Graph.java similarity index 99% rename from src/main/org/insa/graph/Graph.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/Graph.java index b188c91..42e3ecc 100644 --- a/src/main/org/insa/graph/Graph.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/Graph.java @@ -1,4 +1,4 @@ -package org.insa.graph; +package org.insa.graphs.model; import java.util.ArrayList; import java.util.Collections; diff --git a/src/main/org/insa/graph/GraphStatistics.java b/be-graphes-model/src/main/java/org/insa/graphs/model/GraphStatistics.java similarity index 99% rename from src/main/org/insa/graph/GraphStatistics.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/GraphStatistics.java index f5c1e98..658492a 100644 --- a/src/main/org/insa/graph/GraphStatistics.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/GraphStatistics.java @@ -1,4 +1,4 @@ -package org.insa.graph; +package org.insa.graphs.model; /** *

diff --git a/src/main/org/insa/graph/Node.java b/be-graphes-model/src/main/java/org/insa/graphs/model/Node.java similarity index 99% rename from src/main/org/insa/graph/Node.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/Node.java index cb785e7..37f20b0 100644 --- a/src/main/org/insa/graph/Node.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/Node.java @@ -1,4 +1,4 @@ -package org.insa.graph; +package org.insa.graphs.model; import java.util.ArrayList; import java.util.Collections; diff --git a/src/main/org/insa/graph/Path.java b/be-graphes-model/src/main/java/org/insa/graphs/model/Path.java similarity index 99% rename from src/main/org/insa/graph/Path.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/Path.java index 72c5845..6ebdb73 100644 --- a/src/main/org/insa/graph/Path.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/Path.java @@ -1,4 +1,4 @@ -package org.insa.graph; +package org.insa.graphs.model; import java.util.ArrayList; import java.util.Collections; diff --git a/src/main/org/insa/graph/Point.java b/be-graphes-model/src/main/java/org/insa/graphs/model/Point.java similarity index 98% rename from src/main/org/insa/graph/Point.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/Point.java index 509c4f9..82c6f57 100644 --- a/src/main/org/insa/graph/Point.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/Point.java @@ -1,4 +1,4 @@ -package org.insa.graph; +package org.insa.graphs.model; /** * Class representing a point (position) on Earth. diff --git a/src/main/org/insa/graph/RoadInformation.java b/be-graphes-model/src/main/java/org/insa/graphs/model/RoadInformation.java similarity index 98% rename from src/main/org/insa/graph/RoadInformation.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/RoadInformation.java index 61aed04..f5fa39c 100644 --- a/src/main/org/insa/graph/RoadInformation.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/RoadInformation.java @@ -1,4 +1,4 @@ -package org.insa.graph; +package org.insa.graphs.model; /** *

diff --git a/src/main/org/insa/graph/io/BadFormatException.java b/be-graphes-model/src/main/java/org/insa/graphs/model/io/BadFormatException.java similarity index 59% rename from src/main/org/insa/graph/io/BadFormatException.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/io/BadFormatException.java index d69b879..184debe 100644 --- a/src/main/org/insa/graph/io/BadFormatException.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/io/BadFormatException.java @@ -1,4 +1,4 @@ -package org.insa.graph.io; +package org.insa.graphs.model.io; import java.io.IOException; @@ -21,4 +21,13 @@ public class BadFormatException extends IOException { super(); } + /** + * Create a new format exception with the given message. + * + * @param message Message for the exception. + */ + public BadFormatException(String message) { + super(message); + } + } diff --git a/src/main/org/insa/graph/io/BadMagicNumberException.java b/be-graphes-model/src/main/java/org/insa/graphs/model/io/BadMagicNumberException.java similarity index 86% rename from src/main/org/insa/graph/io/BadMagicNumberException.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/io/BadMagicNumberException.java index 98209b8..31d9f42 100644 --- a/src/main/org/insa/graph/io/BadMagicNumberException.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/io/BadMagicNumberException.java @@ -1,4 +1,4 @@ -package org.insa.graph.io; +package org.insa.graphs.model.io; /** * Exception thrown when there is a mismatch between expected and actual magic @@ -23,7 +23,8 @@ public class BadMagicNumberException extends BadFormatException { * @param expectedNumber Expected magic number. */ public BadMagicNumberException(int actualNumber, int expectedNumber) { - super(); + super(String.format("Magic number mismatch, expected %#X, got %#X.", expectedNumber, + actualNumber)); this.actualNumber = actualNumber; this.expectedNumber = expectedNumber; } diff --git a/src/main/org/insa/graph/io/BadVersionException.java b/be-graphes-model/src/main/java/org/insa/graphs/model/io/BadVersionException.java similarity index 96% rename from src/main/org/insa/graph/io/BadVersionException.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/io/BadVersionException.java index a8dead3..892f534 100644 --- a/src/main/org/insa/graph/io/BadVersionException.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/io/BadVersionException.java @@ -1,4 +1,4 @@ -package org.insa.graph.io; +package org.insa.graphs.model.io; /** * Exception thrown when the version of the file is not at least the expected diff --git a/src/main/org/insa/graph/io/BinaryGraphReader.java b/be-graphes-model/src/main/java/org/insa/graphs/model/io/BinaryGraphReader.java similarity index 95% rename from src/main/org/insa/graph/io/BinaryGraphReader.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/io/BinaryGraphReader.java index c132a40..720f54f 100644 --- a/src/main/org/insa/graph/io/BinaryGraphReader.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/io/BinaryGraphReader.java @@ -1,4 +1,4 @@ -package org.insa.graph.io; +package org.insa.graphs.model.io; import java.io.DataInputStream; import java.io.IOException; @@ -6,17 +6,17 @@ import java.util.ArrayList; import java.util.EnumMap; import java.util.List; -import org.insa.graph.AccessRestrictions; -import org.insa.graph.AccessRestrictions.AccessMode; -import org.insa.graph.AccessRestrictions.AccessRestriction; -import org.insa.graph.Arc; -import org.insa.graph.Graph; -import org.insa.graph.GraphStatistics; -import org.insa.graph.GraphStatistics.BoundingBox; -import org.insa.graph.Node; -import org.insa.graph.Point; -import org.insa.graph.RoadInformation; -import org.insa.graph.RoadInformation.RoadType; +import org.insa.graphs.model.AccessRestrictions; +import org.insa.graphs.model.Arc; +import org.insa.graphs.model.Graph; +import org.insa.graphs.model.GraphStatistics; +import org.insa.graphs.model.Node; +import org.insa.graphs.model.Point; +import org.insa.graphs.model.RoadInformation; +import org.insa.graphs.model.AccessRestrictions.AccessMode; +import org.insa.graphs.model.AccessRestrictions.AccessRestriction; +import org.insa.graphs.model.GraphStatistics.BoundingBox; +import org.insa.graphs.model.RoadInformation.RoadType; /** * Implementation of {@link GraphReader} to read graph in binary format. diff --git a/src/main/org/insa/graph/io/BinaryPathReader.java b/be-graphes-model/src/main/java/org/insa/graphs/model/io/BinaryPathReader.java similarity index 93% rename from src/main/org/insa/graph/io/BinaryPathReader.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/io/BinaryPathReader.java index bb3336f..f3351bd 100644 --- a/src/main/org/insa/graph/io/BinaryPathReader.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/io/BinaryPathReader.java @@ -1,12 +1,12 @@ -package org.insa.graph.io; +package org.insa.graphs.model.io; import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; -import org.insa.graph.Graph; -import org.insa.graph.Node; -import org.insa.graph.Path; +import org.insa.graphs.model.Graph; +import org.insa.graphs.model.Node; +import org.insa.graphs.model.Path; /** * Implementation of {@link PathReader} to read paths in binary format. diff --git a/src/main/org/insa/graph/io/BinaryPathWriter.java b/be-graphes-model/src/main/java/org/insa/graphs/model/io/BinaryPathWriter.java similarity index 92% rename from src/main/org/insa/graph/io/BinaryPathWriter.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/io/BinaryPathWriter.java index 8883afc..1eb778c 100644 --- a/src/main/org/insa/graph/io/BinaryPathWriter.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/io/BinaryPathWriter.java @@ -1,11 +1,11 @@ -package org.insa.graph.io; +package org.insa.graphs.model.io; import java.io.DataOutputStream; import java.io.IOException; import java.util.Arrays; -import org.insa.graph.Arc; -import org.insa.graph.Path; +import org.insa.graphs.model.Arc; +import org.insa.graphs.model.Path; /** * Implementation of {@link PathWriter} to write paths in binary format. diff --git a/src/main/org/insa/graph/io/BinaryReader.java b/be-graphes-model/src/main/java/org/insa/graphs/model/io/BinaryReader.java similarity index 90% rename from src/main/org/insa/graph/io/BinaryReader.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/io/BinaryReader.java index 4084359..b654bad 100644 --- a/src/main/org/insa/graph/io/BinaryReader.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/io/BinaryReader.java @@ -1,5 +1,6 @@ -package org.insa.graph.io; +package org.insa.graphs.model.io; +import java.io.Closeable; import java.io.DataInputStream; import java.io.IOException; @@ -7,15 +8,15 @@ import java.io.IOException; * Base class for writing binary file. * */ -public abstract class BinaryReader { +public abstract class BinaryReader implements AutoCloseable, Closeable { // Map version and magic number targeted for this reader. - private int minVersion; + private final int minVersion; private int curVersion; - private int magicNumber; + private final int magicNumber; // InputStream - protected DataInputStream dis; + protected final DataInputStream dis; /** * Create a new BinaryReader that reads from the given stream and that expected @@ -31,6 +32,11 @@ public abstract class BinaryReader { this.dis = dis; } + @Override + public void close() throws IOException { + this.dis.close(); + } + /** * Check if the given version is greater than the minimum version, and update * the current version if it is. @@ -38,7 +44,7 @@ public abstract class BinaryReader { * @param version Version to check. * * @throws BadVersionException if the given version is not greater than the - * minimum version. + * minimum version. */ protected void checkVersionOrThrow(int version) throws BadVersionException { if (version < this.minVersion) { diff --git a/src/main/org/insa/graph/io/BinaryWriter.java b/be-graphes-model/src/main/java/org/insa/graphs/model/io/BinaryWriter.java similarity index 72% rename from src/main/org/insa/graph/io/BinaryWriter.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/io/BinaryWriter.java index a6a263f..34cad06 100644 --- a/src/main/org/insa/graph/io/BinaryWriter.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/io/BinaryWriter.java @@ -1,5 +1,6 @@ -package org.insa.graph.io; +package org.insa.graphs.model.io; +import java.io.Closeable; import java.io.DataOutputStream; import java.io.IOException; @@ -7,10 +8,10 @@ import java.io.IOException; * Base class for writing binary file. * */ -public abstract class BinaryWriter { +public abstract class BinaryWriter implements AutoCloseable, Closeable { // Output stream. - protected DataOutputStream dos; + protected final DataOutputStream dos; /** * Create a new BinaryWriter that writes to the given output stream. @@ -21,6 +22,11 @@ public abstract class BinaryWriter { this.dos = dos; } + @Override + public void close() throws IOException { + this.dos.close(); + } + /** * Write a 24-bits integer in BigEndian order to the output stream. * diff --git a/be-graphes-model/src/main/java/org/insa/graphs/model/io/GraphReader.java b/be-graphes-model/src/main/java/org/insa/graphs/model/io/GraphReader.java new file mode 100644 index 0000000..29ed437 --- /dev/null +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/io/GraphReader.java @@ -0,0 +1,39 @@ +package org.insa.graphs.model.io; + +import java.io.Closeable; +import java.io.IOException; + +import org.insa.graphs.model.Graph; + +/** + * Base interface for classes that can read graph. + * + */ +public interface GraphReader extends AutoCloseable, Closeable { + + /** + * Add a new observer to this graph reader. + * + * @param observer Observer to add. + */ + public void addObserver(GraphReaderObserver observer); + + /** + * Read a graph an returns it. + * + * @return The graph read. + * + * @throws IOException if an exception occurs while reading the graph. + * + */ + public Graph read() throws IOException; + + /** + * Close this graph reader. + * + * @throws IOException if an exception occurs while closing the reader. + * + */ + public void close() throws IOException; + +} diff --git a/src/main/org/insa/graph/io/GraphReaderObserver.java b/be-graphes-model/src/main/java/org/insa/graphs/model/io/GraphReaderObserver.java similarity index 91% rename from src/main/org/insa/graph/io/GraphReaderObserver.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/io/GraphReaderObserver.java index 3ff65a8..4f25835 100644 --- a/src/main/org/insa/graph/io/GraphReaderObserver.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/io/GraphReaderObserver.java @@ -1,8 +1,8 @@ -package org.insa.graph.io; +package org.insa.graphs.model.io; -import org.insa.graph.Arc; -import org.insa.graph.Node; -import org.insa.graph.RoadInformation; +import org.insa.graphs.model.Arc; +import org.insa.graphs.model.Node; +import org.insa.graphs.model.RoadInformation; /** * Base interface that should be implemented by classes that want to observe the diff --git a/src/main/org/insa/graph/io/MapMismatchException.java b/be-graphes-model/src/main/java/org/insa/graphs/model/io/MapMismatchException.java similarity index 96% rename from src/main/org/insa/graph/io/MapMismatchException.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/io/MapMismatchException.java index fca9f70..fb2de3b 100644 --- a/src/main/org/insa/graph/io/MapMismatchException.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/io/MapMismatchException.java @@ -1,4 +1,4 @@ -package org.insa.graph.io; +package org.insa.graphs.model.io; import java.io.IOException; diff --git a/src/main/org/insa/graph/io/PathReader.java b/be-graphes-model/src/main/java/org/insa/graphs/model/io/PathReader.java similarity index 51% rename from src/main/org/insa/graph/io/PathReader.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/io/PathReader.java index b1836b9..e14a5a2 100644 --- a/src/main/org/insa/graph/io/PathReader.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/io/PathReader.java @@ -1,15 +1,16 @@ -package org.insa.graph.io; +package org.insa.graphs.model.io; +import java.io.Closeable; import java.io.IOException; -import org.insa.graph.Graph; -import org.insa.graph.Path; +import org.insa.graphs.model.Graph; +import org.insa.graphs.model.Path; /** * Base interface that should be implemented by class used to read paths. * */ -public interface PathReader { +public interface PathReader extends AutoCloseable, Closeable { /** * Read a path of the given graph and returns it. @@ -22,4 +23,12 @@ public interface PathReader { */ public Path readPath(Graph graph) throws IOException; + /** + * Close this graph reader. + * + * @throws IOException if an exception occurs while closing the reader. + * + */ + public void close() throws IOException; + } diff --git a/src/main/org/insa/graph/io/PathWriter.java b/be-graphes-model/src/main/java/org/insa/graphs/model/io/PathWriter.java similarity index 50% rename from src/main/org/insa/graph/io/PathWriter.java rename to be-graphes-model/src/main/java/org/insa/graphs/model/io/PathWriter.java index 098fcab..b261763 100644 --- a/src/main/org/insa/graph/io/PathWriter.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/io/PathWriter.java @@ -1,14 +1,15 @@ -package org.insa.graph.io; +package org.insa.graphs.model.io; +import java.io.Closeable; import java.io.IOException; -import org.insa.graph.Path; +import org.insa.graphs.model.Path; /** * Base interface that should be implemented by class used to write paths. * */ -public interface PathWriter { +public interface PathWriter extends AutoCloseable, Closeable { /** * Write the given path. @@ -19,4 +20,12 @@ public interface PathWriter { */ public void writePath(Path path) throws IOException; + /** + * Close this graph reader. + * + * @throws IOException if an exception occurs while closing the reader. + * + */ + public void close() throws IOException; + } diff --git a/src/test/org/insa/graph/GraphTest.java b/be-graphes-model/src/test/java/org/insa/graphes/model/GraphTest.java similarity index 95% rename from src/test/org/insa/graph/GraphTest.java rename to be-graphes-model/src/test/java/org/insa/graphes/model/GraphTest.java index 3fa3765..f9333b9 100644 --- a/src/test/org/insa/graph/GraphTest.java +++ b/be-graphes-model/src/test/java/org/insa/graphes/model/GraphTest.java @@ -1,4 +1,4 @@ -package org.insa.graph; +package org.insa.graphes.model; import static org.junit.Assert.assertEquals; @@ -7,7 +7,11 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.insa.graph.RoadInformation.RoadType; +import org.insa.graphs.model.Arc; +import org.insa.graphs.model.Graph; +import org.insa.graphs.model.Node; +import org.insa.graphs.model.RoadInformation; +import org.insa.graphs.model.RoadInformation.RoadType; import org.junit.BeforeClass; import org.junit.Test; diff --git a/src/test/org/insa/graph/NodeTest.java b/be-graphes-model/src/test/java/org/insa/graphes/model/NodeTest.java similarity index 93% rename from src/test/org/insa/graph/NodeTest.java rename to be-graphes-model/src/test/java/org/insa/graphes/model/NodeTest.java index 242a43f..057c5d5 100644 --- a/src/test/org/insa/graph/NodeTest.java +++ b/be-graphes-model/src/test/java/org/insa/graphes/model/NodeTest.java @@ -1,11 +1,14 @@ -package org.insa.graph; +package org.insa.graphes.model; import static org.junit.Assert.assertEquals; import java.io.IOException; import java.util.ArrayList; -import org.insa.graph.RoadInformation.RoadType; +import org.insa.graphs.model.Arc; +import org.insa.graphs.model.Node; +import org.insa.graphs.model.RoadInformation; +import org.insa.graphs.model.RoadInformation.RoadType; import org.junit.Before; import org.junit.Test; diff --git a/src/test/org/insa/graph/PathTest.java b/be-graphes-model/src/test/java/org/insa/graphes/model/PathTest.java similarity index 97% rename from src/test/org/insa/graph/PathTest.java rename to be-graphes-model/src/test/java/org/insa/graphes/model/PathTest.java index 55dd4fa..fbef0f3 100644 --- a/src/test/org/insa/graph/PathTest.java +++ b/be-graphes-model/src/test/java/org/insa/graphes/model/PathTest.java @@ -1,4 +1,4 @@ -package org.insa.graph; +package org.insa.graphes.model; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -8,7 +8,12 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import org.insa.graph.RoadInformation.RoadType; +import org.insa.graphs.model.Arc; +import org.insa.graphs.model.Graph; +import org.insa.graphs.model.Node; +import org.insa.graphs.model.Path; +import org.insa.graphs.model.RoadInformation; +import org.insa.graphs.model.RoadInformation.RoadType; import org.junit.BeforeClass; import org.junit.Test; diff --git a/libs/kxml2-2.3.0.jar b/libs/kxml2-2.3.0.jar deleted file mode 100644 index 6470952..0000000 Binary files a/libs/kxml2-2.3.0.jar and /dev/null differ diff --git a/libs/mapsforge-core-0.9.1-javadoc.jar b/libs/mapsforge-core-0.9.1-javadoc.jar deleted file mode 100644 index a2a3d4f..0000000 Binary files a/libs/mapsforge-core-0.9.1-javadoc.jar and /dev/null differ diff --git a/libs/mapsforge-core-0.9.1.jar b/libs/mapsforge-core-0.9.1.jar deleted file mode 100644 index 23125a4..0000000 Binary files a/libs/mapsforge-core-0.9.1.jar and /dev/null differ diff --git a/libs/mapsforge-map-0.9.1-javadoc.jar b/libs/mapsforge-map-0.9.1-javadoc.jar deleted file mode 100644 index 5fe05e1..0000000 Binary files a/libs/mapsforge-map-0.9.1-javadoc.jar and /dev/null differ diff --git a/libs/mapsforge-map-0.9.1.jar b/libs/mapsforge-map-0.9.1.jar deleted file mode 100644 index abb4f89..0000000 Binary files a/libs/mapsforge-map-0.9.1.jar and /dev/null differ diff --git a/libs/mapsforge-map-awt-0.9.1-javadoc.jar b/libs/mapsforge-map-awt-0.9.1-javadoc.jar deleted file mode 100644 index 5f01eaa..0000000 Binary files a/libs/mapsforge-map-awt-0.9.1-javadoc.jar and /dev/null differ diff --git a/libs/mapsforge-map-awt-0.9.1.jar b/libs/mapsforge-map-awt-0.9.1.jar deleted file mode 100644 index 169c154..0000000 Binary files a/libs/mapsforge-map-awt-0.9.1.jar and /dev/null differ diff --git a/libs/mapsforge-map-reader-0.9.1-javadoc.jar b/libs/mapsforge-map-reader-0.9.1-javadoc.jar deleted file mode 100644 index 783bb46..0000000 Binary files a/libs/mapsforge-map-reader-0.9.1-javadoc.jar and /dev/null differ diff --git a/libs/mapsforge-map-reader-0.9.1.jar b/libs/mapsforge-map-reader-0.9.1.jar deleted file mode 100644 index 51ad11d..0000000 Binary files a/libs/mapsforge-map-reader-0.9.1.jar and /dev/null differ diff --git a/libs/mapsforge-poi-0.9.1-javadoc.jar b/libs/mapsforge-poi-0.9.1-javadoc.jar deleted file mode 100644 index 0d23e5d..0000000 Binary files a/libs/mapsforge-poi-0.9.1-javadoc.jar and /dev/null differ diff --git a/libs/mapsforge-poi-0.9.1.jar b/libs/mapsforge-poi-0.9.1.jar deleted file mode 100644 index d778de4..0000000 Binary files a/libs/mapsforge-poi-0.9.1.jar and /dev/null differ diff --git a/libs/mapsforge-poi-awt-0.9.1-javadoc.jar b/libs/mapsforge-poi-awt-0.9.1-javadoc.jar deleted file mode 100644 index 3c6a872..0000000 Binary files a/libs/mapsforge-poi-awt-0.9.1-javadoc.jar and /dev/null differ diff --git a/libs/mapsforge-poi-awt-0.9.1.jar b/libs/mapsforge-poi-awt-0.9.1.jar deleted file mode 100644 index 14e1b89..0000000 Binary files a/libs/mapsforge-poi-awt-0.9.1.jar and /dev/null differ diff --git a/libs/mapsforge-themes-0.9.1-javadoc.jar b/libs/mapsforge-themes-0.9.1-javadoc.jar deleted file mode 100644 index b40c7e5..0000000 Binary files a/libs/mapsforge-themes-0.9.1-javadoc.jar and /dev/null differ diff --git a/libs/mapsforge-themes-0.9.1.jar b/libs/mapsforge-themes-0.9.1.jar deleted file mode 100644 index e91f12b..0000000 Binary files a/libs/mapsforge-themes-0.9.1.jar and /dev/null differ diff --git a/libs/svg-salamander-1.0-javadoc.jar b/libs/svg-salamander-1.0-javadoc.jar deleted file mode 100644 index e136ad8..0000000 Binary files a/libs/svg-salamander-1.0-javadoc.jar and /dev/null differ diff --git a/libs/svg-salamander-1.0.jar b/libs/svg-salamander-1.0.jar deleted file mode 100644 index 200eeb0..0000000 Binary files a/libs/svg-salamander-1.0.jar and /dev/null differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..0c02ef4 --- /dev/null +++ b/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + + org.insa.graphs + be-graphes-all + 0.0.1-SNAPSHOT + pom + + be-graphes-all + http://maven.apache.org + + + 1.8 + 1.8 + UTF-8 + + + + + + maven-compiler-plugin + 3.1 + + 8 + 8 + + + + + + + + junit + junit + 4.12 + test + + + + + be-graphes-model + be-graphes-algos + be-graphes-gui + + diff --git a/src/main/org/insa/algo/carpooling/CarPoolingData.java b/src/main/org/insa/algo/carpooling/CarPoolingData.java deleted file mode 100644 index 559e6da..0000000 --- a/src/main/org/insa/algo/carpooling/CarPoolingData.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.insa.algo.carpooling; - -import org.insa.algo.AbstractInputData; -import org.insa.algo.ArcInspector; -import org.insa.graph.Graph; - -public class CarPoolingData extends AbstractInputData { - - protected CarPoolingData(Graph graph, ArcInspector arcFilter) { - super(graph, arcFilter); - } - -} diff --git a/src/main/org/insa/algo/carpooling/CarPoolingObserver.java b/src/main/org/insa/algo/carpooling/CarPoolingObserver.java deleted file mode 100644 index e7249e1..0000000 --- a/src/main/org/insa/algo/carpooling/CarPoolingObserver.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.insa.algo.carpooling; - -public interface CarPoolingObserver { - -} diff --git a/src/main/org/insa/algo/packageswitch/PackageSwitchData.java b/src/main/org/insa/algo/packageswitch/PackageSwitchData.java deleted file mode 100644 index 57c581f..0000000 --- a/src/main/org/insa/algo/packageswitch/PackageSwitchData.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.insa.algo.packageswitch; - -import org.insa.algo.AbstractInputData; -import org.insa.algo.ArcInspector; -import org.insa.graph.Graph; - -public class PackageSwitchData extends AbstractInputData { - - protected PackageSwitchData(Graph graph, ArcInspector arcFilter) { - super(graph, arcFilter); - } - -} diff --git a/src/main/org/insa/algo/packageswitch/PackageSwitchObserver.java b/src/main/org/insa/algo/packageswitch/PackageSwitchObserver.java deleted file mode 100644 index 4f29e7b..0000000 --- a/src/main/org/insa/algo/packageswitch/PackageSwitchObserver.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.insa.algo.packageswitch; - -public interface PackageSwitchObserver { - -} diff --git a/src/main/org/insa/algo/utils/BinaryHeap.java b/src/main/org/insa/algo/utils/BinaryHeap.java deleted file mode 100644 index b18aae0..0000000 --- a/src/main/org/insa/algo/utils/BinaryHeap.java +++ /dev/null @@ -1,311 +0,0 @@ -package org.insa.algo.utils; - -import java.util.ArrayList; - - - -/** - * Implements a binary heap containing elements of type E. - * - * Note that all comparisons are based on the compareTo method, - * hence E must implement Comparable - * - * @author Mark Allen Weiss - * @author DLB - */ -public class BinaryHeap> implements PriorityQueue { - - // Number of elements in heap. - private int currentSize; - - // The heap array. - private final ArrayList array; - - /** - * Construct a new empty binary heap. - */ - public BinaryHeap() { - this.currentSize = 0; - this.array = new ArrayList(); - } - - /** - * Construct a copy of the given heap. - * - * @param heap Binary heap to copy. - */ - public BinaryHeap(BinaryHeap heap) { - this.currentSize = heap.currentSize; - this.array = new ArrayList(heap.array); - } - - /** - * Set an element at the given index. - * - * @param index Index at which the element should be set. - * @param value Element to set. - */ - private void arraySet(int index, E value) { - if (index == this.array.size()) { - this.array.add(value); - } - else { - this.array.set(index, value); - } - - } - - /** - * @return Index of the parent of the given index. - */ - private int index_parent(int index) { - return (index - 1) / 2; - } - - /** - * @return Index of the left child of the given index. - */ - private int index_left(int index) { - return index * 2 + 1; - } - - /** - * Internal method to percolate up in the heap. - * - * @param index Index at which the percolate begins. - */ - private void percolateUp(int index) { - E x = this.array.get(index); - - for (; index > 0 - && x.compareTo(this.array.get(index_parent(index))) < 0; index = index_parent( - index)) { - E moving_val = this.array.get(index_parent(index)); - this.arraySet(index, moving_val); - } - - this.arraySet(index, x); - } - - /** - * Internal method to percolate down in the heap. - * - * @param index Index at which the percolate begins. - */ - private void percolateDown(int index) { - int ileft = index_left(index); - int iright = ileft + 1; - - if (ileft < this.currentSize) { - E current = this.array.get(index); - E left = this.array.get(ileft); - boolean hasRight = iright < this.currentSize; - E right = (hasRight) ? this.array.get(iright) : null; - - if (!hasRight || left.compareTo(right) < 0) { - // Left is smaller - if (left.compareTo(current) < 0) { - this.arraySet(index, left); - this.arraySet(ileft, current); - this.percolateDown(ileft); - } - } - else { - // Right is smaller - if (right.compareTo(current) < 0) { - this.arraySet(index, right); - this.arraySet(iright, current); - this.percolateDown(iright); - } - } - } - } - - @Override - public boolean isEmpty() { - return this.currentSize == 0; - } - - @Override - public int size() { - return this.currentSize; - } - - @Override - public void insert(E x) { - int index = this.currentSize++; - this.arraySet(index, x); - this.percolateUp(index); - } - - @Override - public void remove(E x) throws ElementNotFoundException { - // TODO: - } - - @Override - public E findMin() throws EmptyPriorityQueueException { - if (isEmpty()) - throw new EmptyPriorityQueueException(); - return this.array.get(0); - } - - @Override - public E deleteMin() throws EmptyPriorityQueueException { - E minItem = findMin(); - E lastItem = this.array.get(--this.currentSize); - this.arraySet(0, lastItem); - this.percolateDown(0); - return minItem; - } - - /* This class is used by toString_tree. - * It is just a triple of strings. Could it be made simpler in Java ? - * - * Printing context, functional style. - */ - private class Context { - /* Output text */ - public final String acu ; - - /* margin: the margin to get back exactly under the current position on the next line. */ - public final String margin ; - - /* lastmargin: margin used for the last child of a node. The markers are different. */ - public final String lastmargin ; - - public Context(String a, String b, String c) { - this.acu = a ; - this.margin = b ; - this.lastmargin = c ; - } - - /* Appends newlines. */ - public Context nl(int n) { - if (n <= 0) { return this ; } - else { - String acu2 = this.acu + "\n" + this.margin ; - return (new Context(acu2, this.margin, this.lastmargin).nl(n-1)) ; - } - } - - /* Adds some text */ - public Context add(Integer count, String s) { - int cnt = (count==null) ? s.length() : count ; - String spaces = new String(new char[cnt]).replace('\0', ' '); - - return new Context(this.acu + s, this.margin + spaces, this.lastmargin + spaces) ; - } - - /* Adds a branch */ - public Context br(Integer count, String label) { - Context ctxt = this.add(count, label) ; - - if (count == null) { - return new Context(ctxt.acu + "_", - ctxt.margin + "|", - ctxt.margin + " ") ; - } - else { - return new Context(ctxt.acu, - ctxt.margin + "|", - ctxt.margin + " ").nl(1) ; - - } - } - } - - /* Input : ready to write the current node at the current context position. - * Output : the last character of acu is the last character of the current node. */ - public Context toString_loop(Context ctxt, int node, int max_depth) { - - if (max_depth < 0) { return ctxt.add(null,"...") ; } - else { - E nodeval = this.array.get(node) ; - String nodevals = nodeval.toString() ; - - ArrayList childs = new ArrayList() ; - // Add childs - int index_left = this.index_left(node) ; - int index_right = index_left + 1 ; - - if (index_left < this.currentSize) { childs.add(index_left) ; } - if (index_right < this.currentSize) { childs.add(index_right) ; } - - Context ctxt2 = childs.isEmpty() ? ctxt.add(null,nodevals) : ctxt.br(1, nodevals) ; - - for (int ch = 0 ; ch < childs.size() ; ch++) { - boolean is_last = (ch == childs.size() - 1) ; - int child = childs.get(ch) ; - - if (is_last) { - Context ctxt3 = new Context( ctxt2.acu, ctxt2.lastmargin, ctxt2.lastmargin) ; - ctxt2 = new Context( this.toString_loop(ctxt3.add(null, "___"),child,max_depth-1).acu, - ctxt2.margin, - ctxt2.lastmargin) ; - } - else { - ctxt2 = new Context(this.toString_loop(ctxt2.add(null,"___"),child,max_depth-1).acu, - ctxt2.margin, - ctxt2.lastmargin).nl(2) ; - } - } - - return ctxt2 ; - } - } - - - // Textual representation of the tree. - public String toString_tree(int max_depth) { - Context init_context = new Context(" ", " ", " ") ; - Context result = this.toString_loop(init_context, 0, max_depth) ; - return result.acu ; - } - - // Prints the elements, sorted. - // max_elements: maximal number of elements printed. -1 for infinity. - public String toString_sorted(int max_elements) { - String result = "\n" ; - BinaryHeap copy = new BinaryHeap(this); - - int remaining = max_elements ; - - String truncate = "" ; - if (max_elements < 0 || max_elements >= this.currentSize) { - truncate = "" ; - } else { - truncate = ", only " + max_elements + " elements are shown"; - } - - result += "======== Sorted HEAP (size = " + this.currentSize + truncate + ") ========\n\n" ; - - while (!copy.isEmpty() && remaining != 0) { - result += copy.deleteMin() + "\n" ; - remaining-- ; - } - - result += "\n-------- End of heap --------\n\n" ; - - return result ; - } - - public String toString() { - return this.toString_tree(8) ; - } - - /* - public static void main(String[] args) { - BinaryHeap heap = new BinaryHeap() ; - - for (int i = 0 ; i < 50 ; i++) { - heap.insert(i) ; - } - - System.out.println(heap.toString_tree(4)) ; - } - */ - -} - - diff --git a/src/main/org/insa/graph/io/GraphReader.java b/src/main/org/insa/graph/io/GraphReader.java deleted file mode 100644 index 10a9d48..0000000 --- a/src/main/org/insa/graph/io/GraphReader.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.insa.graph.io; - -import java.io.IOException; - -import org.insa.graph.Graph; - -/** - * Base interface for classes that can read graph. - * - */ -public interface GraphReader { - - /** - * Add a new observer to this graph reader. - * - * @param observer Observer to add. - */ - public void addObserver(GraphReaderObserver observer); - - /** - * Read a graph an returns it. - * - * @return The graph read. - * - * @throws IOException When an exception occurs while reading the graph. - * - */ - public Graph read() throws IOException; - -}