ToolboxManager.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. package de.tu_darmstadt.informatik.tk.scopviz.ui;
  2. import java.util.Optional;
  3. import de.tu_darmstadt.informatik.tk.scopviz.graphs.GraphHelper;
  4. import de.tu_darmstadt.informatik.tk.scopviz.graphs.MyEdge;
  5. import de.tu_darmstadt.informatik.tk.scopviz.main.CreationMode;
  6. import de.tu_darmstadt.informatik.tk.scopviz.main.Main;
  7. import de.tu_darmstadt.informatik.tk.scopviz.main.MainApp;
  8. import javafx.application.Platform;
  9. import javafx.beans.property.ReadOnlyObjectWrapper;
  10. import javafx.beans.value.ObservableValue;
  11. import javafx.collections.FXCollections;
  12. import javafx.collections.ObservableList;
  13. import javafx.scene.Node;
  14. import javafx.scene.control.CheckBox;
  15. import javafx.scene.control.TableCell;
  16. import javafx.scene.control.TableColumn;
  17. import javafx.scene.control.TableRow;
  18. import javafx.scene.control.TextInputDialog;
  19. import javafx.scene.image.Image;
  20. import javafx.scene.image.ImageView;
  21. import javafx.scene.input.MouseEvent;
  22. import javafx.util.Callback;
  23. import javafx.util.Pair;
  24. /**
  25. * Manager for the Toolbox pane.
  26. *
  27. * @author Dominik Renkel
  28. * @version 2.0
  29. *
  30. */
  31. public final class ToolboxManager {
  32. /**
  33. * GUIController reference
  34. */
  35. private static GUIController controller;
  36. /**
  37. * needed, so that MouseClickedEvent is not fired, when SelectionProperty
  38. * was changed
  39. */
  40. private static boolean selectedPropertyChanged = false;
  41. /**
  42. * private constructor to prevent Instantiation.
  43. */
  44. private ToolboxManager() {
  45. }
  46. /**
  47. * Initialize Toolbox, set controller
  48. *
  49. * @param guiController
  50. */
  51. public static void initialize(GUIController guiController) {
  52. controller = guiController;
  53. }
  54. /**
  55. * Initializes the toolbox to contain the specified list of entries.
  56. *
  57. */
  58. public static void initializeItems() {
  59. setUnderlayItems();
  60. }
  61. /**
  62. * Create Row Elements for underlay toolbox view
  63. */
  64. public static void setUnderlayItems() {
  65. @SuppressWarnings("unchecked")
  66. ObservableList<Pair<Object, String>> data = FXCollections.observableArrayList(
  67. pair(new Image(MainApp.class
  68. .getResource("/de/tu_darmstadt/informatik/tk/scopviz/ui/standard_operator.png").toString()),
  69. "Standard"),
  70. pair(new Image(
  71. MainApp.class.getResource("/de/tu_darmstadt/informatik/tk/scopviz/ui/procEn.png").toString()),
  72. "ProcEn"),
  73. pair(new Image(
  74. MainApp.class.getResource("/de/tu_darmstadt/informatik/tk/scopviz/ui/source.png").toString()),
  75. "Source"),
  76. pair(new Image(
  77. MainApp.class.getResource("/de/tu_darmstadt/informatik/tk/scopviz/ui/sink.png").toString()),
  78. "Sink"),
  79. pair(new Image(MainApp.class.getResource("/de/tu_darmstadt/informatik/tk/scopviz/ui/undirEdge.png")
  80. .toString()), "Undirected"));
  81. controller.toolbox.getItems().setAll(data);
  82. }
  83. /**
  84. * create row elements for operator toolbox view
  85. */
  86. public static void setOperatorItems() {
  87. @SuppressWarnings("unchecked")
  88. ObservableList<Pair<Object, String>> data = FXCollections.observableArrayList(
  89. pair(new Image(MainApp.class
  90. .getResource("/de/tu_darmstadt/informatik/tk/scopviz/ui/standard_operator.png").toString()),
  91. "Operator"),
  92. pair(new Image(
  93. MainApp.class.getResource("/de/tu_darmstadt/informatik/tk/scopviz/ui/source.png").toString()),
  94. "Source"),
  95. pair(new Image(
  96. MainApp.class.getResource("/de/tu_darmstadt/informatik/tk/scopviz/ui/sink.png").toString()),
  97. "Sink"),
  98. pair(new Image(
  99. MainApp.class.getResource("/de/tu_darmstadt/informatik/tk/scopviz/ui/dirEdge.png").toString()),
  100. "Directed"));
  101. controller.toolbox.getItems().setAll(data);
  102. }
  103. /**
  104. * create row elements for mapping toolbox view
  105. */
  106. public static void setMappingItems() {
  107. @SuppressWarnings("unchecked")
  108. ObservableList<Pair<Object, String>> data = FXCollections.observableArrayList(pair(
  109. new Image(
  110. MainApp.class.getResource("/de/tu_darmstadt/informatik/tk/scopviz/ui/dirEdge.png").toString()),
  111. "Mapping Edge"));
  112. controller.toolbox.getItems().setAll(data);
  113. }
  114. /**
  115. * fired when the selected item in the Toolbox was changed
  116. *
  117. * @param ov
  118. * @param oldVal
  119. * the previous selected item
  120. * @param newVal
  121. * the new selected item
  122. */
  123. public static void selectedItemChanged(ObservableValue<? extends Pair<Object, String>> ov,
  124. Pair<Object, String> oldVal, Pair<Object, String> newVal) {
  125. if (newVal != null) {
  126. // change creation mode based on selected item
  127. String rowString = newVal.getValue();
  128. if (rowString.equals("Standard")) {
  129. changeCreationMode(CreationMode.CREATE_STANDARD_NODE);
  130. } else if (rowString.equals("Source")) {
  131. changeCreationMode(CreationMode.CREATE_SOURCE_NODE);
  132. } else if (rowString.equals("Sink")) {
  133. changeCreationMode(CreationMode.CREATE_SINK_NODE);
  134. } else if (rowString.equals("ProcEn")) {
  135. changeCreationMode(CreationMode.CREATE_PROC_NODE);
  136. } else if (rowString.equals("Operator")) {
  137. changeCreationMode(CreationMode.CREATE_OPERATOR_NODE);
  138. } else if (rowString.equals("Directed")) {
  139. changeCreationMode(CreationMode.CREATE_DIRECTED_EDGE);
  140. } else if (rowString.equals("Undirected")) {
  141. changeCreationMode(CreationMode.CREATE_UNDIRECTED_EDGE);
  142. } else if (rowString.equals("Mapping Edge")) {
  143. changeCreationMode(CreationMode.CREATE_DIRECTED_EDGE);
  144. }
  145. } else {
  146. // selected item was an empty row
  147. Main.getInstance().setCreationMode(CreationMode.CREATE_NONE);
  148. }
  149. // Unselecet Rows if Creation Mode is None
  150. if (Main.getInstance().getCreationMode().equals(CreationMode.CREATE_NONE)) {
  151. controller.toolbox.getSelectionModel().clearSelection();
  152. Main.getInstance().getGraphManager().deselectEdgeCreationNodes();
  153. }
  154. // set this property to true, so the MouseClickedHandler doesn't also
  155. // fire its event
  156. selectedPropertyChanged = true;
  157. }
  158. /**
  159. * fired when a row was clicked
  160. *
  161. * @param event
  162. */
  163. @SuppressWarnings("unchecked")
  164. public static void rowClickedHandler(MouseEvent event) {
  165. // only use the handler when the selectionProperty Listener didn't fire
  166. // its event
  167. if (selectedPropertyChanged) {
  168. selectedPropertyChanged = false;
  169. return;
  170. }
  171. // Get the clicked TableRow
  172. Node node = ((Node) event.getTarget()).getParent();
  173. TableRow<Pair<Object, String>> row = null;
  174. if (node instanceof TableRow) {
  175. row = (TableRow<Pair<Object, String>>) node;
  176. } else {
  177. // clicking on picture part
  178. try {
  179. row = (TableRow<Pair<Object, String>>) node.getParent();
  180. } catch (ClassCastException e) {
  181. // there was a dragging move one the picture part when this
  182. // exception is thrown -> cant get row from this action
  183. return;
  184. }
  185. }
  186. // clear selection if selected row was clicked again
  187. if (row.isEmpty()
  188. || controller.toolbox.getSelectionModel().selectedItemProperty().get().equals(row.getItem())) {
  189. controller.toolbox.getSelectionModel().clearSelection();
  190. }
  191. }
  192. /**
  193. * If currentMode already selected then deselect, otherwise set mode on
  194. * currentMode
  195. *
  196. * @param currentMode
  197. */
  198. private static void changeCreationMode(CreationMode currentMode) {
  199. if (Main.getInstance().getCreationMode().equals(currentMode))
  200. Main.getInstance().setCreationMode(CreationMode.CREATE_NONE);
  201. else
  202. Main.getInstance().setCreationMode(currentMode);
  203. }
  204. /**
  205. * create a pair object under given picture and name
  206. *
  207. * @param picture
  208. * @param name
  209. * @return
  210. */
  211. private static Pair<Object, String> pair(Object picture, String name) {
  212. return new Pair<>(picture, name);
  213. }
  214. /**
  215. * the last edge that was created
  216. */
  217. private static MyEdge lastCreatedEdge = null;
  218. /**
  219. * opens a dialog that asks for a weight for a newly created Edge. The
  220. * default value is Optionsmanager.getDefaultWeight()
  221. *
  222. * @param e
  223. * the new Edge that needs a weight
  224. */
  225. public static void createWeightDialog(MyEdge e) {
  226. if (e.equals(lastCreatedEdge)) {
  227. return;
  228. }
  229. lastCreatedEdge = e;
  230. Platform.runLater(() -> {
  231. TextInputDialog weightDialog = new TextInputDialog(Double.toString(OptionsManager.getDefaultWeight()));
  232. weightDialog.setTitle("Edge Weight");
  233. weightDialog.setHeaderText("Please enter the weight of the Edge");
  234. weightDialog.setContentText("Edge Weight");
  235. Optional<String> result = weightDialog.showAndWait();
  236. if (result.isPresent()) {
  237. e.addAttribute("weight", Double.parseDouble(result.get()));
  238. GraphHelper.propagateAttribute(Main.getInstance().getGraphManager().getGraph(), e, "weight",
  239. Double.parseDouble(result.get()));
  240. }
  241. });
  242. }
  243. /**
  244. * Class for getting the string out of the pair elements in each row
  245. *
  246. */
  247. public static class PairKeyFactory
  248. implements Callback<TableColumn.CellDataFeatures<Pair<Object, String>, String>, ObservableValue<String>> {
  249. @Override
  250. public ObservableValue<String> call(TableColumn.CellDataFeatures<Pair<Object, String>, String> data) {
  251. return new ReadOnlyObjectWrapper<>(data.getValue().getValue());
  252. }
  253. }
  254. /**
  255. * Class for getting the picture out of the pair elements in each row
  256. *
  257. */
  258. public static class PairValueFactory
  259. implements Callback<TableColumn.CellDataFeatures<Pair<Object, String>, Object>, ObservableValue<Object>> {
  260. @SuppressWarnings("unchecked")
  261. @Override
  262. public ObservableValue<Object> call(TableColumn.CellDataFeatures<Pair<Object, String>, Object> data) {
  263. Object value = data.getValue().getKey();
  264. return (value instanceof ObservableValue) ? (ObservableValue<Object>) value
  265. : new ReadOnlyObjectWrapper<>(value);
  266. }
  267. }
  268. /**
  269. * The actual TableCell, that renders the images of nodes and edges. (Image,
  270. * String)-Cell additional support for (String, String), (Integer, String),
  271. * (Boolean, String), ("N/A", String) table cells
  272. *
  273. */
  274. public static class PairValueCell extends TableCell<Pair<Object, String>, Object> {
  275. @Override
  276. protected void updateItem(Object item, boolean empty) {
  277. super.updateItem(item, empty);
  278. if (item != null) {
  279. if (item instanceof String) {
  280. setText((String) item);
  281. setGraphic(null);
  282. } else if (item instanceof Integer) {
  283. setText(Integer.toString((Integer) item));
  284. setGraphic(null);
  285. } else if (item instanceof Boolean) {
  286. CheckBox checkBox = new CheckBox();
  287. checkBox.setSelected((boolean) item);
  288. setGraphic(checkBox);
  289. } else if (item instanceof Image) {
  290. setText(null);
  291. ImageView imageView = new ImageView((Image) item);
  292. imageView.setFitWidth(20);
  293. imageView.setFitHeight(20);
  294. imageView.setPreserveRatio(true);
  295. imageView.setSmooth(true);
  296. setGraphic(imageView);
  297. } else {
  298. setText("N/A");
  299. setGraphic(null);
  300. }
  301. } else {
  302. setText(null);
  303. setGraphic(null);
  304. }
  305. }
  306. }
  307. private static org.graphstream.graph.Node lastCreatedNode = null;
  308. public static void createProcMaxDialog(org.graphstream.graph.Node n) {
  309. if (n.equals(lastCreatedNode)) {
  310. return;
  311. }
  312. lastCreatedNode = n;
  313. Platform.runLater(() -> {
  314. TextInputDialog weightDialog = new TextInputDialog(Double.toString(OptionsManager.getDefaultWeight()));
  315. weightDialog.setTitle("Maximum Processing Power");
  316. weightDialog.setHeaderText("Please enter the maximum processing power of the Node");
  317. weightDialog.setContentText("processing power");
  318. Optional<String> result = weightDialog.showAndWait();
  319. org.graphstream.graph.Node actualNode = Main.getInstance().getGraphManager().getGraph().getNode(n.getId());
  320. if (result.isPresent()) {
  321. actualNode.addAttribute("process-max", Double.parseDouble(result.get()));
  322. GraphHelper.propagateAttribute(Main.getInstance().getGraphManager().getGraph(), actualNode,
  323. "process-max", Double.parseDouble(result.get()));
  324. }
  325. PropertiesManager.setItemsProperties();
  326. });
  327. }
  328. public static void createProcNeedDialog(org.graphstream.graph.Node n) {
  329. if (n.equals(lastCreatedNode)) {
  330. return;
  331. }
  332. lastCreatedNode = n;
  333. Platform.runLater(() -> {
  334. TextInputDialog weightDialog = new TextInputDialog(Double.toString(OptionsManager.getDefaultWeight()));
  335. weightDialog.setTitle("needed Processing power");
  336. weightDialog.setHeaderText("Please enter the amount of processing power the node needs");
  337. weightDialog.setContentText("needed Power");
  338. Optional<String> result = weightDialog.showAndWait();
  339. org.graphstream.graph.Node actualNode = Main.getInstance().getGraphManager().getGraph().getNode(n.getId());
  340. if(actualNode == null){
  341. actualNode = Main.getInstance().getGraphManager().getGraph().getNode(Main.getInstance().getGraphManager().getActiveSubGraph().getId() + n.getId());
  342. }
  343. if (result.isPresent() && actualNode!= null) {
  344. try {
  345. actualNode.addAttribute("process-need", Double.parseDouble(result.get()));
  346. } catch (Exception e){
  347. actualNode.addAttribute("process-need", 0.0);
  348. }
  349. GraphHelper.propagateAttribute(Main.getInstance().getGraphManager().getGraph(), actualNode,
  350. "process-need", Double.parseDouble(result.get()));
  351. }
  352. PropertiesManager.setItemsProperties();
  353. });
  354. }
  355. }