package ui.view.main; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Cursor; import java.awt.Dimension; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.HeadlessException; import java.awt.Image; import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.ItemEvent; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.io.File; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; import javax.swing.AbstractAction; import javax.swing.ActionMap; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.GrayFilter; import javax.swing.ImageIcon; import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JCheckBoxMenuItem; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTabbedPane; import javax.swing.JTextField; import javax.swing.JToolBar; import javax.swing.JTree; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeCellRenderer; import org.apache.commons.compress.archivers.ArchiveException; import com.google.gson.JsonParseException; import classes.AbstractCanvasObject; import classes.Category; import classes.Edge; import classes.GroupNode; import classes.HolonObject; import classes.HolonSwitch; import classes.IdCounter; import classes.IdCounter.CounterType; import interfaces.GraphEditable; import ui.controller.Control; import ui.model.DecoratedState; import ui.model.Model; import ui.model.Model.FairnessModel; import ui.view.canvas.AbstractCanvas; import ui.view.canvas.Canvas; import ui.view.canvas.GroupNodeCanvas; import ui.view.component.ButtonTabComponent; import ui.view.dialog.AboutUsPopUp; import ui.view.dialog.AddObjectPopUp; import ui.view.dialog.BackgroundPopUp; import ui.view.dialog.CanvasResizePopUp; import ui.view.dialog.CreateNewDialog; import ui.view.dialog.CreateNewDialog.Option; import ui.view.inspector.Inspector; import ui.view.inspector.UnitGraph; import ui.view.dialog.EditEdgesPopUp; import ui.view.dialog.SearchPopUp; import ui.view.window.AddOnWindow; import ui.view.window.FlexWindow; import ui.view.window.Outliner; import utility.ImageImport; /** * Graphical User Interface. * * @author Gruppe14 */ public class GUI { static final Color PALE_RED = new Color(255, 192, 192); /** * Menu on the Top containing File, Edit View Help etc */ private final JMenuBar menuBar = new JMenuBar(); private final JMenu mnNewMenu = new JMenu("File"); private final JMenu mnNewMenuEdit = new JMenu("Edit"); private final JMenu mnNewMenuOptions = new JMenu("Options"); private final JMenu mnNewMenuView = new JMenu("View"); private final JMenu menuWindow = new JMenu("Window"); /** Help Menu containing helpful Informations and the AboutUs Popup */ private final JMenu mnHelp = new JMenu("Help"); /** * Help -> Introduction A small Introduction of the Application, SmartGrids and * Holons */ private final JMenuItem mntmIntroduction = new JMenuItem("Introduction"); /** * Help -> UserManual */ private final JMenuItem mntmUserManual = new JMenuItem("User Manual"); /** Help -> Algorithm Help Menu */ private final JMenuItem mntmAlgorithmHelp = new JMenuItem("Algorithm Introduction"); /** Help -> CodeDocumentation */ private final JMenuItem mntmCodeDoc = new JMenuItem("Code Documentation"); /** Help -> AboutUs */ private final JMenuItem mntmAboutUs = new JMenuItem("About Us"); /** checked if supplyBars should be shown */ private final JCheckBoxMenuItem showSupplyBarsCheckBox = new JCheckBoxMenuItem("Show supply bars."); /** menu for the different fairness Models */ private final JMenu mnFairnessModel = new JMenu("Fairness Model"); /** press to supply minimum demand first */ private final JMenuItem mntmFairMinFirst = new JMenuItem("Minimum demand first"); /** press to give everyone the same energy */ private final JMenuItem mntmFairAlleEqual = new JMenuItem("Equal supply for everyone"); private final JMenuItem mntmOpen = new JMenuItem("Open"); private final JMenuItem mntmNew = new JMenuItem("New"); private final JMenuItem mntmSave = new JMenuItem("Save"); private final JMenuItem mntmCanvasSize = new JMenuItem("Set View Size"); private final JMenuItem mntmBackground = new JMenuItem("Set Background Image"); private final JSplitPane splitPane = new JSplitPane(); private final JSplitPane splitPane1 = new JSplitPane(); // the tabbed canvas containing the different sub-net tabs of the grid (Main // Grid + Nodes of Nodes) private final JPanel myPanel = new JPanel(new BorderLayout()); private final JTabbedPane tabbedPaneInnerOriginal = new JTabbedPane(JTabbedPane.TOP); // the main canvas where we can see the grid currently displayed private final JScrollPane canvasSP = new JScrollPane(); private final JScrollPane scrollPane1 = new JScrollPane(); // private final JScrollPane holonSP = new JScrollPane(); // the original tabbed Pane (containing tabs for view, statistics, holon, // flexibility) private final JTabbedPane tabbedPaneOriginal = new JTabbedPane(JTabbedPane.TOP); private final JPopupMenu popmenuEdit = new JPopupMenu(); private final JMenuItem editItem = new JMenuItem("Edit Object"); private final JLabel elementGraph = new JLabel("None "); private final JTree categoryTree = new JTree(); /****************************************** ************* Right Container************* ****************************************** * Right Container: here comes the information about the HolonObject, such as * HolonElements Information, Properties and Consumption/Production graph. **/ private final Inspector inspector; private final JSplitPane splitHolonElPro = new JSplitPane(JSplitPane.VERTICAL_SPLIT); private final JSplitPane splitGraphHolonEl = new JSplitPane(JSplitPane.VERTICAL_SPLIT); private final int distanceBetweenElementsAndGraph = 350; // Prechoosed local Periods private final JScrollPane scrollProperties = new JScrollPane(); // In this section is the graph for the selected HolonElement of the clicked private final Model model; private final Control controller; // In this section are all the Holonelements that correspond to the clicked // HolonObject with consumption/production, name and amount. private final JPanel panel = new JPanel(); private final JPanel panelHolonEl = new JPanel(); // Buttons private final JButton btnAdd = new JButton(); private final JPopupMenu btnAddPopUp = new JPopupMenu("Newacac"); private final JMenuItem mItemNew = new JMenuItem("New.."); private final JMenuItem mItemCategory = new JMenuItem("Category"); private final JMenuItem mItemObject = new JMenuItem("Object"); private final JMenuItem mItemSwitch = new JMenuItem("Switch"); private final JButton btnDel = new JButton(); private final JToolBar toolBar = new JToolBar(); private final JToolBar toolBarHolonEl = new JToolBar(); // Languages private final Canvas canvas; private final UnitGraph unitGraph; /** Textfield to show the period of an element */ private final JTextField unitGraphLocalPeriod = new JTextField(6); private final JMenuItem mntmUndo = new JMenuItem("Undo"); private final JMenuItem mntmRedo = new JMenuItem("Redo"); private final JMenuItem mntmEditEdges = new JMenuItem("Edge Properties"); private final JMenuItem mntmFindReplace = new JMenuItem("Find/ Replace"); private final JMenuItem mntmAlignAll = new JMenuItem("Align All"); private final JMenuItem mntmResetCategory = new JMenuItem("Reset Categories"); // TODO make GUI a JFRAME and remove holegJFrame private JFrame holegJFrame; // tabbedPaneOriginal or tabbedPaneSplit private JTabbedPane tabTemp; private String catOfObjToBeEdited; private GroupNodeCanvas unc; private JPanel contentPane; // Pop up Windows private AddObjectPopUp addObjectPopUP; private AboutUsPopUp aboutUsPopUp; // variables private boolean dragging = false; private String actualObjectClicked; private Image img = null; private AbstractCanvasObject tempCps = null; // Time Stuff private TimePanel timePanel; public TimePanel getTimePanel() { return timePanel; } private AbstractCanvasObject temp = null; private String warningText = "Warning"; private String saveBeforeNew = "Do you want to save your current data?"; private String eraseCategory = "Do you really want to delete the Category "; private String selectObjBeforeErase = "Please select a Category or an Object in the left library in order to delete something."; private List outlinerList = new ArrayList(); private List flexList = new ArrayList(); private JMenuItem removeItem = new JMenuItem("Remove"); /** * Create the application. * * @param control the Controller */ GUI(Control control) { this.controller = control; this.model = control.getModel(); inspector = new Inspector(control); control.setGui(this); control.calculateStateAndVisualForCurrentTimeStep(); this.unitGraph = new UnitGraph(control); this.canvas = new Canvas(model, control, unitGraph); initialize(); updateCategories(model.getCategories()); control.OnCategoryChanged.addListener(() -> this.updateCategoryUI(model.getCategories())); } /** * Initialize the contents of the frame. */ private void initialize() { holegJFrame = new JFrame(); holegJFrame.setTitle("HOLEG Simulator"); // try to restore old position/dimensions ArrayList savedWindowDim = controller.loadSavedWindowDimensionsIfExistent(); if (savedWindowDim.size() == 4) { holegJFrame.setBounds(savedWindowDim.get(0), savedWindowDim.get(1), savedWindowDim.get(2), savedWindowDim.get(3)); } // if the upper part of the window is showing, the windows can still be // moved, // but if it is not, we need to move it to somewhere else if (savedWindowDim.size() != 4 || !isUpperPanelInsideBounds()) { holegJFrame.setBounds(100, 100, 1000, 800); holegJFrame.setExtendedState(JFrame.MAXIMIZED_BOTH); } holegJFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); holegJFrame.addWindowListener(new java.awt.event.WindowAdapter() { @Override public void windowClosing(java.awt.event.WindowEvent windowEvent) { if (JOptionPane.showConfirmDialog(holegJFrame, "Are you sure you want to exit?", "HOLEG", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { controller .deleteDirectory(new File(System.getProperty("user.home") + "/.config/HolonGUI/Autosave")); // try to save the position and size of the window, such // that (if possible) // it can be opened in the same position the next time try { controller.savePosAndSizeOfWindow(holegJFrame.getX(), holegJFrame.getY(), holegJFrame.getWidth(), holegJFrame.getHeight()); } catch (Exception e) { e.printStackTrace(); } System.exit(1); } System.exit(0); } }); contentPane = (JPanel) holegJFrame.getContentPane(); int condition = JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT; InputMap inputMap = contentPane.getInputMap(condition); ActionMap actionMap = contentPane.getActionMap(); String cntrlZDown = "controlZ"; inputMap.put(KeyStroke.getKeyStroke("control Z"), cntrlZDown); actionMap.put(cntrlZDown, new AbstractAction() { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { try { controller.loadAutoSave(controller.getUndoSave()); closeInvalidUpperNodeTabs(); controller.calculateStateAndVisualForCurrentTimeStep(); canvas.repaint(); updateUpperNodes(); } catch (IOException eex) { eex.printStackTrace(); } } }); String cntrlYDown = "controlY"; inputMap.put(KeyStroke.getKeyStroke("control Y"), cntrlYDown); actionMap.put(cntrlYDown, new AbstractAction() { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { try { controller.loadAutoSave(controller.getRedoSave()); closeInvalidUpperNodeTabs(); controller.calculateStateAndVisualForCurrentTimeStep(); canvas.repaint(); updateUpperNodes(); } catch (IOException ex) { ex.printStackTrace(); } } }); String cntrlADown = "controlA"; inputMap.put(KeyStroke.getKeyStroke("control A"), cntrlADown); AbstractAction controlA = new AbstractAction() { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { chooseTabTemp(); model.getSelectedObjects().clear(); // Uppernode Canvas? JScrollPane scrollPane = getScrollPaneFromTabbedPane(); Component canvasOrUpperNodeCanvas = scrollPane.getViewport().getComponent(0); if (canvasOrUpperNodeCanvas instanceof GroupNodeCanvas) { GroupNodeCanvas uNC = (GroupNodeCanvas) canvasOrUpperNodeCanvas; controller.addSelectedObjects(uNC.getGroupNode().getNodes()); uNC.repaint(); // or Canvas? } else if (canvasOrUpperNodeCanvas instanceof Canvas) { controller.addSelectedObjects(model.getObjectsOnCanvas()); canvas.repaint(); } controller.getObjectsInDepth(); } }; actionMap.put(cntrlADown, controlA); String delDown = "delete"; inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0, false), delDown); actionMap.put(delDown, new AbstractAction() { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { chooseTabTemp(); // Uppernode Canvas? JScrollPane scrollPane = getScrollPaneFromTabbedPane(); Component canvasOrUpperNodeCanvas = scrollPane.getViewport().getComponent(0); // check whether a producer was deleted (this triggers a // complete re-evaluation of the net) boolean wasProducerDeleted = true; if (canvasOrUpperNodeCanvas instanceof GroupNodeCanvas) { GroupNodeCanvas uNC = (GroupNodeCanvas) canvasOrUpperNodeCanvas; for (AbstractCanvasObject cps : model.getSelectedObjects()) { if (uNC.getGroupNode().getNodes().contains(cps)) { controller.delObjUpperNode(cps, uNC.getGroupNode()); unc.setToolTip(false); // remove UpperNodeTab if UpperNode deleted removeUpperNodeTab(cps); } } uNC.repaint(); controller.clearSelection(); // or Canvas? } else if (canvasOrUpperNodeCanvas instanceof Canvas) { // Edge Deleting Edge edgeHighlight = model.getSelectedEdge(); if (edgeHighlight != null) { controller.removeEdgesOnCanvas(edgeHighlight); ((Canvas) canvasOrUpperNodeCanvas).edgeHighlight = null; } canvas.setToolTip(false); for (AbstractCanvasObject cps : model.getSelectedObjects()) { controller.delCanvasObject(cps, false); // remove UpperNodeTab if UpperNode deleted removeUpperNodeTab(cps); } controller.clearSelection(); controller.tryAutoSave(); canvas.repaint(); } // recalculate net if a producer was deleted if (wasProducerDeleted) { controller.resetSimulation(); controller.calculateStateAndVisualForCurrentTimeStep(); } model.getSelectedObjects().clear(); } }); String cntrlFDown = "controlF"; inputMap.put(KeyStroke.getKeyStroke("control F"), cntrlFDown); actionMap.put(cntrlFDown, new AbstractAction() { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { SearchPopUp dialog = new SearchPopUp(controller, canvas, holegJFrame); dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); dialog.setVisible(true); } }); String cntrlCDown = "controlC"; inputMap.put(KeyStroke.getKeyStroke("control C"), cntrlCDown); AbstractAction controlC = new AbstractAction() { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { chooseTabTemp(); System.out.println("heiCopy - control C"); JScrollPane scrollPane = getScrollPaneFromTabbedPane(); if (!model.getSelectedObjects().isEmpty()) { if (scrollPane.getViewport().getComponent(0) instanceof GroupNodeCanvas) controller.copy(((GroupNodeCanvas) scrollPane.getViewport().getComponent(0)).getGroupNode()); else controller.copy(null); if (!model.getClipboradObjects().isEmpty()) { canvas.itemPaste.setEnabled(true); } } } }; actionMap.put(cntrlCDown, controlC); String cntrlVDown = "controlV"; inputMap.put(KeyStroke.getKeyStroke("control V"), cntrlVDown); AbstractAction controlV = new AbstractAction() { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { try { tabTemp = null; if (tabbedPaneOriginal.getMousePosition() != null) { tabTemp = tabbedPaneOriginal; } else { } if (tabTemp == null) return; JScrollPane scrollPane = getScrollPaneFromTabbedPane(); Component canvasOrUpperNodeCanvas = scrollPane.getViewport().getComponent(0); if (tabTemp != null && canvasOrUpperNodeCanvas instanceof GroupNodeCanvas) { controller.paste(((GroupNodeCanvas) canvasOrUpperNodeCanvas).getGroupNode(), canvasOrUpperNodeCanvas.getMousePosition()); controller.calculateStateAndVisualForCurrentTimeStep(); scrollPane.getViewport().getComponent(0).repaint(); } else { controller.paste(null, canvas.getMousePosition()); controller.calculateStateAndVisualForCurrentTimeStep(); canvas.repaint(); } } catch (HeadlessException | JsonParseException | UnsupportedFlavorException | IOException e1) { JLabel message = new JLabel("The Clipboard information cannot be pasted into Application."); JOptionPane.showMessageDialog(holegJFrame, message, "", JOptionPane.ERROR_MESSAGE); } } }; actionMap.put(cntrlVDown, controlV); String cntrlXDown = "controlX"; inputMap.put(KeyStroke.getKeyStroke("control X"), cntrlXDown); AbstractAction controlX = new AbstractAction() { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { chooseTabTemp(); JScrollPane scrollPane = getScrollPaneFromTabbedPane(); if (!model.getSelectedObjects().isEmpty()) { if (scrollPane.getViewport().getComponent(0) instanceof GroupNodeCanvas) { controller.cut(((GroupNodeCanvas) scrollPane.getViewport().getComponent(0)).getGroupNode()); controller.calculateStateAndVisualForCurrentTimeStep(); scrollPane.getViewport().getComponent(0).repaint(); } else { controller.cut(null); controller.calculateStateAndVisualForCurrentTimeStep(); canvas.repaint(); } if (!model.getClipboradObjects().isEmpty()) { canvas.itemPaste.setEnabled(true); } } } }; actionMap.put(cntrlXDown, controlX); holegJFrame.setJMenuBar(menuBar); holegJFrame.setIconImage(ImageImport.loadImage("/Images/Holeg.png", 30, 30)); menuBar.add(mnNewMenu); mnNewMenu.add(mntmNew); mnNewMenu.add(mntmOpen); mnNewMenu.add(mntmSave); menuBar.add(mnNewMenuEdit); mnNewMenuEdit.add(mntmUndo); mnNewMenuEdit.add(mntmRedo); mntmFindReplace.addActionListener(actionEvent -> { try { SearchPopUp dialog = new SearchPopUp(controller, canvas, holegJFrame); dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); dialog.setVisible(true); controller.getObjectsInDepth(); } catch (Exception ex) { ex.printStackTrace(); } }); mnNewMenuEdit.add(mntmFindReplace); mnNewMenuEdit.add(mntmEditEdges); mntmEditEdges.addActionListener(actionEvent -> { EditEdgesPopUp edgePopUp = new EditEdgesPopUp(holegJFrame); edgePopUp.setCanvas(canvas); edgePopUp.setController(controller); edgePopUp.setVisible(true); }); // Edit -> Align All mnNewMenuEdit.add(mntmAlignAll); mntmAlignAll.addActionListener(actionEvent -> { // getScrollPaneFromTabbedPane().getViewport().getComponent(0) is always the // active canvas AbstractCanvas activeCanvas = ((AbstractCanvas) getScrollPaneFromTabbedPane().getViewport() .getComponent(0)); if (activeCanvas != null) { activeCanvas.tryToAlignObjects(); activeCanvas.repaint(); } }); menuBar.add(mnNewMenuOptions); mnNewMenuOptions.add(mntmResetCategory); mntmResetCategory.addActionListener(actionEvent -> { ArrayList cat = model.getCategories(); try { while (!cat.isEmpty()) { controller.deleteCategory(cat.get(0).getName()); } controller.resetCategorys(); } catch (Exception e2) { System.out.println(e2.getMessage()); } categoryTree.revalidate(); categoryTree.repaint(); }); /** * Add Fairness Model Option to the option Menu */ mnNewMenuOptions.add(mnFairnessModel); mnFairnessModel.add(mntmFairMinFirst); mntmFairMinFirst.setForeground(Color.BLUE); mntmFairMinFirst .setToolTipText("HolonObjects with the smallest mininum Demand will be partially supplied first.\n" + "After that as many HolonObjects as possible will get fully supplied."); mntmFairMinFirst.addActionListener(arg0 -> { controller.setFairnessModel(FairnessModel.MininumDemandFirst); mntmFairMinFirst.setForeground(Color.BLUE); mntmFairAlleEqual.setForeground(mnFairnessModel.getForeground()); controller.calculateStateAndVisualForCurrentTimeStep(); // Update UpperNodes Component canvasOrUpperNodeCanvas = getScrollPaneFromTabbedPane().getViewport().getComponent(0); if (canvasOrUpperNodeCanvas != null && canvasOrUpperNodeCanvas instanceof GroupNodeCanvas) { ((GroupNodeCanvas) canvasOrUpperNodeCanvas).repaint(); } }); mnFairnessModel.add(mntmFairAlleEqual); mntmFairAlleEqual.setToolTipText("HolonObjects will all get the same amount of energy."); mntmFairAlleEqual.addActionListener(arg0 -> { controller.setFairnessModel(FairnessModel.AllEqual); mntmFairAlleEqual.setForeground(Color.BLUE); mntmFairMinFirst.setForeground(mnFairnessModel.getForeground()); controller.calculateStateAndVisualForCurrentTimeStep(); // Update UpperNodes Component canvasOrUpperNodeCanvas = getScrollPaneFromTabbedPane().getViewport().getComponent(0); if (canvasOrUpperNodeCanvas != null && canvasOrUpperNodeCanvas instanceof GroupNodeCanvas) { ((GroupNodeCanvas) canvasOrUpperNodeCanvas).repaint(); } }); menuBar.add(mnNewMenuView); mnNewMenuView.add(mntmCanvasSize); mntmCanvasSize.addActionListener(actionEvent -> { CanvasResizePopUp popUp = new CanvasResizePopUp(model, controller, canvas, this.tabbedPaneInnerOriginal, holegJFrame); popUp.setVisible(true); }); tabbedPaneInnerOriginal.addChangeListener(change -> { controller.clearSelection(); }); mnNewMenuView.add(mntmCanvasSize); /* * Adds Checkbox to turn supply bars on/off */ mnNewMenuView.add(showSupplyBarsCheckBox); showSupplyBarsCheckBox.setSelected(true); showSupplyBarsCheckBox.addActionListener(arg0 -> { controller.setShowSupplyBars(showSupplyBarsCheckBox.isSelected()); canvas.repaint(); // Update UpperNodes JScrollPane spane = getScrollPaneFromTabbedPane(); if (spane != null) { Component canvasOrUpperNodeCanvas = spane.getViewport().getComponent(0); if (canvasOrUpperNodeCanvas != null && canvasOrUpperNodeCanvas instanceof GroupNodeCanvas) { ((GroupNodeCanvas) canvasOrUpperNodeCanvas).repaint(); } } }); initWindowMenu(); mnNewMenuView.add(mntmBackground); mntmBackground.addActionListener(actionEvent -> { tabTemp = tabbedPaneOriginal; JScrollPane scrollPane = getScrollPaneFromTabbedPane(); if (scrollPane.getViewport().getComponent(0) instanceof Canvas) { BackgroundPopUp backgroundDialog = new BackgroundPopUp(model, controller, canvas, null, holegJFrame); backgroundDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); backgroundDialog.setVisible(true); } else if (scrollPane.getViewport().getComponent(0) instanceof GroupNodeCanvas) { GroupNodeCanvas uNodeCanvas = (GroupNodeCanvas) (scrollPane.getViewport().getComponent(0)); BackgroundPopUp backgroundDialog = new BackgroundPopUp(model, controller, null, uNodeCanvas.getGroupNode(), holegJFrame); backgroundDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); backgroundDialog.setVisible(true); uNodeCanvas.repaint(); } }); /** * add Help Menu and its items */ menuBar.add(mnHelp); mnHelp.add(mntmIntroduction); mnHelp.add(mntmUserManual); mnHelp.add(mntmAlgorithmHelp); mnHelp.add(mntmCodeDoc); mnHelp.add(mntmAboutUs); canvas.setBackground(Color.WHITE); canvas.setPreferredSize(new Dimension(model.getCanvasX(), model.getCanvasY())); /******************** * RIGHT CONTAINER (INFORMATION) **********************/ panelHolonEl.setLayout(new BoxLayout(panelHolonEl, BoxLayout.X_AXIS)); toolBarHolonEl.setFloatable(false); panelHolonEl.add(toolBarHolonEl); /*********************** * HolonElement Graph Actions **********************/ /* * Update Local Period of an Element Graph */ unitGraphLocalPeriod.addKeyListener(new KeyAdapter() { @Override public void keyReleased(KeyEvent e) { try { int localLength = Integer.parseInt(unitGraphLocalPeriod.getText()); unitGraphLocalPeriod.setBackground(Color.WHITE); /** * set local graph Period */ if (e.getKeyCode() == KeyEvent.VK_ENTER) unitGraph.setLocalPeriod(localLength); } catch (NumberFormatException ex) { unitGraphLocalPeriod.setBackground(PALE_RED); } } }); /***************************** * RIGHT CONTAINER DONE *****************************/ holegJFrame.getContentPane().setLayout(new BorderLayout(0, 0)); /**************** * Tree Stuff ****************/ // Override Key Actions inputMap = categoryTree.getInputMap(); inputMap.put(KeyStroke.getKeyStroke("control C"), cntrlCDown); inputMap.put(KeyStroke.getKeyStroke("control V"), cntrlVDown); inputMap.put(KeyStroke.getKeyStroke("control X"), cntrlXDown); inputMap.put(KeyStroke.getKeyStroke("control A"), cntrlADown); TreeCellRenderer customRenderer = new TreeCellRenderer() { @Override public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { JLabel label = new JLabel(); Image imgR; if (leaf) { for (Category cat : model.getCategories()) { for (AbstractCanvasObject cps : cat.getObjects()) { if (value.toString().compareTo(cps.getName()) == 0) { imgR = ImageImport.loadImage(cps.getImage(), 50, 50); if (imgR != null) { label.setIcon(new ImageIcon(imgR)); } label.setText(cps.getName()); } } } } tree.setRowHeight(50); if (hasFocus) { label.setForeground(new Color(0, 0, 255)); label.setOpaque(true); } if (label.getText().length() == 0) { label.setText(value.toString()); if (value.toString().compareTo("Categories") != 0) { label.setIcon(new ImageIcon(ImageImport.loadImage("/Images/folder.png"))); } } return label; } }; categoryTree.setCellRenderer(customRenderer); categoryTree.addMouseMotionListener(new MouseMotionAdapter() { public void mouseDragged(MouseEvent e) { checkForDragAndDrop(e); } /** * checks if an object of the current Panel could be replaced by the dragged * object * * @param e */ private void checkForDragAndDrop(MouseEvent e) { try { /** * if no object gets dragged -> finished */ if (!dragging) return; /** * select the current Panel */ chooseTabTemp(); JScrollPane scrollPane = getScrollPaneFromTabbedPane(); if (scrollPane == null) return; Component canvasOrUpperNodeCanvas = scrollPane.getViewport().getComponent(0); /** * check for replacements on the canvas */ if (canvasOrUpperNodeCanvas instanceof GroupNodeCanvas) { GroupNodeCanvas unc = (GroupNodeCanvas) canvasOrUpperNodeCanvas; if (unc.getMousePosition() == null) return; int x = (int) unc.getMousePosition().getX() + 16; int y = (int) unc.getMousePosition().getY() + 16; /** * check for replacement */ unc.checkForReplacement(x, y); /** * repaint */ unc.invalidate(); unc.repaint(); } else { if (canvas.getMousePosition() == null) return; int x = (int) canvas.getMousePosition().getX() + 16; int y = (int) canvas.getMousePosition().getY() + 16; /** * check for replacement */ canvas.checkForReplacement(x, y); /** * repaint */ canvas.invalidate(); canvas.repaint(); } contentPane.updateUI(); } catch (Exception eex) { eex.printStackTrace(); } } }); categoryTree.addMouseListener(new MouseAdapter() { public void mouseReleased(MouseEvent e) { try { if (dragging) { chooseTabTemp(); JScrollPane scrollPane = getScrollPaneFromTabbedPane(); Component canvasOrUpperNodeCanvas = scrollPane.getViewport().getComponent(0); if (canvasOrUpperNodeCanvas instanceof GroupNodeCanvas) { GroupNodeCanvas unc = (GroupNodeCanvas) canvasOrUpperNodeCanvas; int x = (int) unc.getMousePosition().getX() + 16; int y = (int) unc.getMousePosition().getY() + 16; AbstractCanvasObject h = null; if (tempCps instanceof HolonObject) { h = new HolonObject((HolonObject) tempCps); } if (tempCps instanceof HolonSwitch) { h = new HolonSwitch(tempCps); } h.setPosition(x, y); /** * close UpperNodeTabs of replaced UpperNode */ if (unc.mayBeReplaced != null && unc.mayBeReplaced instanceof GroupNode) { unc.closeUpperNodeTab(unc.mayBeReplaced.getId()); } controller.addObjUpperNode(h, unc.getGroupNode()); /** * object would be replaced */ unc.mayBeReplaced = null; unc.invalidate(); controller.calculateStateAndVisualForCurrentTimeStep(); unc.repaint(); unc.setXY((int) canvas.getMousePosition().getX(), (int) canvas.getMousePosition().getY()); } else { int x = (int) canvas.getMousePosition().getX() + 16; int y = (int) canvas.getMousePosition().getY() + 16; AbstractCanvasObject h = null; if (tempCps instanceof HolonObject) { h = new HolonObject((HolonObject) tempCps); } if (tempCps instanceof HolonSwitch) { h = new HolonSwitch(tempCps); } h.setPosition(x, y); /** * close UpperNodeTabs of replaced UpperNode */ if (canvas.mayBeReplaced != null && canvas.mayBeReplaced instanceof GroupNode) { canvas.closeUpperNodeTab(canvas.mayBeReplaced.getId()); } controller.addObjectCanvas(h); /** * no object should get replaced */ canvas.mayBeReplaced = null; canvas.invalidate(); canvas.setXY((int) canvas.getMousePosition().getX(), (int) canvas.getMousePosition().getY()); canvas.repaint(); } controller.calculateStateAndVisualForCurrentTimeStep(); contentPane.updateUI(); dragging = false; } } catch (Exception eex) { } holegJFrame.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } }); popmenuEdit.add(editItem); popmenuEdit.add(removeItem); editItem.setEnabled(false); editItem.addActionListener(actionEvent -> { }); categoryTree.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { try { actualObjectClicked = categoryTree.getPathForLocation(e.getX(), e.getY()).getLastPathComponent() .toString(); // if an Object was selected, the porperties are shown in // the table DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) categoryTree .getPathForLocation(e.getX(), e.getY()).getLastPathComponent(); if (selectedNode.getLevel() == 2) { controller.searchCategoryObject(selectedNode.getParent().toString(), selectedNode.toString()); // if (selected instanceof HolonObject && selected != // null) { // selected = (HolonObject) selected; // fillElementTable(((HolonObject) // selected).getElements()); // } } if (SwingUtilities.isRightMouseButton(e)) { for (Category cat : model.getCategories()) { for (AbstractCanvasObject cps : cat.getObjects()) { if (actualObjectClicked.compareTo(cps.getName()) == 0 && !(cps instanceof HolonSwitch)) { editItem.setEnabled(true); popmenuEdit.show(e.getComponent(), e.getX(), e.getY()); catOfObjToBeEdited = selectedNode.getParent().toString(); tempCps = cps; } } } } else { for (Category cat : model.getCategories()) { for (AbstractCanvasObject cps : cat.getObjects()) { if (actualObjectClicked.compareTo(cps.getName()) == 0) { File checkPath = new File(cps.getImage()); if (checkPath.exists()) { img = new ImageIcon(cps.getImage()).getImage().getScaledInstance(32, 32, java.awt.Image.SCALE_SMOOTH); } else { img = ImageImport.loadImage(cps.getImage(), 32, 32); } tempCps = cps; dragging = true; Cursor cursor = Toolkit.getDefaultToolkit().createCustomCursor(img, new Point(0, 0), "Image"); holegJFrame.setCursor(cursor); } } } } } catch (Exception eex) { } } }); editItem.addActionListener(actionEvent -> { // Remove the selected Object object // AddObjectPopUp(boolean edit, AbstractCpsObject obj, String cat, JFrame // parentFrame) System.out.println("Edit"); addObjectPopUP = new AddObjectPopUp(true, tempCps, catOfObjToBeEdited, holegJFrame); addObjectPopUP.setCategory(catOfObjToBeEdited); addObjectPopUP.setController(controller); addObjectPopUP.setVisible(true); }); removeItem.addActionListener(actionEvent -> { // Remove the selected Object object try { System.out.println("catOfObjToBeEdited:" + catOfObjToBeEdited + ", tempCps:" + tempCps); controller.delObjectCategory(catOfObjToBeEdited, tempCps.getName()); } catch (IOException e) { System.err.println("IOException"); e.printStackTrace(); } }); scrollPane1.setViewportView(categoryTree); scrollPane1.setColumnHeaderView(panel); panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); toolBar.setAlignmentX(Component.LEFT_ALIGNMENT); toolBar.setFloatable(false); panel.add(toolBar); btnAddPopUp.add(mItemNew); mItemNew.addActionListener(actionEvent -> { new CreateNewDialog(controller, holegJFrame); }); btnAddPopUp.addSeparator(); btnAddPopUp.add(mItemCategory); mItemCategory.addActionListener(actionEvent -> { new CreateNewDialog(controller, Option.Category, holegJFrame); }); btnAddPopUp.add(mItemObject); mItemObject.addActionListener(actionEvent -> { new CreateNewDialog(controller, Option.Object, holegJFrame); }); btnAddPopUp.add(mItemSwitch); mItemSwitch.addActionListener(actionEvent -> { new CreateNewDialog(controller, Option.Switch, holegJFrame); }); btnAdd.addActionListener(actionEvent -> btnAddPopUp.show(btnAdd, -1, +20)); btnAdd.setIcon(new ImageIcon(ImageImport.loadImage("Images/plus.png", 16, 16))); btnAdd.setToolTipText("New
Add a new Category or Item to the library."); toolBar.add(btnAdd); /** * Help Menu Action Listeners */ /** * URL of the telecommunication git Wiki */ String tkWikiWebpage = "https://git.tk.informatik.tu-darmstadt.de/carlos.garcia/praktikum-holons/wiki/"; /** open Introduction Web Page */ mntmIntroduction.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { openWebpage(tkWikiWebpage + "Introduction+V2.1"); } }); /** open UserManual WebPage */ mntmUserManual.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { openWebpage(tkWikiWebpage + "User+Manual+V2.1"); } }); /** open Algorithm Help Web Page */ mntmAlgorithmHelp.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { openWebpage(tkWikiWebpage + "Algorithms+V2.1"); } }); /** open Code Documentation Web Page */ mntmCodeDoc.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { openWebpage(tkWikiWebpage + "Code+documentation+V2.1"); } }); /** * Pop up - About Us with some important information about the developers, * source and programming stuff */ mntmAboutUs.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { aboutUsPopUp = new AboutUsPopUp(holegJFrame); aboutUsPopUp.setVisible(true); } }); // Del Button btnDel.addActionListener(actionEvent -> { Object nodeInfo = categoryTree.getLastSelectedPathComponent(); if (nodeInfo != null) { DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) nodeInfo; String nodeName = selectedNode.getUserObject().toString(); int depthOfNode = selectedNode.getLevel(); try { switch (depthOfNode) { case 1: int dialogResult = JOptionPane.showConfirmDialog(holegJFrame, eraseCategory + nodeName + "?", warningText, JOptionPane.YES_NO_OPTION); if (dialogResult == JOptionPane.YES_OPTION) { controller.deleteCategory(nodeName); } break; case 2: DefaultMutableTreeNode parent = (DefaultMutableTreeNode) selectedNode.getParent(); controller.delObjectCategory(parent.getUserObject().toString(), nodeName); break; default: JOptionPane.showMessageDialog(holegJFrame, selectObjBeforeErase); } } catch (Exception e2) { } } else { JOptionPane.showMessageDialog(holegJFrame, selectObjBeforeErase); } categoryTree.repaint(); }); btnDel.setIcon(new ImageIcon(ImageImport.loadImage("Images/minus.png", 16, 16))); btnDel.setToolTipText("Delete
Removes a Category or a Category Item."); toolBar.add(btnDel); holegJFrame.getContentPane().add(splitPane); mntmNew.addActionListener(actionEvent -> { if (model.getObjectsOnCanvas().size() != 0) { int newWarning = JOptionPane.YES_NO_OPTION; int dialogForNewWarning = JOptionPane.showConfirmDialog(holegJFrame, saveBeforeNew, warningText, newWarning); if (dialogForNewWarning == JOptionPane.YES_OPTION) { mntmSave.doClick(); } } // Remove all but main tab while (tabbedPaneInnerOriginal.getTabCount() > 1) { tabbedPaneInnerOriginal.remove(1); } controller.clearSelection(); model.getEdgesOnCanvas().clear(); model.getObjectsOnCanvas().clear(); controller.OnSelectionChanged.broadcast(); controller.setSelectedObjectID(0); controller.setSelecteEdge(null); controller.setCurIteration(0); elementGraph.setText("None"); canvas.tempCps = null; canvas.repaint(); IdCounter.resetObjectCounter(CounterType.Object); IdCounter.resetObjectCounter(CounterType.Element); controller.calculateStateAndVisualForCurrentTimeStep(); }); mntmOpen.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { menuFileExitActionPerformed(); } private void menuFileExitActionPerformed() { JFileChooser fileChooser = new JFileChooser(); fileChooser.setCurrentDirectory(new File(System.getProperty("user.dir") + "/exampleNetworks/")); FileNameExtensionFilter holonFilter = new FileNameExtensionFilter("Holon Save File(*.holon)", "holon"); fileChooser.setFileFilter(holonFilter); if (fileChooser.showOpenDialog(holegJFrame) == JFileChooser.APPROVE_OPTION) { File file = fileChooser.getSelectedFile(); try { while (tabbedPaneInnerOriginal.getTabCount() > 1) { tabbedPaneInnerOriginal.remove(1); } model.getSelectedObjects().clear(); controller.loadFile(file.getAbsolutePath()); canvas.repaint(); categoryTree.repaint(); controller.calculateStateAndVisualForCurrentTimeStep(); } catch (IOException | ArchiveException e) { e.printStackTrace(); JLabel message = new JLabel("The savefile is corrupt and cannot be opened."); JOptionPane.showMessageDialog(holegJFrame, message, "", JOptionPane.ERROR_MESSAGE); } } } }); mntmSave.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { menuSaveActionPerformed(); } private void menuSaveActionPerformed() { JFileChooser fileChooser = new JFileChooser(); FileNameExtensionFilter holonFilter = new FileNameExtensionFilter("Holon Save File(*.holon)", "holon"); fileChooser.setFileFilter(holonFilter); if (fileChooser.showSaveDialog(holegJFrame) == JFileChooser.APPROVE_OPTION) { File selectedFile = fileChooser.getSelectedFile(); String fileName = selectedFile.getName(); String fullPath = fileChooser.getSelectedFile().getPath(); if (fileChooser.getFileFilter().equals(holonFilter)) { if (!fileName.contains(".")) fullPath += ".holon"; } if (!fullPath.endsWith(".holon")) { String suffix = fullPath.substring(fullPath.lastIndexOf("."), fullPath.length()); String[] options = new String[] { "keep .holon", "use " + suffix }; JLabel message = new JLabel( "Are you sure to use the extension \"" + suffix + "\" instead of \".holon\"?"); int response = JOptionPane.showOptionDialog(holegJFrame, message, "", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[1]); if (response == 0) fullPath = fullPath.replace(suffix, ".holon"); } try { controller.saveFile(new File(fullPath).getAbsolutePath()); } catch (IOException | ArchiveException e) { e.printStackTrace(); } } } }); mntmUndo.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { menuUndoActionPerformed(); } private void menuUndoActionPerformed() { try { controller.loadAutoSave(controller.getUndoSave()); closeInvalidUpperNodeTabs(); controller.calculateStateAndVisualForCurrentTimeStep(); canvas.repaint(); } catch (IOException e) { e.printStackTrace(); } } }); mntmRedo.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { menuRedoActionPerformed(); } private void menuRedoActionPerformed() { try { controller.loadAutoSave(controller.getRedoSave()); closeInvalidUpperNodeTabs(); controller.calculateStateAndVisualForCurrentTimeStep(); canvas.repaint(); } catch (IOException e) { e.printStackTrace(); } } }); timePanel = new TimePanel(controller); timePanel.setBorder(null); timePanel.getTimeSlider().addChangeListener(changeEvent -> { // TimeSliderChanged event controller.calculateStateAndVisualForTimeStep(timePanel.getTimeSlider().getValue()); unitGraph.repaint(); contentPane.updateUI(); }); splitPane1.setMinimumSize(new Dimension(0, 25)); splitPane.setRightComponent(splitPane1); splitPane.setDividerLocation(200); splitPane1.setDividerLocation(500); splitPane.setLeftComponent(scrollPane1); tabbedPaneOriginal.addTab("View", tabbedPaneInnerOriginal); myPanel.add(canvasSP, BorderLayout.CENTER); tabbedPaneInnerOriginal.addTab("Main Grid", myPanel); splitPane1.setLeftComponent(tabbedPaneOriginal); splitPane1.setRightComponent(splitHolonElPro); splitPane1.setResizeWeight(0.9); splitHolonElPro.setDividerLocation(700); // containing the graph and the elements-list splitHolonElPro.setTopComponent(splitGraphHolonEl); // containing the object's properties splitHolonElPro.setBottomComponent(scrollProperties); splitGraphHolonEl.setTopComponent(inspector); splitGraphHolonEl.setDividerLocation(distanceBetweenElementsAndGraph); canvasSP.setViewportView(canvas); tabbedPaneOriginal.setBorder(null); scrollProperties.setBorder(null); splitPane.setBorder(null); splitPane1.setBorder(null); splitHolonElPro.setBorder(null); splitGraphHolonEl.setBorder(null); panelHolonEl.setBorder(null); canvasSP.setBorder(null); holegJFrame.getContentPane().add(timePanel, BorderLayout.SOUTH); try { controller.loadAutoSave(System.getProperty("user.home") + "/.config/HolonGUI/Category/Category.json"); } catch (IOException e1) { } String autoPath = System.getProperty("user.home") + "/.config/HolonGUI/Autosave/"; File dest = new File(autoPath); ArrayList oldAutoSaves = controller.filterOldAutoSaveFiles(); int nrOfOldSaves = oldAutoSaves.size(); if (nrOfOldSaves > 0) { int dialogButton = JOptionPane.YES_NO_OPTION; int dialogResult = JOptionPane.showConfirmDialog(holegJFrame, "Old autosave file was found, should it be loaded?", warningText, dialogButton); if (dialogResult == JOptionPane.YES_OPTION) { if (dest.exists()) { model.setAutoSaveNr(nrOfOldSaves - 1); mntmRedo.doClick(); } else { JOptionPane.showMessageDialog(holegJFrame, "Autosave could not be loaded."); setUpAutoSave(dest); } } else { setUpAutoSave(dest); } // after all: delete the obsolete/old autosave files from the // directory controller.deleteObsoleteAutoSaveFiles(); } canvasSP.addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { controller.setCanvasX(Math.max(model.getCanvasX(), canvasSP.getViewport().getWidth())); controller.setCanvasY(Math.max(model.getCanvasY(), canvasSP.getViewport().getHeight())); canvas.repaint(); } }); } private void initWindowMenu() { menuBar.add(menuWindow); // Algo JMenuItem openMenu = new JMenuItem("Open Algorithm Panel", new ImageIcon(ImageImport .loadImage("/Button_Images/iconAlgo.png").getScaledInstance(20, 20, java.awt.Image.SCALE_SMOOTH))); openMenu.addActionListener(actionEvent -> { new AddOnWindow(holegJFrame, controller); }); openMenu.setAccelerator(KeyStroke.getKeyStroke('N', Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx())); menuWindow.add(openMenu); // Outliner JMenuItem openOutliner = new JMenuItem("Open Outliner", new ImageIcon(ImageImport .loadImage("/Button_Images/iconOutliner.png").getScaledInstance(20, 20, java.awt.Image.SCALE_SMOOTH))); openOutliner.addActionListener(actionEvent -> { outlinerList.add(new Outliner(holegJFrame, model, controller)); }); openOutliner .setAccelerator(KeyStroke.getKeyStroke('O', Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx())); menuWindow.add(openOutliner); // FlexWindow JMenuItem openFlexMenuItem = new JMenuItem("Open Flexibility Panel", new ImageIcon(ImageImport .loadImage("/Button_Images/iconAlgo.png").getScaledInstance(20, 20, java.awt.Image.SCALE_SMOOTH))); openFlexMenuItem.addActionListener(actionEvent -> { flexList.add(new FlexWindow(holegJFrame, controller)); }); openFlexMenuItem .setAccelerator(KeyStroke.getKeyStroke('L', Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx())); menuWindow.add(openFlexMenuItem); } public void updateOutliners(DecoratedState state) { // remove closed Outliner ListIterator iter = outlinerList.listIterator(); while (iter.hasNext()) { if (iter.next().isClosed) iter.remove(); } // update open Outliner for (Outliner out : outlinerList) { out.repaintWithDecoratedState(state); } } public void updateFlexWindows() { // remove closed Outliner ListIterator iter = flexList.listIterator(); while (iter.hasNext()) { if (iter.next().isClosed) iter.remove(); } // update open Flex for (FlexWindow out : flexList) { out.update(); } } private boolean isUpperPanelInsideBounds() { int x = holegJFrame.getX(); int y = holegJFrame.getY(); int width = holegJFrame.getWidth(); // get all connected screen devices GraphicsDevice[] screenDevices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices(); boolean isUpperPanelVisible = false; // and check whether they contain the upper left or upper right point of // the frame for (GraphicsDevice device : screenDevices) { Rectangle bounds = device.getDefaultConfiguration().getBounds(); if (bounds.contains(x, y) || bounds.contains(x + width, y)) { isUpperPanelVisible = true; break; } } return isUpperPanelVisible; } /** * Sets up autosave if no old one is loaded at the beginning * * @param dest path to save-folder */ private void setUpAutoSave(File dest) { dest.mkdirs(); try { controller.autoSave(); } catch (IOException e1) { e1.printStackTrace(); } } /** * reloads the Categories from Model. * * @param categories the current categories */ private void updateCategories(final ArrayList categories) { DefaultTreeModel treemodel = new DefaultTreeModel(new DefaultMutableTreeNode("Categories") { private static final long serialVersionUID = 1L; { DefaultMutableTreeNode node1; for (Category c : categories) { node1 = new DefaultMutableTreeNode(c.getName()); for (AbstractCanvasObject obj : c.getObjects()) { node1.add(new DefaultMutableTreeNode(obj.getName())); } add(node1); } } }); categoryTree.setModel(treemodel); } /** * When changes are made to the Categories. * * @param categories the Categories */ public void updateCategoryUI(ArrayList categories) { DefaultTreeModel model = (DefaultTreeModel) categoryTree.getModel(); updateCategories(categories); model.reload(); } void setVisible(boolean value) { holegJFrame.setVisible(value); } /* * Open a new Tab with an UpperNodeCanvas */ public void openNewUpperNodeTab(GroupNode node) { chooseTabTemp(); JScrollPane scrollPane = getScrollPaneFromTabbedPane(); if (scrollPane.getViewport().getComponent(0) instanceof Canvas) { unc = new GroupNodeCanvas(model, controller, unitGraph, node, "", scrollPane.getViewport().getComponent(0)); } else { unc = new GroupNodeCanvas(model, controller, unitGraph, node, ((GroupNodeCanvas) scrollPane.getViewport().getComponent(0)).getParentPath() + " -> ", scrollPane.getViewport().getComponent(0)); } // check if tab already open for clicked NodeOfNode boolean dupl = false; for (int i = 1; i < tabbedPaneInnerOriginal.getTabCount(); i++) { JScrollPane paneOriginal = (JScrollPane) tabbedPaneInnerOriginal.getComponentAt(i); if (paneOriginal != null && ((GroupNodeCanvas) paneOriginal.getViewport().getComponent(0)).getGroupNode() .getId() == node.getId()) { dupl = true; // set selected component to view tabbedPaneOriginal.setSelectedComponent(tabbedPaneInnerOriginal); // set selected tab in view to found upper-node-canvas tabbedPaneInnerOriginal.setSelectedComponent(tabbedPaneInnerOriginal.getComponentAt(i)); } // if we found a duplicate, break if (dupl) { break; } } if (!dupl) { JScrollPane sp = new JScrollPane(unc); sp.setBorder(null); // Selected tabbed Pane = tabbedPaneOriginal or tabbedPaneSplit if (tabTemp == tabbedPaneOriginal) { this.tabbedPaneInnerOriginal.add(node.getName(), sp); this.tabbedPaneInnerOriginal.setSelectedComponent(sp); this.tabbedPaneInnerOriginal.setTabComponentAt(this.tabbedPaneInnerOriginal.getTabCount() - 1, new ButtonTabComponent(this.tabbedPaneInnerOriginal)); } } } // TODO refactor tabbedPane and access to groupNodeViews private void updateUpperNodes() { for (Component c : tabbedPaneInnerOriginal.getComponents()) { if (!(c instanceof JScrollPane)) { continue; } Component pane = ((JScrollPane) c).getViewport().getComponent(0); if (pane instanceof GroupNodeCanvas) { temp = model.getHashcodeMap().get(((GroupNodeCanvas) pane).hashCode()); ((GroupNodeCanvas) pane).setGroupNode((GroupNode) temp); } } } /** * Removes UpperNodeTab if UpperNode was deleted * * @param cps the CPS object that is currently selected */ private void removeUpperNodeTab(AbstractCanvasObject cps) { if (cps instanceof GroupNode) { for (int i = 1; i < tabbedPaneInnerOriginal.getTabCount(); i++) { JScrollPane scrollPaneOriginal = (JScrollPane) tabbedPaneInnerOriginal.getComponentAt(i); if (scrollPaneOriginal == null) { } else if (((GroupNodeCanvas) scrollPaneOriginal.getViewport().getComponent(0)).getGroupNode() .getId() == cps.getId()) { ((ButtonTabComponent) tabbedPaneInnerOriginal.getTabComponentAt(i)).removeTabs(); break; } } } } /** * chooses whether to set the tabTemp to tabbedPaneOriginal or tabbedPaneSplit */ private void chooseTabTemp() { // TODO Remove tabTabbed tabTemp = tabbedPaneOriginal; } private JScrollPane getScrollPaneFromTabbedPane() { return getScrollPaneFromTabbedPane(-1); } private JScrollPane getScrollPaneFromTabbedPane(int index) { Component upperLevelSelectedComponent; if (tabTemp == null) { return null; } if (index == -1) { upperLevelSelectedComponent = tabTemp.getSelectedComponent(); } else { upperLevelSelectedComponent = tabTemp.getComponentAt(index); } if (upperLevelSelectedComponent instanceof JTabbedPane) { Component nextLevel = ((JTabbedPane) upperLevelSelectedComponent).getSelectedComponent(); if (nextLevel instanceof JPanel) return (JScrollPane) ((JPanel) nextLevel).getComponent(0); else return (JScrollPane) nextLevel; } else if (upperLevelSelectedComponent instanceof JScrollPane) { return (JScrollPane) upperLevelSelectedComponent; } else { return null; } } private void openWebpage(String URL) { try { java.awt.Desktop.getDesktop().browse(new URI(URL)); } catch (Exception e) { e.printStackTrace(); } } /** * closes all UpperNodeTabs, that don't have a valid UpperNode (e.g. if it was * ungrouped/deleted/replaced and so on) */ private void closeInvalidUpperNodeTabs() { /** * close bugged Tabs */ for (int i = 1; i < tabbedPaneInnerOriginal.getTabCount(); i++) { JScrollPane scrollPaneOriginal = (JScrollPane) tabbedPaneInnerOriginal.getComponentAt(i); if (((GroupNodeCanvas) scrollPaneOriginal.getViewport().getComponent(0)).getGroupNode() == null) { ((ButtonTabComponent) tabbedPaneInnerOriginal.getTabComponentAt(i)).removeTabs(); break; } } } public void repaintCanvas() { tabbedPaneInnerOriginal.revalidate(); tabbedPaneInnerOriginal.repaint(); for (int i = 1; i < tabbedPaneInnerOriginal.getTabCount(); i++) { JScrollPane scrollPaneOriginal = (JScrollPane) tabbedPaneInnerOriginal.getComponentAt(i); scrollPaneOriginal.revalidate(); } } /** * TODO: Class should be reworked as soon as possible! * * @param state */ public void guiDisable(boolean state) { canvas.disabled = state; for (int i = 1; i < tabbedPaneInnerOriginal.getTabCount(); i++) { JScrollPane scrollPaneOriginal = (JScrollPane) tabbedPaneInnerOriginal.getComponentAt(i); if (((GroupNodeCanvas) scrollPaneOriginal.getViewport().getComponent(0)).getGroupNode() != null) { ((GroupNodeCanvas) scrollPaneOriginal.getViewport().getComponent(0)).disabled = state; } } } }