Gui.java 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690
  1. package holeg.ui.view.main;
  2. import holeg.interfaces.LocalMode;
  3. import holeg.model.*;
  4. import holeg.preferences.ColorPreference;
  5. import holeg.preferences.ImagePreference;
  6. import holeg.preferences.PreferenceKeys;
  7. import holeg.ui.controller.Control;
  8. import holeg.ui.model.GuiSettings;
  9. import holeg.ui.view.canvas.Canvas;
  10. import holeg.ui.view.category.CategoryPanel;
  11. import holeg.ui.view.component.ButtonTabComponent;
  12. import holeg.ui.view.dialog.*;
  13. import holeg.ui.view.image.Import;
  14. import holeg.ui.view.information.HolonInformationPanel;
  15. import holeg.ui.view.inspector.Inspector;
  16. import holeg.ui.view.inspector.UnitGraph;
  17. import holeg.ui.view.window.AddOnWindow;
  18. import holeg.ui.view.window.FlexWindow;
  19. import holeg.ui.view.window.Outliner;
  20. import holeg.utility.listener.WindowClosingListener;
  21. import javax.swing.*;
  22. import javax.swing.filechooser.FileNameExtensionFilter;
  23. import javax.swing.filechooser.FileSystemView;
  24. import java.awt.*;
  25. import java.awt.event.*;
  26. import java.io.File;
  27. import java.net.URI;
  28. import java.util.logging.Logger;
  29. import java.util.prefs.Preferences;
  30. /**
  31. * Graphical User Interface.
  32. *
  33. * @author Gruppe14
  34. */
  35. public class Gui extends JFrame{
  36. private static final Logger log = Logger.getLogger(Model.class.getName());
  37. private static final Preferences prefs = Preferences.userNodeForPackage(Gui.class);
  38. private final JSplitPane splitPane = new JSplitPane();
  39. private final JSplitPane splitPane1 = new JSplitPane();
  40. private final JPanel myPanel = new JPanel(new BorderLayout());
  41. // the tabbed canvas containing the different sub-net tabs of the grid (Main
  42. // Grid + Nodes of Nodes)
  43. private final JTabbedPane tabbedPaneInnerOriginal = new JTabbedPane(JTabbedPane.TOP);
  44. // the main canvas where we can see the grid currently displayed
  45. private final JScrollPane canvasSP = new JScrollPane();
  46. private final CategoryPanel categoryPanel;
  47. // private final JScrollPane holonSP = new JScrollPane();
  48. // the original tabbed Pane (containing tabs for view, statistics, holon,
  49. // flexibility)
  50. private final JTabbedPane tabbedPaneOriginal = new JTabbedPane(JTabbedPane.TOP);
  51. private final JPopupMenu popmenuEdit = new JPopupMenu();
  52. private final JMenuItem editItem = new JMenuItem("Edit Object");
  53. /******************************************
  54. ************* Right Container*************
  55. ******************************************
  56. * Right Container: here comes the information about the HolonObject, such as
  57. * HolonElements Information, Properties and Consumption/Production graph.
  58. **/
  59. private final Inspector inspector;
  60. private final HolonInformationPanel informationPanel;
  61. private final JSplitPane splitHolonElPro = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
  62. private final JScrollPane scrollProperties = new JScrollPane();
  63. // In this section is the graph for the selected HolonElement of the clicked
  64. private final Control control;
  65. // In this section are all the Holonelements that correspond to the clicked
  66. // HolonObject with consumption/production, name and amount.
  67. private final UnitGraph unitGraph;
  68. /**
  69. * Textfield to show the period of an element
  70. */
  71. private final JTextField unitGraphLocalPeriod = new JTextField(6);
  72. private final Canvas canvas;
  73. // tabbedPaneOriginal or tabbedPaneSplit
  74. private JTabbedPane tabTemp;
  75. private Canvas actualOpenCanvas;
  76. private JPanel contentPane;
  77. // Time Stuff
  78. private TimePanel timePanel;
  79. private final JMenuItem removeItem = new JMenuItem("Remove");
  80. /**
  81. * Create the application.
  82. *
  83. * @param control the Controller
  84. */
  85. public Gui(Control control) {
  86. this.control = control;
  87. this.informationPanel = new HolonInformationPanel(control);
  88. inspector = new Inspector(control);
  89. control.calculateStateAndVisualForCurrentTimeStep();
  90. this.unitGraph = new UnitGraph(control);
  91. this.canvas = new Canvas(control, control.getModel().getCanvas());
  92. this.categoryPanel = new CategoryPanel(control, this);
  93. this.actualOpenCanvas = this.canvas;
  94. initialize();
  95. }
  96. public TimePanel getTimePanel() {
  97. return timePanel;
  98. }
  99. /**
  100. * Initialize the contents of the frame.
  101. */
  102. private void initialize() {
  103. this.setTitle("HOLEG Simulator");
  104. this.setBounds(new Rectangle(1200, 800));
  105. //Center
  106. this.setLocationRelativeTo(null);
  107. this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
  108. this.addWindowListener((WindowClosingListener) e -> {
  109. if (JOptionPane.showConfirmDialog(this, "Are you sure you want to exit?", "HOLEG",
  110. JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
  111. System.exit(0);
  112. }
  113. });
  114. contentPane = (JPanel) this.getContentPane();
  115. int condition = JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT;
  116. InputMap inputMap = contentPane.getInputMap(condition);
  117. ActionMap actionMap = contentPane.getActionMap();
  118. String cntrlZDown = "controlZ";
  119. inputMap.put(KeyStroke.getKeyStroke("control Z"), cntrlZDown);
  120. actionMap.put(cntrlZDown, new AbstractAction() {
  121. @Override
  122. public void actionPerformed(ActionEvent e) {
  123. //TODO(Tom2022-01-27): CtrlZ
  124. }
  125. });
  126. String cntrlYDown = "controlY";
  127. inputMap.put(KeyStroke.getKeyStroke("control Y"), cntrlYDown);
  128. actionMap.put(cntrlYDown, new AbstractAction() {
  129. @Override
  130. public void actionPerformed(ActionEvent e) {
  131. //TODO Ctrl Y
  132. }
  133. });
  134. String cntrlADown = "controlA";
  135. inputMap.put(KeyStroke.getKeyStroke("control A"), cntrlADown);
  136. AbstractAction controlA = new AbstractAction() {
  137. @Override
  138. public void actionPerformed(ActionEvent e) {
  139. GuiSettings.getSelectedObjects().clear();
  140. //TODO(Tom2022-01-27): Ctrl A
  141. }
  142. };
  143. actionMap.put(cntrlADown, controlA);
  144. String delDown = "delete";
  145. inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0, false), delDown);
  146. actionMap.put(delDown, new AbstractAction() {
  147. private static final long serialVersionUID = 1L;
  148. @Override
  149. public void actionPerformed(ActionEvent e) {
  150. chooseTabTemp();
  151. //TODO(Tom2022-01-27): delete
  152. GuiSettings.getSelectedObjects().clear();
  153. }
  154. });
  155. String cntrlCDown = "controlC";
  156. inputMap.put(KeyStroke.getKeyStroke("control C"), cntrlCDown);
  157. AbstractAction controlC = new AbstractAction() {
  158. private static final long serialVersionUID = 1L;
  159. @Override
  160. public void actionPerformed(ActionEvent e) {
  161. chooseTabTemp();
  162. JScrollPane scrollPane = getScrollPaneFromTabbedPane();
  163. if (!GuiSettings.getSelectedObjects().isEmpty()) {
  164. if (scrollPane.getViewport().getComponent(0) instanceof Canvas groupNodeCanvas)
  165. control.copy(groupNodeCanvas.getGroupNode());
  166. else
  167. control.copy(null);
  168. if (!GuiSettings.getClipboardObjects().isEmpty()) {
  169. //TODO(Tom2022-01-14): old code changes itemPaste
  170. //OLD: canvas.itemPaste.setEnabled(true);
  171. }
  172. }
  173. }
  174. };
  175. actionMap.put(cntrlCDown, controlC);
  176. String cntrlVDown = "controlV";
  177. inputMap.put(KeyStroke.getKeyStroke("control V"), cntrlVDown);
  178. AbstractAction controlV = new AbstractAction() {
  179. private static final long serialVersionUID = 1L;
  180. @Override
  181. public void actionPerformed(ActionEvent e) {
  182. //TODO(Tom2022-01-27): Paste
  183. }
  184. };
  185. actionMap.put(cntrlVDown, controlV);
  186. String cntrlXDown = "controlX";
  187. inputMap.put(KeyStroke.getKeyStroke("control X"), cntrlXDown);
  188. AbstractAction controlX = new AbstractAction() {
  189. private static final long serialVersionUID = 1L;
  190. @Override
  191. public void actionPerformed(ActionEvent e) {
  192. chooseTabTemp();
  193. JScrollPane scrollPane = getScrollPaneFromTabbedPane();
  194. if (!GuiSettings.getSelectedObjects().isEmpty()) {
  195. if (scrollPane.getViewport().getComponent(0) instanceof Canvas groupNodeCanvas) {
  196. control.cut(groupNodeCanvas.getGroupNode());
  197. control.calculateStateAndVisualForCurrentTimeStep();
  198. scrollPane.getViewport().getComponent(0).repaint();
  199. } else {
  200. control.cut(null);
  201. control.calculateStateAndVisualForCurrentTimeStep();
  202. log.info("canvas.repaint3");
  203. canvas.repaint();
  204. }
  205. if (!GuiSettings.getClipboardObjects().isEmpty()) {
  206. //TODO(Tom2022-01-14): old code changes itemPaste
  207. //OLD: canvas.itemPaste.setEnabled(true);
  208. }
  209. }
  210. }
  211. };
  212. actionMap.put(cntrlXDown, controlX);
  213. this.setJMenuBar(new GuiMenuBar());
  214. this.setIconImage(Import.loadImage(ImagePreference.Logo, 30, 30));
  215. tabbedPaneInnerOriginal.addChangeListener(change -> {
  216. control.clearSelection();
  217. });
  218. /**
  219. * add Help Menu and its items
  220. */
  221. canvas.setBackground(Color.WHITE);
  222. canvas.setPreferredSize(new Dimension(GuiSettings.canvasSize.getX(), GuiSettings.canvasSize.getY()));
  223. /***********************
  224. * HolonElement Graph Actions
  225. **********************/
  226. /*
  227. * Update Local Period of an Element Graph
  228. */
  229. unitGraphLocalPeriod.addKeyListener(new KeyAdapter() {
  230. @Override
  231. public void keyReleased(KeyEvent e) {
  232. try {
  233. int localLength = Integer.parseInt(unitGraphLocalPeriod.getText());
  234. unitGraphLocalPeriod.setBackground(Color.WHITE);
  235. /**
  236. * set local graph Period
  237. */
  238. if (e.getKeyCode() == KeyEvent.VK_ENTER) {
  239. LocalMode.Period period = new LocalMode.Period(localLength);
  240. period.setInterval(localLength);
  241. unitGraph.setPeriod(period);
  242. }
  243. } catch (NumberFormatException ex) {
  244. unitGraphLocalPeriod.setBackground(ColorPreference.GUI.PALE_RED);
  245. }
  246. }
  247. });
  248. /*****************************
  249. * RIGHT CONTAINER DONE
  250. *****************************/
  251. this.getContentPane().setLayout(new BorderLayout(0, 0));
  252. /****************
  253. * Tree Stuff
  254. ****************/
  255. popmenuEdit.add(editItem);
  256. popmenuEdit.add(removeItem);
  257. editItem.setEnabled(false);
  258. String catOfObjToBeEdited = "TEST";
  259. editItem.addActionListener(actionEvent -> {
  260. // Remove the selected Object object
  261. // AddObjectPopUp(boolean edit, AbstractCpsObject obj, String cat, JFrame
  262. // parentFrame)
  263. log.warning("EDITITEM");
  264. AddObjectPopUp addObjectPopUP = new AddObjectPopUp(true, null, catOfObjToBeEdited, this);
  265. addObjectPopUP.setCategory(catOfObjToBeEdited);
  266. addObjectPopUP.setController(control);
  267. addObjectPopUP.setVisible(true);
  268. });
  269. removeItem.addActionListener(actionEvent -> {
  270. // Remove the selected Object object
  271. log.warning("REMOVEITEM");
  272. log.info("catOfObjToBeEdited:" + catOfObjToBeEdited + ", tempCps:" + null);
  273. control.findCategoryWithName(catOfObjToBeEdited).ifPresent(cat -> {
  274. cat.removeObjectsWithName("");
  275. });
  276. });
  277. this.getContentPane().add(splitPane);
  278. timePanel = new TimePanel(control);
  279. timePanel.setBorder(null);
  280. timePanel.getTimeSlider().addChangeListener(changeEvent -> {
  281. // TimeSliderChanged event
  282. control.calculateStateAndVisualForTimeStep(timePanel.getTimeSlider().getValue());
  283. unitGraph.repaint();
  284. contentPane.updateUI();
  285. });
  286. splitPane1.setMinimumSize(new Dimension(0, 25));
  287. splitPane.setRightComponent(splitPane1);
  288. splitPane.setDividerLocation(200);
  289. splitPane1.setDividerLocation(500);
  290. splitPane.setLeftComponent(categoryPanel);
  291. tabbedPaneOriginal.addTab("View", tabbedPaneInnerOriginal);
  292. myPanel.add(canvasSP, BorderLayout.CENTER);
  293. tabbedPaneInnerOriginal.addTab("Main Grid", myPanel);
  294. splitPane1.setLeftComponent(tabbedPaneOriginal);
  295. splitPane1.setRightComponent(splitHolonElPro);
  296. splitPane1.setResizeWeight(0.9);
  297. splitHolonElPro.setDividerLocation(700);
  298. // containing the graph and the elements-list
  299. splitHolonElPro.setTopComponent(inspector);
  300. // containing the object's properties
  301. splitHolonElPro.setBottomComponent(scrollProperties);
  302. canvasSP.setViewportView(canvas);
  303. // Set up of the Properties section
  304. scrollProperties.setViewportView(this.informationPanel);
  305. scrollProperties.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
  306. scrollProperties.getVerticalScrollBar().setUnitIncrement(16);
  307. tabbedPaneOriginal.setBorder(null);
  308. scrollProperties.setBorder(null);
  309. splitPane.setBorder(null);
  310. splitPane1.setBorder(null);
  311. splitHolonElPro.setBorder(null);
  312. canvasSP.setBorder(null);
  313. this.getContentPane().add(timePanel, BorderLayout.SOUTH);
  314. canvasSP.addComponentListener(new ComponentAdapter() {
  315. @Override
  316. public void componentResized(ComponentEvent e) {
  317. GuiSettings.canvasSize.setX(Math.max(GuiSettings.canvasSize.getX(), canvasSP.getViewport().getWidth()));
  318. GuiSettings.canvasSize
  319. .setY(Math.max(GuiSettings.canvasSize.getY(), canvasSP.getViewport().getHeight()));
  320. log.info("canvas.repaint11");
  321. canvas.repaint();
  322. }
  323. });
  324. }
  325. /*
  326. * Open a new Tab with an UpperNodeCanvas
  327. */
  328. public void openNewUpperNodeTab(GroupNode node) {
  329. chooseTabTemp();
  330. JScrollPane scrollPane = getScrollPaneFromTabbedPane();
  331. if (scrollPane.getViewport().getComponent(0) instanceof Canvas canvasPanel) {
  332. actualOpenCanvas = new Canvas(control, node);
  333. }
  334. // check if tab already open for clicked NodeOfNode
  335. boolean dupl = false;
  336. for (int i = 1; i < tabbedPaneInnerOriginal.getTabCount(); i++) {
  337. JScrollPane paneOriginal = (JScrollPane) tabbedPaneInnerOriginal.getComponentAt(i);
  338. if (paneOriginal != null && ((Canvas) paneOriginal.getViewport().getComponent(0)).getGroupNode()
  339. .getId() == node.getId()) {
  340. dupl = true;
  341. // set selected component to view
  342. tabbedPaneOriginal.setSelectedComponent(tabbedPaneInnerOriginal);
  343. // set selected tab in view to found upper-node-canvas
  344. tabbedPaneInnerOriginal.setSelectedComponent(tabbedPaneInnerOriginal.getComponentAt(i));
  345. }
  346. // if we found a duplicate, break
  347. if (dupl) {
  348. break;
  349. }
  350. }
  351. if (!dupl) {
  352. JScrollPane sp = new JScrollPane(actualOpenCanvas);
  353. sp.setBorder(null);
  354. // Selected tabbed Pane = tabbedPaneOriginal or tabbedPaneSplit
  355. if (tabTemp == tabbedPaneOriginal) {
  356. this.tabbedPaneInnerOriginal.add(node.getName(), sp);
  357. this.tabbedPaneInnerOriginal.setSelectedComponent(sp);
  358. this.tabbedPaneInnerOriginal.setTabComponentAt(this.tabbedPaneInnerOriginal.getTabCount() - 1,
  359. new ButtonTabComponent(this.tabbedPaneInnerOriginal));
  360. }
  361. }
  362. }
  363. /**
  364. * Removes UpperNodeTab if UpperNode was deleted
  365. *
  366. * @param cps the CPS object that is currently selected
  367. */
  368. private void removeUpperNodeTab(AbstractCanvasObject cps) {
  369. if (cps instanceof GroupNode) {
  370. for (int i = 1; i < tabbedPaneInnerOriginal.getTabCount(); i++) {
  371. JScrollPane scrollPaneOriginal = (JScrollPane) tabbedPaneInnerOriginal.getComponentAt(i);
  372. if (scrollPaneOriginal == null) {
  373. } else if (((Canvas) scrollPaneOriginal.getViewport().getComponent(0)).getGroupNode()
  374. .getId() == cps.getId()) {
  375. ((ButtonTabComponent) tabbedPaneInnerOriginal.getTabComponentAt(i)).removeTabs();
  376. break;
  377. }
  378. }
  379. }
  380. }
  381. /**
  382. * chooses whether to set the tabTemp to tabbedPaneOriginal or tabbedPaneSplit
  383. */
  384. private void chooseTabTemp() {
  385. // TODO(Tom2021-12-1) Remove tabTabbed
  386. tabTemp = tabbedPaneOriginal;
  387. }
  388. private JScrollPane getScrollPaneFromTabbedPane() {
  389. return getScrollPaneFromTabbedPane(-1);
  390. }
  391. private JScrollPane getScrollPaneFromTabbedPane(int index) {
  392. Component upperLevelSelectedComponent;
  393. if (tabTemp == null) {
  394. return null;
  395. }
  396. if (index == -1) {
  397. upperLevelSelectedComponent = tabTemp.getSelectedComponent();
  398. } else {
  399. upperLevelSelectedComponent = tabTemp.getComponentAt(index);
  400. }
  401. if (upperLevelSelectedComponent instanceof JTabbedPane) {
  402. Component nextLevel = ((JTabbedPane) upperLevelSelectedComponent).getSelectedComponent();
  403. if (nextLevel instanceof JPanel panel)
  404. return (JScrollPane) panel.getComponent(0);
  405. else
  406. return (JScrollPane) nextLevel;
  407. } else if (upperLevelSelectedComponent instanceof JScrollPane scrollPane) {
  408. return scrollPane;
  409. } else {
  410. return null;
  411. }
  412. }
  413. private void openWebpage(String URL) {
  414. try {
  415. java.awt.Desktop.getDesktop().browse(new URI(URL));
  416. } catch (Exception e) {
  417. e.printStackTrace();
  418. }
  419. }
  420. /**
  421. * closes all UpperNodeTabs, that don't have a valid UpperNode (e.g. if it was
  422. * ungrouped/deleted/replaced and so on)
  423. */
  424. private void closeInvalidUpperNodeTabs() {
  425. /**
  426. * close bugged Tabs
  427. */
  428. for (int i = 1; i < tabbedPaneInnerOriginal.getTabCount(); i++) {
  429. JScrollPane scrollPaneOriginal = (JScrollPane) tabbedPaneInnerOriginal.getComponentAt(i);
  430. if (((Canvas) scrollPaneOriginal.getViewport().getComponent(0)).getGroupNode() == null) {
  431. ((ButtonTabComponent) tabbedPaneInnerOriginal.getTabComponentAt(i)).removeTabs();
  432. break;
  433. }
  434. }
  435. }
  436. public Canvas getCanvas() {
  437. return canvas;
  438. }
  439. public JFrame getFrame() {
  440. return this;
  441. }
  442. private class GuiMenuBar extends JMenuBar {
  443. //Menus
  444. private final JMenu fileMenu = new JMenu("File");
  445. private final JMenu editMenu = new JMenu("Edit");
  446. private final JMenu viewMenu = new JMenu("View");
  447. private final JMenu windowMenu = new JMenu("Window");
  448. private final JMenu helpMenu = new JMenu("Help");
  449. // FileMenu
  450. private final JMenuItem newMenuButton = new JMenuItem("New");
  451. private final JMenuItem openMenuButton = new JMenuItem("Open..");
  452. private final JMenuItem saveMenuButton = new JMenuItem("Save");
  453. private final JMenuItem saveAsMenuButton = new JMenuItem("Save..");
  454. // EditMenu
  455. private final JMenuItem undoButton = new JMenuItem("Undo");
  456. private final JMenuItem redoButton = new JMenuItem("Redo");
  457. private final JMenuItem edgePropertiesButton = new JMenuItem("Edge Properties");
  458. private final JMenuItem alignAllButton = new JMenuItem("Align All");
  459. private final JMenu resetMenu = new JMenu("Reset");
  460. private final JMenuItem resetCategoryButton = new JMenuItem("Categories");
  461. //HelpMenu
  462. private final JMenuItem introductionButton = new JMenuItem("Introduction");
  463. private final JMenuItem userManualButton = new JMenuItem("User Manual");
  464. private final JMenuItem algorithmHelpButton = new JMenuItem("Algorithm Introduction");
  465. private final JMenuItem codeDocumentationButton = new JMenuItem("Code Documentation");
  466. private final JMenuItem aboutUsButton = new JMenuItem("About Us");
  467. //ViewMenu
  468. private final JMenu appearanceMenu = new JMenu("Appearance");
  469. private final JMenuItem canvasSizeButton = new JMenuItem("Set View Size");
  470. private final JCheckBoxMenuItem showSupplyBarsCheckBox = new JCheckBoxMenuItem("Show supply bars.", true);
  471. private final JFileChooser fileChooser = initFileChooser();
  472. //WindowMenu
  473. JMenuItem algorithmButton = new JMenuItem("Algorithm Panel", new ImageIcon(Import
  474. .loadImage(ImagePreference.Button.Menu.Algo).getScaledInstance(20, 20, java.awt.Image.SCALE_SMOOTH)));
  475. JMenuItem outlinerButton = new JMenuItem("Outliner", new ImageIcon(Import
  476. .loadImage(ImagePreference.Button.Menu.Outliner).getScaledInstance(20, 20, java.awt.Image.SCALE_SMOOTH)));
  477. JMenuItem flexMenuButton = new JMenuItem("Flexibility Panel", new ImageIcon(Import
  478. .loadImage(ImagePreference.Button.Menu.Algo).getScaledInstance(20, 20, java.awt.Image.SCALE_SMOOTH)));
  479. GuiMenuBar() {
  480. initMenuLayout();
  481. initButtonActions();
  482. initButtonShortCuts();
  483. }
  484. private static JFileChooser initFileChooser() {
  485. JFileChooser safeLoadFileChooser = new JFileChooser(prefs.get(PreferenceKeys.Gui.DefaultFolder,
  486. FileSystemView.getFileSystemView().getDefaultDirectory().getPath()));
  487. safeLoadFileChooser.setFileFilter(new FileNameExtensionFilter("Holeg json files", "json"));
  488. safeLoadFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
  489. safeLoadFileChooser.setAcceptAllFileFilterUsed(false);
  490. return safeLoadFileChooser;
  491. }
  492. private void initMenuLayout() {
  493. add(fileMenu);
  494. add(editMenu);
  495. add(viewMenu);
  496. add(windowMenu);
  497. add(helpMenu);
  498. fileMenu.add(newMenuButton);
  499. fileMenu.add(openMenuButton);
  500. fileMenu.addSeparator();
  501. fileMenu.add(saveMenuButton);
  502. fileMenu.add(saveAsMenuButton);
  503. editMenu.add(undoButton);
  504. editMenu.add(redoButton);
  505. editMenu.add(edgePropertiesButton);
  506. editMenu.add(alignAllButton);
  507. editMenu.add(resetMenu);
  508. resetMenu.add(resetCategoryButton);
  509. helpMenu.add(introductionButton);
  510. helpMenu.add(userManualButton);
  511. helpMenu.add(algorithmHelpButton);
  512. helpMenu.add(codeDocumentationButton);
  513. helpMenu.add(aboutUsButton);
  514. viewMenu.add(appearanceMenu);
  515. appearanceMenu.add(showSupplyBarsCheckBox);
  516. viewMenu.add(canvasSizeButton);
  517. windowMenu.add(algorithmButton);
  518. windowMenu.add(outlinerButton);
  519. windowMenu.add(flexMenuButton);
  520. }
  521. private void initButtonActions() {
  522. newMenuButton.addActionListener(clicked -> newFile());
  523. openMenuButton.addActionListener(clicked -> openFile());
  524. saveMenuButton.addActionListener(clicked -> saveFile());
  525. saveAsMenuButton.addActionListener(clicked -> saveNewFile());
  526. edgePropertiesButton.addActionListener(actionEvent -> new EditEdgesPopUp(Gui.this, control));
  527. //TODO(Tom2022-01-14): recreateTryToAlignObjects
  528. alignAllButton.addActionListener(clicked -> {
  529. log.info("Not implemented yet.");
  530. });
  531. resetCategoryButton.addActionListener(clicked -> control.resetCategories());
  532. showSupplyBarsCheckBox.addActionListener(clicked -> toggleSupplyBarAppearance());
  533. canvasSizeButton.addActionListener(clicked -> new CanvasResizePopUp(control, canvas, tabbedPaneInnerOriginal,
  534. Gui.this));
  535. algorithmButton.addActionListener(clicked -> new AddOnWindow(Gui.this, control));
  536. outlinerButton.addActionListener(clicked -> new Outliner(Gui.this, control));
  537. flexMenuButton.addActionListener(clicked -> new FlexWindow(Gui.this, control));
  538. String tkWikiWebpage = "https://git.tk.informatik.tu-darmstadt.de/carlos.garcia/praktikum-holons/wiki/";
  539. introductionButton.addActionListener(clicked -> openWebpage(tkWikiWebpage + "Introduction+V2.1"));
  540. userManualButton.addActionListener(clicked -> openWebpage(tkWikiWebpage + "User+Manual+V2.1"));
  541. algorithmHelpButton.addActionListener(clicked -> openWebpage(tkWikiWebpage + "Algorithms+V2.1"));
  542. codeDocumentationButton.addActionListener(clicked -> openWebpage(tkWikiWebpage + "Code+documentation+V2.1"));
  543. aboutUsButton.addActionListener(clicked -> new AboutUsPopUp(Gui.this));
  544. }
  545. private void initButtonShortCuts() {
  546. int defaultModifier = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx();
  547. saveMenuButton.setAccelerator(KeyStroke.getKeyStroke('S', defaultModifier));
  548. saveAsMenuButton.setAccelerator(KeyStroke.getKeyStroke('S', defaultModifier + InputEvent.SHIFT_DOWN_MASK));
  549. openMenuButton.setAccelerator(KeyStroke.getKeyStroke('O', defaultModifier));
  550. newMenuButton.setAccelerator(KeyStroke.getKeyStroke('N', defaultModifier));
  551. }
  552. private void toggleSupplyBarAppearance() {
  553. GuiSettings.showSupplyBars = showSupplyBarsCheckBox.isSelected();
  554. log.info("canvas.repaint4");
  555. canvas.repaint();
  556. }
  557. private void saveFile(){
  558. GuiSettings.getActualSaveFile().ifPresentOrElse(control::saveFile, this::saveNewFile);
  559. }
  560. private void saveNewFile() {
  561. if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
  562. String path = fileChooser.getSelectedFile().getPath();
  563. if (!path.endsWith(".json")) {
  564. path += ".json";
  565. }
  566. prefs.put(PreferenceKeys.Gui.DefaultFolder, fileChooser.getCurrentDirectory().getPath());
  567. control.saveFile(new File(path));
  568. }
  569. }
  570. private void openFile() {
  571. if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
  572. prefs.put(PreferenceKeys.Gui.DefaultFolder, fileChooser.getCurrentDirectory().getPath());
  573. control.loadFile(fileChooser.getSelectedFile());
  574. //TODO(Tom2022-01-27): make better
  575. canvas.setGroupNode(control.getModel().getCanvas());
  576. canvas.repaint();
  577. }
  578. }
  579. private void newFile() {
  580. if (control.getModel().getCanvas().getObjectsInThisLayer().findAny().isPresent()) {
  581. int selectedOption = JOptionPane.showConfirmDialog(this, "Do you want to save your current model?",
  582. "Warning", JOptionPane.YES_NO_OPTION);
  583. if (selectedOption == JOptionPane.YES_OPTION) {
  584. saveNewFile();
  585. }
  586. }
  587. control.clearModel();
  588. }
  589. }
  590. }