GraphDisplayManager.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. package de.tu_darmstadt.informatik.tk.scopviz.ui;
  2. import java.awt.Dimension;
  3. import java.net.URL;
  4. import java.util.ArrayList;
  5. import java.util.Iterator;
  6. import java.util.LinkedList;
  7. import org.apache.commons.math3.exception.NullArgumentException;
  8. import org.graphstream.graph.Edge;
  9. import org.graphstream.graph.Node;
  10. import de.tu_darmstadt.informatik.tk.scopviz.debug.Debug;
  11. import de.tu_darmstadt.informatik.tk.scopviz.graphs.GraphHelper;
  12. import de.tu_darmstadt.informatik.tk.scopviz.graphs.GraphManager;
  13. import de.tu_darmstadt.informatik.tk.scopviz.graphs.MappingGraphManager;
  14. import de.tu_darmstadt.informatik.tk.scopviz.graphs.MyGraph;
  15. import de.tu_darmstadt.informatik.tk.scopviz.io.GraphMLImporter;
  16. import de.tu_darmstadt.informatik.tk.scopviz.main.CreationMode;
  17. import de.tu_darmstadt.informatik.tk.scopviz.main.Layer;
  18. import de.tu_darmstadt.informatik.tk.scopviz.main.Main;
  19. import javafx.beans.property.BooleanProperty;
  20. import javafx.beans.property.SimpleBooleanProperty;
  21. import javafx.event.EventHandler;
  22. import javafx.scene.input.ScrollEvent;
  23. import javafx.scene.layout.Pane;
  24. import javafx.stage.FileChooser;
  25. import javafx.stage.Stage;
  26. import javafx.stage.FileChooser.ExtensionFilter;
  27. /**
  28. * This class holds all GraphManagers, provides Functions to add Graphs and get
  29. * corresponding GraphManagers.
  30. *
  31. * @author Matthias Wilhelm
  32. * @version 1.1
  33. *
  34. */
  35. public final class GraphDisplayManager {
  36. /** Prefix to add to the Name of the Graphs. */
  37. private static final String GRAPH_STRING_ID_PREFIX = "graph";
  38. /** A List of all GraphManagers managed by this class. */
  39. private static ArrayList<GraphManager> vList = new ArrayList<GraphManager>();
  40. /** The number of GraphManagers currently being managed. */
  41. private static int count = 0;
  42. /** Reference to the GUI Controller for Access to UI Elements. */
  43. private static GUIController guiController;
  44. /** The number of the currently used GraphManager. */
  45. private static int currentGraphManager = 0;
  46. /** The currently active Layer. */
  47. private static Layer currentLayer = Layer.UNDERLAY;
  48. /**
  49. * Observable boolean value, true when currentLayer = symbol layer, false
  50. * otherwise
  51. */
  52. private static BooleanProperty inSymbolLayer = new SimpleBooleanProperty();
  53. /**
  54. * set inSymbolLayer to true
  55. */
  56. private static final void changeToSymbolLayer() {
  57. inSymbolLayer.set(true);
  58. };
  59. /**
  60. * set inSymbolLayer to false
  61. */
  62. private static final void changeToOtherLayer() {
  63. inSymbolLayer.set(false);
  64. };
  65. /**
  66. *
  67. * @return inSymbolLayer property
  68. */
  69. public static BooleanProperty inSymbolLayerProperty() {
  70. return inSymbolLayer;
  71. };
  72. /**
  73. * An empty GraphManager to use with Layers not yet filled with another
  74. * GraphManager.
  75. */
  76. private static final GraphManager emptyLayer = new GraphManager(new MyGraph("g"));
  77. /** Importer for loading Graphs from Disk. */
  78. private static GraphMLImporter importer = new GraphMLImporter();
  79. /**
  80. * Private Constructor to prevent initialization.
  81. */
  82. private GraphDisplayManager() {
  83. }
  84. /**
  85. * Sets the Reference to the GUI Controller to use for accessing UI
  86. * Elements.
  87. *
  88. * @param guiController
  89. * a Reference to the GUI Controller
  90. */
  91. public static void init(GUIController guiController) {
  92. GraphDisplayManager.guiController = guiController;
  93. addGraph();
  94. currentLayer = Layer.OPERATOR;
  95. addGraph();
  96. /*
  97. * currentLayer = Layer.MAPPING; addGraph();
  98. */
  99. currentLayer = Layer.SYMBOL;
  100. addGraph();
  101. currentLayer = Layer.UNDERLAY;
  102. }
  103. /**
  104. * Adds an empty Graph to the collection.
  105. *
  106. * @return the id to access the specific Graph
  107. */
  108. public static int addGraph() {
  109. String id = getGraphStringID(count);
  110. MyGraph g = new MyGraph(id);
  111. return addGraph(g, true);
  112. }
  113. /**
  114. * Imports and adds the specified Graph to the collection.
  115. *
  116. * @param fileName
  117. * name of the file on disk uses System.getResource to get the
  118. * file
  119. * @param replaceCurrent
  120. * if true the given graph will replace any preexisting graph in
  121. * the current layer, if false they will be merged.
  122. * @return the id to access the specific Graph
  123. */
  124. public static int addGraph(String fileName, boolean replaceCurrent) {
  125. String id = getGraphStringID(count);
  126. MyGraph g = importer.readGraph(id, Main.class.getResource(fileName));
  127. return addGraph(g, replaceCurrent);
  128. }
  129. /**
  130. * Opens a Wizard and adds the chosen Graph to the collection.
  131. *
  132. * @param stage
  133. * the root Window of the program
  134. * @param replaceCurrent
  135. * if true the given graph will replace any preexisting graph in
  136. * the current layer, if false they will be merged.
  137. * @return the id to access the specific Graph
  138. */
  139. public static int addGraph(Stage stage, boolean replaceCurrent) {
  140. String id = getGraphStringID(count);
  141. MyGraph g = importer.readGraph(id, stage);
  142. if (g == null) {
  143. return currentGraphManager;
  144. }
  145. return addGraph(g, replaceCurrent);
  146. }
  147. /**
  148. * Imports and adds the specified Graph to the collection.
  149. *
  150. * @param fileURL
  151. * URL of the file
  152. * @param replaceCurrent
  153. * if true the given graph will replace any preexisting graph in
  154. * the current layer, if false they will be merged.
  155. * @return the id to access the specific Graph
  156. */
  157. public static int addGraph(URL fileURL, boolean replaceCurrent) {
  158. String id = getGraphStringID(count);
  159. MyGraph g = importer.readGraph(id, fileURL);
  160. return addGraph(g, replaceCurrent);
  161. }
  162. /**
  163. * Adds the graph to the collection. All other addGraph() functions call
  164. * this one internally.
  165. *
  166. * @param g
  167. * the Graph that should be added to the collection
  168. * @param replaceCurrent
  169. * if true the given graph will replace any preexisting graph in
  170. * the current layer, if false they will be merged.
  171. * @return the id to access the specific graph
  172. */
  173. public static int addGraph(MyGraph g, boolean replaceCurrent) {
  174. if (g == null) {
  175. throw new NullArgumentException();
  176. }
  177. GraphManager v;
  178. int ret = 0;
  179. // replacing the current graph or merging
  180. if (replaceCurrent) {
  181. v = new GraphManager(g);
  182. v.getGraph().addAttribute("layer", currentLayer);
  183. // set default values
  184. GraphHelper.setAllDefaults(g);
  185. v.getGraph().addAttribute("ui.antialias");
  186. removeAllCurrentGraphs();
  187. vList.add(v);
  188. ret = count++;
  189. // set basic style
  190. v.setStylesheet(StylesheetManager.DEFAULT_STYLESHEET);
  191. } else {
  192. v = new GraphManager(GraphHelper.newMerge(false, getGraphManager().getGraph(), g));
  193. v.getGraph().addAttribute("layer", currentLayer);
  194. g.addAttribute("layer", currentLayer);
  195. v.getGraph().addAttribute("ui.antialias");
  196. g.addAttribute("ui.antialias");
  197. removeAllCurrentGraphs();
  198. vList.add(v);
  199. ret = count++;
  200. // set basic style
  201. v.setStylesheet(StylesheetManager.DEFAULT_STYLESHEET);
  202. }
  203. // set ui.class
  204. v.convertUiClass();
  205. // display the graph
  206. switchActiveGraph();
  207. return ret;
  208. }
  209. /**
  210. * Removes all GraphManagers from the current Layer.
  211. */
  212. private static void removeAllCurrentGraphs() {
  213. // TODO weird multithread behavior, count auskommentier fuer matthias
  214. for (int i = 0; i < vList.size(); i++) {
  215. GraphManager man = vList.get(i);
  216. if (man.getGraph().getAttribute("layer").equals(currentLayer)) {
  217. vList.remove(i);
  218. // count--;
  219. }
  220. }
  221. }
  222. /**
  223. * Returns a Graph Id to have a name for Graphs.
  224. *
  225. * @param id
  226. * the number of the Graph
  227. * @return the new String ID
  228. */
  229. private static String getGraphStringID(int id) {
  230. return GRAPH_STRING_ID_PREFIX + id;
  231. }
  232. /**
  233. * Switches the active Graph to the one with the given id.
  234. *
  235. */
  236. public static void switchActiveGraph() {
  237. Pane pane = guiController.pane;
  238. Main.getInstance().getGraphManager().getView()
  239. .setPreferredSize(new Dimension((int) pane.getWidth() - 5, (int) pane.getHeight() - 5));
  240. guiController.swingNode.setContent(Main.getInstance().getGraphManager().getView());
  241. Main.getInstance().getGraphManager().updateStylesheet();
  242. Main.getInstance().setCreationMode(CreationMode.CREATE_NONE);
  243. }
  244. /**
  245. * Returns a reference to the current Visualizer. To change it call
  246. * {@link #switchActiveGraph(int)}
  247. *
  248. * @return the current Visualizer
  249. * @see #switchActiveGraph(int)
  250. */
  251. public static GraphManager getCurrentGraphManager() {
  252. return vList.get(currentGraphManager);
  253. }
  254. /**
  255. * Returns the GraphManager for the current Layer.
  256. *
  257. * @return the GraphManager for the current Layer, or an empty GraphManager
  258. * if none is found
  259. */
  260. public static GraphManager getGraphManager() {
  261. for (GraphManager man : vList) {
  262. if (man.getGraph().getAttribute("layer").equals(currentLayer)) {
  263. return man;
  264. }
  265. }
  266. return emptyLayer;
  267. }
  268. /**
  269. * Returns the GraphManager for the given layer.
  270. *
  271. * @param l
  272. * the given layer
  273. * @return the GraphManager for the given Layer, or an empty GraphManager if
  274. * none is found
  275. */
  276. public static GraphManager getGraphManager(Layer l) {
  277. for (GraphManager man : vList) {
  278. if (man.getGraph().getAttribute("layer").equals(l)) {
  279. return man;
  280. }
  281. }
  282. return emptyLayer;
  283. }
  284. /**
  285. * Returns the currently active Layer.
  286. *
  287. * @return the currently active Layer.
  288. */
  289. public static Layer getCurrentLayer() {
  290. return currentLayer;
  291. }
  292. /**
  293. * Sets the active Layer to a given one.
  294. *
  295. * @param currentLayer
  296. * the layer to switch to
  297. */
  298. public static void setCurrentLayer(Layer currentLayer) {
  299. if (currentLayer.equals(Layer.MAPPING)) {
  300. initMappingLayer(false);
  301. }
  302. GraphDisplayManager.currentLayer = currentLayer;
  303. if (currentLayer.equals(Layer.SYMBOL)) {
  304. changeToSymbolLayer();
  305. } else {
  306. changeToOtherLayer();
  307. }
  308. }
  309. /**
  310. * Sets up the Mapping Layer.
  311. */
  312. public static void initMappingLayer(boolean force) {
  313. GraphManager underlay = null, operator = null;
  314. MappingGraphManager mapping = null;
  315. for (GraphManager man : vList) {
  316. if (man.getGraph().getAttribute("layer").equals(Layer.UNDERLAY)) {
  317. underlay = man;
  318. } else if (man.getGraph().getAttribute("layer").equals(Layer.OPERATOR)) {
  319. operator = man;
  320. } else if (man.getGraph().getAttribute("layer").equals(Layer.MAPPING)
  321. && MappingGraphManager.class.isInstance(man)) {
  322. mapping = (MappingGraphManager) man;
  323. }
  324. }
  325. if (underlay == null) {
  326. Debug.out("ERROR: no Underlay found", 3);
  327. return;
  328. }
  329. if (operator == null) {
  330. Debug.out("ERROR: no Operator found", 3);
  331. return;
  332. }
  333. if (mapping == null || !mapping.hasGraphManagerAsParent(underlay) || !mapping.hasGraphManagerAsParent(operator)
  334. || force) {
  335. if (mapping == null)
  336. Debug.out("WARNING: no Mapping found", 2);
  337. else {
  338. Debug.out("WARNING: old Mapping found", 2);
  339. vList.remove(mapping);
  340. }
  341. MyGraph g;
  342. g = new MyGraph(getGraphStringID(count));
  343. count++;
  344. mapping = new MappingGraphManager(g, underlay, operator);
  345. g.addAttribute("layer", Layer.MAPPING);
  346. g.addAttribute("ui.antialias");
  347. mapping.setStylesheet(StylesheetManager.DEFAULT_STYLESHEET);
  348. vList.add(mapping);
  349. }
  350. mapping.activated();
  351. switchActiveGraph();
  352. }
  353. /**
  354. * Handler for Scrolling while the Mouse is over the Graph Display Window.
  355. */
  356. public static final EventHandler<ScrollEvent> scrollHandler = new EventHandler<ScrollEvent>() {
  357. @Override
  358. public void handle(ScrollEvent event) {
  359. double deltaY = event.getDeltaY();
  360. Main.getInstance().getGraphManager().zoom(deltaY / -100);
  361. }
  362. };
  363. /**
  364. * reads a Mapping Graph and sets the underlay, operator and mapping layers
  365. * accordingly
  366. */
  367. public static void readMapping() {
  368. //import the root Graph
  369. MyGraph g = null;
  370. GraphMLImporter reader = new GraphMLImporter();
  371. FileChooser fileChooser = new FileChooser();
  372. fileChooser.setTitle("open graph");
  373. ExtensionFilter standard = new ExtensionFilter("GraphML Mapping Files", "*.graphmlMap");
  374. fileChooser.getExtensionFilters().add(standard);
  375. fileChooser.getExtensionFilters().add(new ExtensionFilter("all Files", "*"));
  376. fileChooser.setSelectedExtensionFilter(standard);
  377. try {
  378. String fileName = fileChooser.showOpenDialog(Main.getInstance().getPrimaryStage()).getPath();
  379. Main.getInstance().getGraphManager().setCurrentPath(fileName);
  380. g = reader.readGraph(getGraphStringID(count++), fileName);
  381. g.getId();
  382. } catch (NullPointerException e) {
  383. Debug.out("INFORMATION: Mapping loading aborted", 1);
  384. return;
  385. }
  386. //splitting graphs
  387. //saving the layer for reuse later
  388. Layer tempLayer = currentLayer;
  389. //underlay graph
  390. LinkedList<MyGraph> graphs = g.getAllSubGraphs();
  391. Iterator<MyGraph> graphIter = graphs.iterator();
  392. while(graphIter.hasNext()){
  393. if(!"UNDERLAY".equalsIgnoreCase(graphIter.next().getAttribute("layer"))){
  394. graphIter.remove();
  395. }
  396. }
  397. MyGraph tempGraph = GraphHelper.newMerge(false, graphs.toArray(new MyGraph[0]));
  398. currentLayer = Layer.UNDERLAY;
  399. addGraph(tempGraph, true);
  400. GraphManager und = getGraphManager(Layer.UNDERLAY);
  401. // operator graph
  402. graphs = g.getAllSubGraphs();
  403. graphIter = graphs.iterator();
  404. while(graphIter.hasNext()){
  405. if(!"OPERATOR".equalsIgnoreCase(graphIter.next().getAttribute("layer"))){
  406. graphIter.remove();
  407. }
  408. }
  409. tempGraph = GraphHelper.newMerge(false, graphs.toArray(new MyGraph[0]));
  410. currentLayer = Layer.OPERATOR;
  411. addGraph(tempGraph, true);
  412. GraphManager op = getGraphManager(Layer.OPERATOR);
  413. // Mapping graph
  414. MyGraph moreTempGraph = new MyGraph(getGraphStringID(count));
  415. moreTempGraph.addAttribute("layer", Layer.MAPPING);
  416. MappingGraphManager map = new MappingGraphManager(moreTempGraph, und, op);
  417. count++;
  418. g.addAttribute("layer", Layer.MAPPING);
  419. g.addAttribute("ui.antialias");
  420. map.setStylesheet(StylesheetManager.DEFAULT_STYLESHEET);
  421. currentLayer = Layer.MAPPING;
  422. removeAllCurrentGraphs();
  423. vList.add(map);
  424. map.loadGraph(g);
  425. currentLayer = tempLayer;
  426. switchActiveGraph();
  427. }
  428. }