GraphManager.java 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. package de.tu_darmstadt.informatik.tk.scopviz.graphs;
  2. import java.util.Collection;
  3. import java.util.HashMap;
  4. import java.util.LinkedList;
  5. import org.graphstream.graph.Edge;
  6. import org.graphstream.graph.Element;
  7. import org.graphstream.graph.Node;
  8. import org.graphstream.ui.swingViewer.ViewPanel;
  9. import org.graphstream.ui.view.Viewer;
  10. import org.graphstream.ui.view.ViewerPipe;
  11. import de.tu_darmstadt.informatik.tk.scopviz.debug.Debug;
  12. import de.tu_darmstadt.informatik.tk.scopviz.main.CreationMode;
  13. import de.tu_darmstadt.informatik.tk.scopviz.main.Layer;
  14. import de.tu_darmstadt.informatik.tk.scopviz.main.Main;
  15. import de.tu_darmstadt.informatik.tk.scopviz.ui.GraphDisplayManager;
  16. import de.tu_darmstadt.informatik.tk.scopviz.ui.PropertiesManager;
  17. import de.tu_darmstadt.informatik.tk.scopviz.ui.StylesheetManager;
  18. import de.tu_darmstadt.informatik.tk.scopviz.ui.handlers.MyMouseManager;
  19. /**
  20. * Interface between GUI and internal Graph representation. Manages internal
  21. * representation of the Graph to accommodate creation and deletion of nodes and
  22. * edges.
  23. *
  24. * @author Jascha Bohne
  25. * @version 3.0.0.0
  26. *
  27. */
  28. public class GraphManager {
  29. /** String for the processing enabled type of node. */
  30. public static final String UI_CLASS_PROCESSING_ENABLED = "procEn";
  31. /** The Graph this instance of GraphManager manages. */
  32. protected MyGraph g;
  33. /**
  34. * The Stylesheet for this Graph, excluding parts that can be set by
  35. * NodeGraphics.
  36. */
  37. protected String stylesheet = "";
  38. /** the grpah that a Node was last deleted of */
  39. private String graphDeleteId;
  40. /** The last Node that was deleted. */
  41. protected Node deletedNode;
  42. /** The last Edge that was deleted. */
  43. protected LinkedList<Edge> deletedEdges = new LinkedList<>();
  44. /** The currently selected Node, mutually exclusive with selectedEdgeID. */
  45. protected String selectedNodeID = null;
  46. /** The currently selected Edge, mutually exclusive with selectedNodeID. */
  47. protected String selectedEdgeID = null;
  48. /** The ViewPanel the Graph is drawn in. */
  49. protected ViewPanel view;
  50. /** The Path on Disk the Graph will be saved to. */
  51. protected String currentPath;
  52. /** The Viewer the Graph provides, grants Access to Camera Manipulation. */
  53. protected Viewer viewer;
  54. /**
  55. * The Pipe that notifies the underlying Graph of any Changes within the
  56. * graphic Representation.
  57. */
  58. protected ViewerPipe fromViewer;
  59. /**
  60. * The Id of the Node that was last clicked.
  61. */
  62. protected String lastClickedID;
  63. /**
  64. * Creates a new Manager for the given graph.
  65. *
  66. * @param graph
  67. * the graph this visualizer should handle
  68. */
  69. public GraphManager(MyGraph graph) {
  70. g = graph;
  71. /* Viewer */ viewer = new Viewer(g, Viewer.ThreadingModel.GRAPH_IN_ANOTHER_THREAD);
  72. view = viewer.addDefaultView(false);
  73. viewer.setCloseFramePolicy(Viewer.CloseFramePolicy.EXIT);
  74. /* ViewerPipe */fromViewer = viewer.newViewerPipe();
  75. view.setMouseManager(new MyMouseManager(this));
  76. fromViewer.addSink(graph);
  77. fromViewer.removeElementSink(graph);
  78. }
  79. /**
  80. * Deletes the Node corresponding to the given ID from the Graph. The
  81. * referenced Graph is modified directly. Will throw an
  82. * ElementNotFoundException, when the Node is not Found Will also remove all
  83. * Edges connected to the given Node
  84. *
  85. * @param id
  86. * the ID of the node that will be removed
  87. */
  88. public void deleteNode(final String id) {
  89. deletedEdges.removeAll(deletedEdges);
  90. deletedNode = null;
  91. // Edges have to be deleted first because they clear deletedNode
  92. // and need the Node to still be in the Graph
  93. deleteEdgesOfNode(id);
  94. deletedNode = g.removeNode(id);
  95. graphDeleteId = GraphHelper.propagateElementDeletion(g, deletedNode);
  96. }
  97. /**
  98. * Deletes the Edge corresponding to the given ID from the Graph. The
  99. * referenced Graph is modified directly. Will throw an
  100. * ElementNotFoundException, when the Edge is not Found
  101. *
  102. * @param id
  103. * the ID of the Edge that will be removed
  104. */
  105. public void deleteEdge(final String id) {
  106. deselect();
  107. deletedEdges.removeAll(deletedEdges);
  108. deletedNode = null;
  109. deletedEdges.add(g.removeEdge(id));
  110. graphDeleteId = GraphHelper.propagateElementDeletion(g, deletedEdges);
  111. }
  112. /**
  113. * Deletes all Edges connected to the given Node. The referenced Graph is
  114. * modified directly. Will throw an ElementNotFoundException if the Node is
  115. * not Found
  116. *
  117. * @param id
  118. * the Id of the Node, whose Edges shall be removed
  119. */
  120. protected void deleteEdgesOfNode(final String id) {
  121. deselect();
  122. Node node = g.getNode(id);
  123. deletedEdges.removeAll(deletedEdges);
  124. deletedNode = null;
  125. Edge[] temp = new Edge[0];
  126. temp = g.getEdgeSet().toArray(temp);
  127. for (Edge e : temp) {
  128. if (e.getSourceNode().equals(node) || e.getTargetNode().equals(node)) {
  129. // adds the Edge to the list of deleted Edges and remove sit
  130. // from the Graph
  131. deletedEdges.add(g.removeEdge(e));
  132. }
  133. }
  134. GraphHelper.propagateElementDeletion(g, deletedEdges);
  135. }
  136. /**
  137. * Undoes the last deleting operation on the given Graph. Deleting
  138. * operations are: deleteNode, deleteEdge and deleteEdgesOfNode. Only undoes
  139. * the last deleting operation even if that operation didn't change the
  140. * Graph
  141. */
  142. public void undelete() {
  143. String newId = "";
  144. HashMap<String, Object> attributes = new HashMap<String, Object>();
  145. if (deletedNode != null) {
  146. for (String s : deletedNode.getAttributeKeySet()) {
  147. attributes.put(s, deletedNode.getAttribute(s));
  148. }
  149. newId = Main.getInstance().getUnusedID();
  150. g.addNode(newId);
  151. g.getNode(newId).addAttributes(attributes);
  152. String origElement = GraphHelper.propagateElementUndeletion(g, deletedNode, null);
  153. if(origElement != null){
  154. g.getNode(newId).addAttribute("originalElement", origElement);
  155. }
  156. }
  157. for (Edge e : deletedEdges) {
  158. String sourceId = null;
  159. String targetId = null;
  160. attributes = new HashMap<String, Object>();
  161. for (String s : e.getAttributeKeySet()) {
  162. attributes.put(s, e.getAttribute(s));
  163. }
  164. String id = Main.getInstance().getUnusedID();
  165. if (deletedNode != null) {
  166. sourceId = (e.getSourceNode().getId().equals(deletedNode.getId())) ? newId : e.getSourceNode().getId();
  167. targetId = (e.getTargetNode().getId().equals(deletedNode.getId())) ? newId : e.getTargetNode().getId();
  168. } else {
  169. sourceId = e.getSourceNode().getId();
  170. targetId = e.getTargetNode().getId();
  171. }
  172. g.addEdge(id, sourceId, targetId, e.isDirected());
  173. g.getEdge(id).addAttributes(attributes);
  174. String origElement = GraphHelper.propagateElementUndeletion(g, e, g.getNode(newId).getAttribute("originalElement"));
  175. if(origElement != null){
  176. g.getEdge(id).addAttribute("originalElement", origElement);
  177. }
  178. }
  179. deletedEdges = new LinkedList<>();
  180. deletedNode = null;
  181. }
  182. /**
  183. * returns a View of the Graph. The View lives in the Swing Thread and the
  184. * Graph in the Main thread.
  185. *
  186. *
  187. * @return a View of the Graph, inheriting from JPanel
  188. */
  189. public ViewPanel getView() {
  190. return view;
  191. }
  192. /**
  193. * Returns the ID of the currently selected Node.
  194. *
  195. * @return the node's ID
  196. */
  197. public String getSelectedNodeID() {
  198. return selectedNodeID;
  199. }
  200. /**
  201. * Returns the ID of the currently selected Edge.
  202. *
  203. * @return the edge's ID
  204. */
  205. public String getSelectedEdgeID() {
  206. return selectedEdgeID;
  207. }
  208. /**
  209. * Selects the Node with the given ID, resets Edge selection.
  210. *
  211. * @param nodeID
  212. * the ID of the Node to select
  213. */
  214. public void selectNode(String nodeID) {
  215. if (nodeID != null && g.getNode(nodeID) != null) {
  216. deselect();
  217. this.selectedNodeID = nodeID;
  218. Node n = g.getNode(nodeID);
  219. // set selected node color to red
  220. if (!hasClass(n, UI_CLASS_PROCESSING_ENABLED)
  221. || !GraphDisplayManager.getCurrentLayer().equals(Layer.MAPPING)) {
  222. n.changeAttribute("ui.style", "fill-color : #F00; size: 15px;");
  223. PropertiesManager.setItemsProperties();
  224. }
  225. }
  226. }
  227. /**
  228. * Selects the Edge with the given ID, resets Node selection.
  229. *
  230. * @param edgeID
  231. * the ID of the Edge to select
  232. */
  233. public void selectEdge(String edgeID) {
  234. if (edgeID != null && g.getEdge(edgeID) != null) {
  235. deselect();
  236. this.selectedEdgeID = edgeID;
  237. addClass(edgeID, "selected");
  238. PropertiesManager.setItemsProperties();
  239. }
  240. }
  241. /**
  242. * Deselect any currently selected nodes or edges.
  243. */
  244. // TODO call this before save
  245. protected void deselect() {
  246. // Set last selected Edge Color to Black
  247. if (getSelectedEdgeID() != null && g.getEdge(getSelectedEdgeID()) != null) {
  248. removeClass(getSelectedEdgeID(), "selected");
  249. }
  250. // Set last selected Node color to black
  251. else if (getSelectedNodeID() != null && g.getNode(getSelectedNodeID()) != null) {
  252. Node n = g.getNode(getSelectedNodeID());
  253. if (!hasClass(n, UI_CLASS_PROCESSING_ENABLED)
  254. || !GraphDisplayManager.getCurrentLayer().equals(Layer.MAPPING)) {
  255. String nodeType = n.getAttribute("ui.class");
  256. n.removeAttribute("ui.style");
  257. n.changeAttribute("ui.style", "fill-color: #000000; size: 15px;");
  258. n.changeAttribute("ui.class", nodeType.split("_")[0]);
  259. }
  260. }
  261. this.selectedNodeID = null;
  262. this.selectedEdgeID = null;
  263. }
  264. /**
  265. * Returns a reference to the Graph object managed by this visualizer.
  266. *
  267. * @return the graph
  268. */
  269. public MyGraph getGraph() {
  270. return g;
  271. }
  272. /**
  273. * Zooms in the view of the graph by 5 percent.
  274. */
  275. public void zoomIn() {
  276. zoom(-0.05);
  277. }
  278. /**
  279. * Zooms out the view of the graph by 5 percent.
  280. */
  281. public void zoomOut() {
  282. zoom(0.05);
  283. }
  284. /**
  285. * Zooms the view by the given Amount, positive values zoom out, negative
  286. * values zoom in.
  287. *
  288. * @param amount
  289. * the amount of zoom, should usually be between -0.2 and 0.2 for
  290. * reasonable zoom.
  291. */
  292. public void zoom(double amount) {
  293. view.getCamera().setViewPercent(view.getCamera().getViewPercent() * (1 + amount));
  294. }
  295. /**
  296. * Pumps the Pipe from the graphical Representation to the underlying Graph,
  297. * propagating all Changes made.
  298. */
  299. public void pumpIt() {
  300. fromViewer.pump();
  301. }
  302. @Override
  303. public String toString() {
  304. return "Visualizer for Graph \"" + g.getId() + "\"";
  305. }
  306. /**
  307. * Returns the current Save Path on Disk for the Graph.
  308. *
  309. * @return the current Path
  310. */
  311. public String getCurrentPath() {
  312. return currentPath;
  313. }
  314. /**
  315. * Sets the Save Path.
  316. *
  317. * @param currentPath
  318. * the new Path to set
  319. */
  320. public void setCurrentPath(String currentPath) {
  321. this.currentPath = currentPath;
  322. }
  323. /**
  324. * Adds a <b>Copy</b> of the given Edge to the graph. The Copy retains the
  325. * ID and all attributes.
  326. *
  327. * @param e
  328. * the Edge to be added to the graph
  329. */
  330. public void addEdge(Edge e) {
  331. HashMap<String, Object> attributes = new HashMap<>();
  332. for (String s : e.getAttributeKeySet()) {
  333. attributes.put(s, e.getAttribute(s));
  334. }
  335. g.addEdge(e.getId(), (Node) e.getSourceNode(), (Node) e.getTargetNode(), e.isDirected());
  336. g.getEdge(e.getId()).addAttributes(attributes);
  337. }
  338. /**
  339. * Adds a <b>Copy</b> of the given Node to the graph. The Copy retains the
  340. * ID and all attributes.
  341. *
  342. * @param n
  343. * the Node to be added to the graph
  344. */
  345. public void addNode(Node n) {
  346. HashMap<String, Object> attributes = new HashMap<>();
  347. for (String s : n.getAttributeKeySet()) {
  348. attributes.put(s, deletedNode.getAttribute(s));
  349. }
  350. g.addNode(n.getId());
  351. g.getNode(n.getId()).addAttributes(attributes);
  352. }
  353. /**
  354. * Returns the smallest X Coordinate of any Node in the Graph.
  355. *
  356. * @return the smallest X Coordinate in the Graph
  357. * @deprecated Use
  358. * {@link de.tu_darmstadt.informatik.tk.scopviz.graphs.MyGraph#getMinX()}
  359. * instead
  360. */
  361. public double getMinX() {
  362. return g.getMinX();
  363. }
  364. /**
  365. * Returns the biggest X Coordinate of any Node in the Graph.
  366. *
  367. * @return the biggest X Coordinate in the Graph
  368. * @deprecated Use
  369. * {@link de.tu_darmstadt.informatik.tk.scopviz.graphs.MyGraph#getMaxX()}
  370. * instead
  371. */
  372. public double getMaxX() {
  373. return g.getMaxX();
  374. }
  375. /**
  376. * Returns the smallest Y Coordinate of any Node in the Graph.
  377. *
  378. * @return the smallest Y Coordinate in the Graph
  379. * @deprecated Use
  380. * {@link de.tu_darmstadt.informatik.tk.scopviz.graphs.MyGraph#getMinY()}
  381. * instead
  382. */
  383. public double getMinY() {
  384. return g.getMinY();
  385. }
  386. /**
  387. * Returns the biggest Y Coordinate of any Node in the Graph.
  388. *
  389. * @return the biggest Y Coordinate in the Graph
  390. * @deprecated Use
  391. * {@link de.tu_darmstadt.informatik.tk.scopviz.graphs.MyGraph#getMaxY()}
  392. * instead
  393. */
  394. public double getMaxY() {
  395. return g.getMaxY();
  396. }
  397. /**
  398. * Returns the Stylesheet used by the Graph.
  399. *
  400. * @return the Stylesheet in use
  401. */
  402. public String getStylesheet() {
  403. return stylesheet;
  404. }
  405. /**
  406. * Sets the Stylesheet to be used by the Graph.
  407. *
  408. * @param stylesheet
  409. * the new stylesheet to use
  410. */
  411. public void setStylesheet(String stylesheet) {
  412. this.stylesheet = stylesheet;
  413. g.removeAttribute("ui.stylesheet");
  414. String completeStylesheet = stylesheet;
  415. completeStylesheet = completeStylesheet.concat(StylesheetManager.getNodeStylesheet());
  416. completeStylesheet = completeStylesheet
  417. .concat(StylesheetManager.getLayerStyle((Layer) g.getAttribute("layer")));
  418. g.addAttribute("ui.stylesheet", completeStylesheet);
  419. }
  420. /**
  421. * adds the given listener to the underlying graph the listener will be
  422. * notified, when an Edge is added.
  423. *
  424. * @param e
  425. * the EdgeCreatedListener
  426. */
  427. public void addEdgeCreatedListener(EdgeCreatedListener e) {
  428. ((MyGraph) g).addEdgeCreatedListener(e);
  429. }
  430. /**
  431. * adds the given listener to the underlying graph the listener will be
  432. * notified, when a Node is added.
  433. *
  434. * @param n
  435. * the NodeCreatedListener
  436. */
  437. public void addNodeCreatedListener(NodeCreatedListener n) {
  438. ((MyGraph) g).addNodeCreatedListener(n);
  439. }
  440. /**
  441. * Updates the Stylesheet, causing any changes to it to come into effect.
  442. */
  443. public void updateStylesheet() {
  444. setStylesheet(this.stylesheet);
  445. }
  446. /**
  447. * Sets typeofNode as the ui.class of all Nodes.
  448. *
  449. */
  450. public void convertUiClass() {
  451. Collection<Node> allNodes = g.getNodeSet();
  452. for (Node n : allNodes) {
  453. if (n.hasAttribute("typeofNode")) {
  454. n.addAttribute("ui.class", n.getAttribute("typeofNode").toString());
  455. }
  456. }
  457. }
  458. /**
  459. * Create Edges based on CreateMode.
  460. *
  461. * @param id
  462. * The ID for the newly created Edge
  463. */
  464. public void createEdges(String id) {
  465. switch (Main.getInstance().getCreationMode()) {
  466. case CREATE_DIRECTED_EDGE:
  467. case CREATE_UNDIRECTED_EDGE:
  468. if (lastClickedID == null) {
  469. lastClickedID = id;
  470. if (!selectNodeForEdgeCreation(lastClickedID)) {
  471. lastClickedID = null;
  472. }
  473. } else if (id.equals(lastClickedID) || createEdge(id, lastClickedID)) {
  474. deselectNodesAfterEdgeCreation(lastClickedID);
  475. lastClickedID = null;
  476. }
  477. break;
  478. default:
  479. break;
  480. }
  481. PropertiesManager.setItemsProperties();
  482. }
  483. /**
  484. * creates a edge between two nodes.
  485. *
  486. * @author MW
  487. * @param to
  488. * ID of the destination node
  489. * @param from
  490. * ID of the origin node
  491. * @return true if the edge was created. false otherwise
  492. */
  493. protected boolean createEdge(String to, String from) {
  494. if (getGraph().getNode(from).hasEdgeBetween(to))
  495. return false;
  496. String newID = Main.getInstance().getUnusedID();
  497. if (Main.getInstance().getCreationMode() == CreationMode.CREATE_DIRECTED_EDGE) {
  498. getGraph().addEdge(newID, from, to, true);
  499. Debug.out("Created an directed edge with Id " + newID + " between " + from + " and " + to);
  500. } else {
  501. getGraph().addEdge(newID, from, to);
  502. Debug.out("Created an undirected edge with Id " + newID + " between " + from + " and " + to);
  503. }
  504. selectEdge(newID);
  505. return true;
  506. }
  507. /**
  508. * Selects a Node as the starting point for creating a new Edge.
  509. *
  510. * @param nodeID
  511. * the ID of the Node to select
  512. */
  513. protected boolean selectNodeForEdgeCreation(String nodeID) {
  514. deselect();
  515. Node n = getGraph().getNode(nodeID);
  516. if (!hasClass(n, UI_CLASS_PROCESSING_ENABLED) || !GraphDisplayManager.getCurrentLayer().equals(Layer.MAPPING)) {
  517. n.changeAttribute("ui.style", "fill-color:green; size: 15px;");
  518. }
  519. return true;
  520. }
  521. /**
  522. * Reset the Selection of the Node after Edge has been successfully created.
  523. *
  524. * @param nodeID
  525. * the Id of the node to deselect.
  526. */
  527. protected void deselectNodesAfterEdgeCreation(String nodeID) {
  528. Node n = getGraph().getNode(nodeID);
  529. if (n == null) {
  530. return;
  531. }
  532. if (!hasClass(n, UI_CLASS_PROCESSING_ENABLED) || !GraphDisplayManager.getCurrentLayer().equals(Layer.MAPPING)) {
  533. n.removeAttribute("ui.style");
  534. n.changeAttribute("ui.style", "fill-color: #000000; size: 15px;");
  535. }
  536. }
  537. /**
  538. * Resets the selction of the Node for Edge selection
  539. */
  540. public void deselectEdgeCreationNodes() {
  541. if (lastClickedID != null)
  542. deselectNodesAfterEdgeCreation(lastClickedID);
  543. lastClickedID = null;
  544. }
  545. protected boolean addClass(String id, String className) {
  546. Element e = getGraph().getEdge(id);
  547. if (e == null)
  548. e = getGraph().getNode(id);
  549. if (e == null)
  550. return false;
  551. String eClass = e.getAttribute("ui.class");
  552. if (eClass == null || eClass.equals(""))
  553. eClass = className;
  554. else if (!(eClass.equals(className) || eClass.startsWith(className.concat(", "))
  555. || eClass.contains(", ".concat(className))))
  556. eClass = className.concat(", ").concat(eClass);
  557. e.addAttribute("ui.class", eClass);
  558. Debug.out("added " + className + ": " + eClass);
  559. return true;
  560. }
  561. protected boolean removeClass(String id, String className) {
  562. Element e = getGraph().getEdge(id);
  563. if (e == null)
  564. e = getGraph().getNode(id);
  565. if (e == null)
  566. return false;
  567. String eClass = e.getAttribute("ui.class");
  568. if (eClass == null || eClass.equals(className))
  569. eClass = "";
  570. else
  571. eClass = eClass.replace(className.concat(", "), "").replace(", ".concat(className), "");
  572. e.addAttribute("ui.class", eClass);
  573. Debug.out("removed " + className + ": " + eClass);
  574. return true;
  575. }
  576. protected boolean toggleClass(String id, String className) {
  577. Element e = getGraph().getEdge(id);
  578. if (e == null)
  579. e = getGraph().getNode(id);
  580. if (e == null)
  581. return false;
  582. String eClass = e.getAttribute("ui.class");
  583. if (eClass == null || !(eClass.equals(className) || eClass.startsWith(className.concat(", "))
  584. || eClass.contains(", ".concat(className))))
  585. return addClass(id, className);
  586. return removeClass(id, className);
  587. }
  588. protected boolean hasClass(String id, String className) {
  589. Element e = getGraph().getEdge(id);
  590. if (e == null)
  591. e = getGraph().getNode(id);
  592. if (e == null)
  593. return false;
  594. String eClass = e.getAttribute("ui.class");
  595. return (eClass != null && (eClass.equals(className) || eClass.startsWith(className.concat(", "))
  596. || eClass.contains(", ".concat(className))));
  597. }
  598. protected boolean hasClass(Edge e, String className) {
  599. if (e == null)
  600. return false;
  601. String eClass = e.getAttribute("ui.class");
  602. return (eClass != null && (eClass.equals(className) || eClass.startsWith(className.concat(", "))
  603. || eClass.contains(", ".concat(className))));
  604. }
  605. protected boolean hasClass(Node n, String className) {
  606. if (n == null)
  607. return false;
  608. String nClass = n.getAttribute("ui.class");
  609. /*
  610. * TODO: nochmal angucken, wenn CSS Manager steht, ist gerade gehackt
  611. * damit, Vorführung läuft. return (nClass != null &&
  612. * (nClass.equals(className) ||
  613. * nClass.startsWith(className.concat(", ")) ||
  614. * nClass.contains(", ".concat(className))));
  615. */
  616. return (nClass != null && nClass.contains(className));
  617. }
  618. }