GraphDisplayManager.java 14 KB

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