|
@@ -0,0 +1,2686 @@
|
|
|
+package ui.view;
|
|
|
+
|
|
|
+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.net.URISyntaxException;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.ListIterator;
|
|
|
+import java.util.Timer;
|
|
|
+import java.util.TimerTask;
|
|
|
+
|
|
|
+import javax.swing.AbstractAction;
|
|
|
+import javax.swing.ActionMap;
|
|
|
+import javax.swing.Box;
|
|
|
+import javax.swing.BoxLayout;
|
|
|
+import javax.swing.CellEditor;
|
|
|
+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.JTable;
|
|
|
+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.table.DefaultTableModel;
|
|
|
+import javax.swing.table.JTableHeader;
|
|
|
+import javax.swing.table.TableCellEditor;
|
|
|
+import javax.swing.table.TableCellRenderer;
|
|
|
+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.HolonElement;
|
|
|
+import classes.HolonObject;
|
|
|
+import classes.HolonSwitch;
|
|
|
+import classes.IdCounter;
|
|
|
+import classes.IdCounter.CounterType;
|
|
|
+import interfaces.GraphEditable;
|
|
|
+import ui.controller.Control;
|
|
|
+import ui.controller.UpdateController;
|
|
|
+import ui.model.DecoratedState;
|
|
|
+import ui.model.Model;
|
|
|
+import ui.model.Model.FairnessModel;
|
|
|
+import ui.view.CreateNewDialog.Option;
|
|
|
+import utility.Event;
|
|
|
+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");
|
|
|
+
|
|
|
+
|
|
|
+ private final HolonInformationPanel informationPanel;
|
|
|
+
|
|
|
+ /** 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);
|
|
|
+ // the same tabbed Pane that appears once the view is split
|
|
|
+ private final JTabbedPane tabbedPaneSplit = new JTabbedPane(JTabbedPane.TOP);
|
|
|
+ private final JPopupMenu popmenuEdit = new JPopupMenu();
|
|
|
+ private final JMenuItem editItem = new JMenuItem("Edit Object");
|
|
|
+ private final JLabel maxGraph = new JLabel("100%");
|
|
|
+ private final JLabel medGraph = new JLabel("50%");
|
|
|
+ private final JLabel minGraph = new JLabel("0%");
|
|
|
+ private final JLabel elementGraph = new JLabel("None ");
|
|
|
+ private final ArrayList<HolonElement> selectedElements = new ArrayList<>();
|
|
|
+ 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 JSplitPane splitHolonElPro = new JSplitPane(
|
|
|
+ JSplitPane.VERTICAL_SPLIT);
|
|
|
+ private final JSplitPane splitGraphHolonEl = new JSplitPane(
|
|
|
+ JSplitPane.VERTICAL_SPLIT);
|
|
|
+ private final int distanceBetweenElementsAndGraph = 350;
|
|
|
+ // Model for single or multi selection
|
|
|
+ private final JPanel scrollElements = new JPanel();
|
|
|
+ private final JScrollPane tableHolonElementScrollPane = new JScrollPane();
|
|
|
+
|
|
|
+ //Prechoosed local Periods
|
|
|
+ private String[] comboContext = {
|
|
|
+ "", "5", "10", "20" ,"100", "1000"
|
|
|
+ };
|
|
|
+ private JComboBox<String> localPeriodInput = new JComboBox<String>(comboContext);
|
|
|
+ JButton resetButton = new JButton("", new ImageIcon(ImageImport.loadImage("/Images/resetIcon3.png")));
|
|
|
+ ImageIcon localPeriodButtonImage = new ImageIcon(GrayFilter.createDisabledImage(ImageImport.loadImage("/Images/Graph.png")));
|
|
|
+ private JButton localPeriodButton = new JButton("", localPeriodButtonImage);
|
|
|
+ private final JPanel graphLabel = new JPanel();
|
|
|
+ private final JScrollPane scrollProperties = new JScrollPane();
|
|
|
+ // In this section is the graph for the selected HolonElement of the clicked
|
|
|
+ // HolonObject
|
|
|
+ private final DefaultTableModel tableModelGraph = new DefaultTableModel();
|
|
|
+ private final JScrollPane scrollGraph = new JScrollPane();
|
|
|
+ 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 JButton btnAddHolEL = new JButton();
|
|
|
+ private final JButton btnDelHolEL = new JButton();
|
|
|
+
|
|
|
+ private final JToolBar toolBar = new JToolBar();
|
|
|
+ private final JToolBar toolBarHolonEl = new JToolBar();
|
|
|
+ private final JToolBar toolBarGraph = new JToolBar();
|
|
|
+ // Languages
|
|
|
+ private final MyCanvas 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");
|
|
|
+ private final String[] columnNamesMulti = { "Object", "Nr.", "Device",
|
|
|
+ "Energy", "Flexibility active", "Quantity", "Activated" };
|
|
|
+ private final String[] columnNamesSingle = { "Nr.", "Device", "Energy",
|
|
|
+ "Flexibility active", "Quantity", "Activated" };
|
|
|
+ private final ArrayList<PropertyTable> tables = new ArrayList<>();
|
|
|
+ private final UpdateController updCon;
|
|
|
+ // for doubleclick
|
|
|
+ private boolean click = false;
|
|
|
+ private JFrame holegJFrame;
|
|
|
+ private JTabbedPane tabTemp; // tabbedPaneOriginal or tabbedPaneSplit
|
|
|
+ private boolean initSplit = true;
|
|
|
+ private String catOfObjToBeEdited;
|
|
|
+ private GroupNodeCanvas unc;
|
|
|
+ private JPanel contentPane;
|
|
|
+ private String holonEleNamesDisplayed = "None ";
|
|
|
+ // Pop up Windows
|
|
|
+ private AddObjectPopUp addObjectPopUP;
|
|
|
+ private AboutUsPopUp aboutUsPopUp;
|
|
|
+ private AddElementPopUp addElementPopUp;
|
|
|
+ // variables
|
|
|
+ private boolean dragging = false;
|
|
|
+ private String actualObjectClicked;
|
|
|
+ private Image img = null;
|
|
|
+ private AbstractCanvasObject tempCps = null;
|
|
|
+ private int yValueElements = 0;
|
|
|
+ // Time Stuff
|
|
|
+ private TimePanel timePanel;
|
|
|
+ public TimePanel getTimePanel() {
|
|
|
+ return timePanel;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Coord for all Cells with text
|
|
|
+ private int yThis;
|
|
|
+ private int xThis;
|
|
|
+ // Coord for all Cells with boolean values (checkbox)
|
|
|
+ private int yBTis;
|
|
|
+ private int xBThis;
|
|
|
+ // Coord for the Edit-Modus in the PropertieTable
|
|
|
+ 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<Outliner> outlinerList = new ArrayList<Outliner>();
|
|
|
+ private List<FlexWindow> flexList = new ArrayList<FlexWindow>();
|
|
|
+
|
|
|
+ private JMenuItem removeItem = new JMenuItem("Remove");
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Create the application.
|
|
|
+ *
|
|
|
+ * @param control
|
|
|
+ * the Controller
|
|
|
+ */
|
|
|
+ GUI(Control control) {
|
|
|
+ this.controller = control;
|
|
|
+ this.informationPanel = new HolonInformationPanel(control);
|
|
|
+ this.model = control.getModel();
|
|
|
+ control.setGui(this);
|
|
|
+ this.unitGraph = new UnitGraph(model, control);
|
|
|
+ this.canvas = new MyCanvas(model, control, unitGraph);
|
|
|
+ initialize();
|
|
|
+ updateCategories(model.getCategories());
|
|
|
+ updCon = new UpdateController(model, controller);
|
|
|
+ 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<Integer> 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_IN_FOCUSED_WINDOW;
|
|
|
+ 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();
|
|
|
+
|
|
|
+ controller.clearSelection();
|
|
|
+
|
|
|
+ // Uppernode Canvas?
|
|
|
+ JScrollPane scrollPane = getScrollPaneFromTabbedPane();
|
|
|
+ Component canvasOrUpperNodeCanvas = scrollPane.getViewport()
|
|
|
+ .getComponent(0);
|
|
|
+
|
|
|
+ if (canvasOrUpperNodeCanvas instanceof GroupNodeCanvas) {
|
|
|
+ GroupNodeCanvas uNC = (GroupNodeCanvas) canvasOrUpperNodeCanvas;
|
|
|
+ for (AbstractCanvasObject cps : uNC.upperNode.getNodes()) {
|
|
|
+ controller.addSelectedObject(cps);
|
|
|
+ }
|
|
|
+ uNC.repaint();
|
|
|
+ // or Canvas?
|
|
|
+ } else if (canvasOrUpperNodeCanvas instanceof MyCanvas) {
|
|
|
+ for (AbstractCanvasObject cps : model.getObjectsOnCanvas()) {
|
|
|
+ controller.addSelectedObject(cps);
|
|
|
+ }
|
|
|
+ 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.getSelectedCpsObjects()) {
|
|
|
+ if (uNC.upperNode.getNodes().contains(cps)) {
|
|
|
+ controller.delObjUpperNode(cps, uNC.upperNode);
|
|
|
+ unc.setToolTip(false);
|
|
|
+
|
|
|
+ // remove UpperNodeTab if UpperNode deleted
|
|
|
+ removeUpperNodeTab(cps);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ uNC.repaint();
|
|
|
+
|
|
|
+ // or Canvas?
|
|
|
+ } else if (canvasOrUpperNodeCanvas instanceof MyCanvas) {
|
|
|
+ boolean save = false;
|
|
|
+ // Edge Deleting
|
|
|
+ Edge edgeHighlight = model.getSelectedEdge();
|
|
|
+ if (edgeHighlight != null) {
|
|
|
+ controller.removeEdgesOnCanvas(edgeHighlight);
|
|
|
+ ((MyCanvas) canvasOrUpperNodeCanvas).edgeHighlight = null;
|
|
|
+ }
|
|
|
+ for (int j = 0; j < model.getSelectedCpsObjects().size(); j++) {
|
|
|
+ AbstractCanvasObject cps = model.getSelectedCpsObjects()
|
|
|
+ .get(j);
|
|
|
+ if (j < model.getSelectedCpsObjects().size() - 1)
|
|
|
+ save = true;
|
|
|
+ controller.delCanvasObject(cps, save);
|
|
|
+ canvas.setToolTip(false);
|
|
|
+
|
|
|
+ // remove UpperNodeTab if UpperNode deleted
|
|
|
+ removeUpperNodeTab(cps);
|
|
|
+ }
|
|
|
+ canvas.repaint();
|
|
|
+ }
|
|
|
+
|
|
|
+ // recalculate net if a producer was deleted
|
|
|
+ if (wasProducerDeleted) {
|
|
|
+ controller.resetSimulation();
|
|
|
+ controller.calculateStateAndVisualForCurrentTimeStep();
|
|
|
+ }
|
|
|
+
|
|
|
+ controller.clearSelection();
|
|
|
+ hideScrollGraph();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ 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();
|
|
|
+
|
|
|
+ JScrollPane scrollPane = getScrollPaneFromTabbedPane();
|
|
|
+ if (!model.getSelectedCpsObjects().isEmpty()) {
|
|
|
+ if (scrollPane.getViewport().getComponent(0) instanceof GroupNodeCanvas)
|
|
|
+ controller.copy(((GroupNodeCanvas) scrollPane
|
|
|
+ .getViewport().getComponent(0)).upperNode);
|
|
|
+ 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 (!initSplit) {
|
|
|
+ tabTemp = tabbedPaneSplit;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(tabTemp == null)return;
|
|
|
+ JScrollPane scrollPane = getScrollPaneFromTabbedPane();
|
|
|
+ Component canvasOrUpperNodeCanvas = scrollPane
|
|
|
+ .getViewport().getComponent(0);
|
|
|
+
|
|
|
+ if (tabTemp != null
|
|
|
+ && canvasOrUpperNodeCanvas instanceof GroupNodeCanvas) {
|
|
|
+
|
|
|
+ controller
|
|
|
+ .paste(((GroupNodeCanvas) canvasOrUpperNodeCanvas).upperNode,
|
|
|
+ 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.getSelectedCpsObjects().isEmpty()) {
|
|
|
+ if (scrollPane.getViewport().getComponent(0) instanceof GroupNodeCanvas) {
|
|
|
+ controller.cut(((GroupNodeCanvas) scrollPane
|
|
|
+ .getViewport().getComponent(0)).upperNode);
|
|
|
+ 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<Category> 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, tabbedPaneOriginal, tabbedPaneSplit,
|
|
|
+ holegJFrame);
|
|
|
+ popUp.setVisible(true);
|
|
|
+ });
|
|
|
+
|
|
|
+ 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 MyCanvas) {
|
|
|
+ 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.upperNode,
|
|
|
+ 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);
|
|
|
+
|
|
|
+ tabbedPaneOriginal.addChangeListener(changeEvent -> {
|
|
|
+ if (tabbedPaneOriginal.getSelectedComponent() == null) {
|
|
|
+ Component tempC = tabbedPaneSplit.getSelectedComponent();
|
|
|
+ tabbedPaneSplit.setComponentAt(
|
|
|
+ tabbedPaneOriginal.getSelectedIndex(), null);
|
|
|
+ tabbedPaneOriginal.setComponentAt(
|
|
|
+ tabbedPaneOriginal.getSelectedIndex(), tempC);
|
|
|
+ tempC = tabbedPaneOriginal.getComponentAt((tabbedPaneOriginal
|
|
|
+ .getSelectedIndex() + 1)
|
|
|
+ % (tabbedPaneOriginal.getTabCount()));
|
|
|
+ tabbedPaneOriginal.setComponentAt(
|
|
|
+ (tabbedPaneOriginal.getSelectedIndex() + 1)
|
|
|
+ % (tabbedPaneOriginal.getTabCount()), null);
|
|
|
+ tabbedPaneSplit.setComponentAt(
|
|
|
+ (tabbedPaneOriginal.getSelectedIndex() + 1)
|
|
|
+ % (tabbedPaneOriginal.getTabCount()), tempC);
|
|
|
+ tabbedPaneSplit.setSelectedIndex((tabbedPaneOriginal
|
|
|
+ .getSelectedIndex() + 1)
|
|
|
+ % (tabbedPaneOriginal.getTabCount()));
|
|
|
+ contentPane.updateUI();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ tabbedPaneSplit.addChangeListener(changeEvent -> {
|
|
|
+ if (tabbedPaneSplit.getSelectedComponent() == null && !initSplit) {
|
|
|
+ Component tempC = tabbedPaneOriginal
|
|
|
+ .getComponentAt(tabbedPaneSplit.getSelectedIndex());
|
|
|
+ tabbedPaneOriginal.setComponentAt(
|
|
|
+ tabbedPaneSplit.getSelectedIndex(), null);
|
|
|
+ tabbedPaneSplit.setComponentAt(
|
|
|
+ tabbedPaneSplit.getSelectedIndex(), tempC);
|
|
|
+
|
|
|
+ for (int i = 0; i < tabbedPaneOriginal.getTabCount(); i++) {
|
|
|
+ if (tabbedPaneSplit.getComponentAt(i) != null
|
|
|
+ && tabbedPaneSplit.getComponentAt(i) != tempC) {
|
|
|
+ tempC = tabbedPaneSplit.getComponentAt(i);
|
|
|
+ tabbedPaneSplit.setComponentAt(i, null);
|
|
|
+ tabbedPaneOriginal.setComponentAt(i, tempC);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (tabbedPaneOriginal.getSelectedIndex() == tabbedPaneSplit
|
|
|
+ .getSelectedIndex()) {
|
|
|
+ tabbedPaneOriginal.setSelectedIndex((tabbedPaneSplit
|
|
|
+ .getSelectedIndex() + 1)
|
|
|
+ % tabbedPaneOriginal.getTabCount());
|
|
|
+ }
|
|
|
+ contentPane.updateUI();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ canvas.setBackground(Color.WHITE);
|
|
|
+ canvas.setPreferredSize(new Dimension(model.getCanvasX(), model
|
|
|
+ .getCanvasY()));
|
|
|
+ /********************
|
|
|
+ * RIGHT CONTAINER (INFORMATION)
|
|
|
+ **********************/
|
|
|
+ // Set up of the HolonElements section
|
|
|
+ // Two different Models: Multi for multi-selection mode and Single for
|
|
|
+ // single-selection mode (CPS-Object)
|
|
|
+ model.getMultiTable().setColumnIdentifiers(columnNamesMulti);
|
|
|
+ model.getSingleTable().setColumnIdentifiers(columnNamesSingle);
|
|
|
+ model.getTableHolonElement().setBorder(null);
|
|
|
+ model.getTableHolonElement().setFillsViewportHeight(true);
|
|
|
+ model.getTableHolonElement().setCellSelectionEnabled(true);
|
|
|
+ model.getTableHolonElement().setColumnSelectionAllowed(true);
|
|
|
+ /*
|
|
|
+ * Register Clicks on ColumNames for sorting:
|
|
|
+ */
|
|
|
+ model.getTableHolonElement().getTableHeader()
|
|
|
+ .addMouseListener(new MouseAdapter() {
|
|
|
+ public void mouseClicked(MouseEvent e) {
|
|
|
+ //TODO: sort
|
|
|
+ //clicked column
|
|
|
+ int col = model.getTableHolonElement().columnAtPoint(
|
|
|
+ e.getPoint());
|
|
|
+ //insert column into UpdateController
|
|
|
+ updCon.setSortBy(col);
|
|
|
+ //refresh HolonElementTable
|
|
|
+ updCon.refreshTableHolonElement(model.getMultiTable(), model.getSingleTable());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mouseExited(MouseEvent e) {
|
|
|
+ /**
|
|
|
+ * Stop Editing, if mouse exits the Table
|
|
|
+ */
|
|
|
+ JTable holElem = model.getTableHolonElement();
|
|
|
+ JTableHeader holElemHead = holElem.getTableHeader();
|
|
|
+ if(e.getX()<=0 || e.getX()>=holElemHead.getWidth()
|
|
|
+ || e.getY() <= 0){
|
|
|
+ CellEditor cellEditor = holElem.getCellEditor();
|
|
|
+ if (cellEditor != null) {
|
|
|
+ if (cellEditor.getCellEditorValue() != null) {
|
|
|
+ /** TODO: Maybe try to save current Data */
|
|
|
+ cellEditor.stopCellEditing();
|
|
|
+ } else {
|
|
|
+ cellEditor.cancelCellEditing();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ });
|
|
|
+ model.getTableHolonElement().getTableHeader().setReorderingAllowed(false);
|
|
|
+
|
|
|
+ tableHolonElementScrollPane.setViewportView(model
|
|
|
+ .getTableHolonElement());
|
|
|
+ scrollElements.setLayout(new BorderLayout(0, 0));
|
|
|
+ scrollElements.add(panelHolonEl, BorderLayout.NORTH);
|
|
|
+ scrollElements.add(tableHolonElementScrollPane);
|
|
|
+ panelHolonEl.setLayout(new BoxLayout(panelHolonEl, BoxLayout.X_AXIS));
|
|
|
+ toolBarHolonEl.add(btnAddHolEL);
|
|
|
+ toolBarHolonEl.add(btnDelHolEL);
|
|
|
+ toolBarHolonEl.setFloatable(false);
|
|
|
+ panelHolonEl.add(toolBarHolonEl);
|
|
|
+
|
|
|
+ // Set up of the Properties section
|
|
|
+ scrollProperties.setViewportView(this.informationPanel);
|
|
|
+ scrollProperties.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
|
|
+ scrollProperties.getVerticalScrollBar().setUnitIncrement(16);
|
|
|
+
|
|
|
+ // Set up of the Graph section
|
|
|
+ scrollGraph.setViewportView(unitGraph);
|
|
|
+ graphLabel.setLayout(new BorderLayout(0, 10));
|
|
|
+ graphLabel.add(maxGraph, BorderLayout.NORTH);
|
|
|
+ graphLabel.add(medGraph, BorderLayout.CENTER);
|
|
|
+ graphLabel.add(minGraph, BorderLayout.SOUTH);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ toolBarGraph.setFloatable(false);
|
|
|
+ toolBarGraph.setAlignmentY(Component.RIGHT_ALIGNMENT);
|
|
|
+
|
|
|
+
|
|
|
+ localPeriodButton.setToolTipText("Toggle Local/Global Mode");
|
|
|
+ toolBarGraph.add(localPeriodButton);
|
|
|
+ //ComboBox
|
|
|
+ localPeriodInput.setEditable(true);
|
|
|
+ localPeriodInput.setVisible(false);
|
|
|
+ localPeriodInput.setMaximumSize(new Dimension(20,23));
|
|
|
+ localPeriodInput.addItemListener(aListener->{
|
|
|
+ if(aListener.getStateChange() == ItemEvent.DESELECTED) {
|
|
|
+ validateInput(localPeriodInput.getEditor().getItem().toString(), true);
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ toolBarGraph.add(localPeriodInput);
|
|
|
+
|
|
|
+ //localPeriodButtonFunction
|
|
|
+ localPeriodButton.addActionListener(actionEvent->{
|
|
|
+ boolean newState= !localPeriodInput.isVisible();
|
|
|
+ changeLocalPeriodButtonAppeareance(newState);
|
|
|
+ unitGraph.setUseLocalPeriod(newState);
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ toolBarGraph.add(Box.createHorizontalGlue());
|
|
|
+ resetButton.setToolTipText("Reset");
|
|
|
+ resetButton.addActionListener(actionEvent -> unitGraph.reset());
|
|
|
+ toolBarGraph.add(resetButton);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ scrollGraph.setRowHeaderView(graphLabel);
|
|
|
+ scrollGraph.setColumnHeaderView(toolBarGraph);
|
|
|
+
|
|
|
+ tables.add(model.getSingleTable());
|
|
|
+ tables.add(model.getMultiTable());
|
|
|
+ /***********************
|
|
|
+ * HolonElement Table Actions
|
|
|
+ **********************/
|
|
|
+ /*
|
|
|
+ * Add HolonElement to given HolonObject
|
|
|
+ */
|
|
|
+ btnAddHolEL.addActionListener(actionEvent -> {
|
|
|
+ if (model.getSelectedCpsObjects().size() == 1) {
|
|
|
+ AbstractCanvasObject tempCpsObject = updCon.getActualCps();
|
|
|
+ if (tempCpsObject != null
|
|
|
+ && tempCpsObject.getClass() == HolonObject.class
|
|
|
+ && tempCpsObject.getId() != 0) {
|
|
|
+ addElementPopUp = new AddElementPopUp(holegJFrame);
|
|
|
+ addElementPopUp.setActualHolonObject((HolonObject)updCon.getActualCps());
|
|
|
+ addElementPopUp.setVisible(true);
|
|
|
+ HolonElement ele = addElementPopUp.getElement();
|
|
|
+ if (ele != null) {
|
|
|
+ controller.addElementCanvasObject(
|
|
|
+ tempCpsObject.getId(), ele.getEleName(),
|
|
|
+ ele.getAmount(), ele.getEnergyPerElement(),
|
|
|
+ ele.getId());
|
|
|
+ }
|
|
|
+ controller.calculateStateAndVisualForTimeStep(model
|
|
|
+ .getCurIteration());
|
|
|
+ triggerUpdateController(null);
|
|
|
+ contentPane.updateUI();
|
|
|
+ }
|
|
|
+ }else
|
|
|
+ {
|
|
|
+ JOptionPane.showMessageDialog(contentPane, "No object selected.\nPlease select a object first." , "Message" , JOptionPane.INFORMATION_MESSAGE);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ btnAddHolEL.setIcon(new ImageIcon(ImageImport.loadImage("Images/plus.png", 16, 16)));
|
|
|
+ btnAddHolEL.setToolTipText("<html><b>Add Element</b><br>Add a new HolonElement to the HolonObject.</html>");
|
|
|
+
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Delete the chosen HolonElement of the selected HolonObject,
|
|
|
+ * Multi-Selection for CpsObjects as well as for HolonElements possible
|
|
|
+ */
|
|
|
+ btnDelHolEL.addActionListener(actionEvent -> {
|
|
|
+ // For Single Selection of CpsObject
|
|
|
+ if (model.getSelectedCpsObjects().size() == 1) {
|
|
|
+ if (updCon.getActualCps().getClass() == HolonObject.class) {
|
|
|
+ HolonObject obj = (HolonObject) updCon.getActualCps();
|
|
|
+ if(selectedElements.isEmpty())
|
|
|
+ {
|
|
|
+ JOptionPane.showMessageDialog(contentPane, "No element selectet.\nPlease select a element in the list first." , "Message" , JOptionPane.INFORMATION_MESSAGE);
|
|
|
+ }
|
|
|
+ for (HolonElement e : selectedElements) {
|
|
|
+ controller.deleteElementCanvas(obj.getId(),
|
|
|
+ e.getId());
|
|
|
+ controller.calculateStateAndVisualForTimeStep(model
|
|
|
+ .getCurIteration());
|
|
|
+ triggerUpdateController(null);
|
|
|
+ contentPane.updateUI();
|
|
|
+ // Names displayed in graph are not updated
|
|
|
+ }
|
|
|
+ model.getEleToDelete().clear();
|
|
|
+ selectedElements.clear();
|
|
|
+ }
|
|
|
+ // For MultiSelection of CpsObject
|
|
|
+ } else if (model.getSelectedCpsObjects().size() > 1) {
|
|
|
+ for (Integer i : model.getEleToDelete().keySet()) {
|
|
|
+ for (HolonElement e : model.getEleToDelete().get(i)) {
|
|
|
+ controller.deleteElementCanvas(i, e.getId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ triggerUpdateController(null);
|
|
|
+ model.getEleToDelete().clear();
|
|
|
+ selectedElements.clear();
|
|
|
+ }else
|
|
|
+ {
|
|
|
+ JOptionPane.showMessageDialog(contentPane, "No object selectet.\nPlease select a object first." , "No object selectet" , JOptionPane.INFORMATION_MESSAGE);
|
|
|
+ }
|
|
|
+ triggerUpdateController(null);
|
|
|
+ elementGraph.setText("None");
|
|
|
+ holonEleNamesDisplayed = "None";
|
|
|
+}) ;
|
|
|
+ btnDelHolEL.setIcon(new ImageIcon(ImageImport.loadImage("Images/minus.png", 16, 16)));
|
|
|
+ btnDelHolEL.setToolTipText("<html><b>Remove Element</b><br>Removes the selected HolonElement from the HolonObject.</html>");
|
|
|
+ /*
|
|
|
+ * Communication between HolonElement Table and displayed Graph and
|
|
|
+ * Properties, as well as selection of different HolonElements
|
|
|
+ */
|
|
|
+ model.getTableHolonElement().addMouseListener(new MouseAdapter() {
|
|
|
+ public void mousePressed(MouseEvent e) {
|
|
|
+ HolonObject obj = null;
|
|
|
+ if (model.getSelectedCpsObjects().size() == 1
|
|
|
+ && model.getSelectedCpsObjects().get(0) instanceof HolonObject) {
|
|
|
+ obj = (HolonObject) updCon.getActualCps();
|
|
|
+ }
|
|
|
+ yValueElements = e.getY();
|
|
|
+ HolonElement ele;
|
|
|
+ // Search for current clicked HolonElement
|
|
|
+ if (model.getSelectedCpsObjects().size() == 1) {
|
|
|
+ ele = updCon.getActualHolonElement(obj, yValueElements, 0,
|
|
|
+ tables);
|
|
|
+ } else {
|
|
|
+ ele = updCon.getActualHolonElement(null, yValueElements, 0,
|
|
|
+ tables);
|
|
|
+ }
|
|
|
+ // Multi-Selection of HolonElements through control button +
|
|
|
+ // mouse click
|
|
|
+ if (ele != null) {
|
|
|
+ // make energy-consumption graph visible
|
|
|
+ showScrollGraph();
|
|
|
+
|
|
|
+ if (e.isControlDown()) {
|
|
|
+ if (!selectedElements.contains(ele)) {
|
|
|
+ selectedElements.add(ele);
|
|
|
+ if (!holonEleNamesDisplayed.equals("None")) {
|
|
|
+ holonEleNamesDisplayed = holonEleNamesDisplayed
|
|
|
+ + "; " + ele.getEleName() + " ";
|
|
|
+ } else {
|
|
|
+ holonEleNamesDisplayed = ele.getEleName() + " ";
|
|
|
+ }
|
|
|
+ updateUnitGraph((GraphEditable)selectedElements.get(selectedElements.size()-1));
|
|
|
+ }
|
|
|
+ updCon.getActualHolonElement(null, yValueElements, 2,
|
|
|
+ tables);
|
|
|
+ }
|
|
|
+ // if no control-button pressed but a HolonElement chosen
|
|
|
+ else {
|
|
|
+ selectedElements.clear();
|
|
|
+ selectedElements.add(ele);
|
|
|
+ updCon.getActualHolonElement(null, yValueElements, 1,
|
|
|
+ tables);
|
|
|
+ holonEleNamesDisplayed = ele.getEleName() + " ";
|
|
|
+ updateUnitGraph((GraphEditable)selectedElements.get(selectedElements.size()-1));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ elementGraph.setText("None");
|
|
|
+ hideScrollGraph();
|
|
|
+ }
|
|
|
+ // if any HolonElement is double-clicked --> Edit-Mode started
|
|
|
+ // for selected HolonElement
|
|
|
+ if (e.getClickCount() == 2) {
|
|
|
+ yThis = e.getY();
|
|
|
+ xThis = e.getX();
|
|
|
+ }
|
|
|
+ // for single click and empty slot
|
|
|
+ if (e.getClickCount() == 1 && ele == null) {
|
|
|
+ selectedElements.clear();
|
|
|
+ holonEleNamesDisplayed = "None";
|
|
|
+ }
|
|
|
+ elementGraph.setText(holonEleNamesDisplayed);
|
|
|
+ yBTis = e.getY();
|
|
|
+ xBThis = e.getX();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mouseExited(MouseEvent e) {
|
|
|
+ /**
|
|
|
+ * Stop Editing, if mouse exits the Table
|
|
|
+ */
|
|
|
+ JTable holElem = model.getTableHolonElement();
|
|
|
+ if(e.getX()<=0 || e.getX()>=holElem.getWidth()
|
|
|
+ /*|| e.getY() <= 0*/|| e.getY()>= holElem.getHeight()){
|
|
|
+ CellEditor cellEditor = holElem.getCellEditor();
|
|
|
+ if (cellEditor != null) {
|
|
|
+ if (cellEditor.getCellEditorValue() != null) {
|
|
|
+ /** TODO: Maybe try to save current Data */
|
|
|
+ cellEditor.stopCellEditing();
|
|
|
+ } else {
|
|
|
+ cellEditor.cancelCellEditing();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Triggered every time a change is made
|
|
|
+ */
|
|
|
+ model.getTableHolonElement()
|
|
|
+ .addPropertyChangeListener(propertyChangeEvent -> {
|
|
|
+ try {
|
|
|
+ int yMouse = yThis;
|
|
|
+ int yBMouse = yBTis;
|
|
|
+ int selectedValueY = (int) Math.floor(yMouse / 16);
|
|
|
+ int selectedValueBY = (int) Math.floor(yBMouse / 16);
|
|
|
+ // ------------------ multi-selection mode
|
|
|
+ // ------------------
|
|
|
+ if (model.getSelectedCpsObjects().size() > 1) {
|
|
|
+ int selectedValueX = (int) Math
|
|
|
+ .floor(xThis
|
|
|
+ / (model.getTableHolonElement()
|
|
|
+ .getWidth() / 8));
|
|
|
+ int selectedValueBX = (int) Math
|
|
|
+ .floor(xBThis
|
|
|
+ / (model.getTableHolonElement()
|
|
|
+ .getWidth() / 8));
|
|
|
+ if (updCon.getHolonObj(yMouse,
|
|
|
+ model.getMultiTable()) != null) {
|
|
|
+ // For active column (boolean with a checkbox)
|
|
|
+ if (selectedValueBX == 6) {
|
|
|
+ System.out.println("selectedValueBX == 6");
|
|
|
+ HolonElement eleBTemp = updCon
|
|
|
+ .getActualHolonElement(null,
|
|
|
+ yBMouse, 0, tables);
|
|
|
+ String newBStuff = model
|
|
|
+ .getMultiTable()
|
|
|
+ .getValueAt(selectedValueBY,
|
|
|
+ selectedValueBX).toString();
|
|
|
+ Boolean bTemp = Boolean
|
|
|
+ .parseBoolean(newBStuff);
|
|
|
+ eleBTemp.setActive(bTemp);
|
|
|
+ }
|
|
|
+ // For activeFlex column (boolean with a
|
|
|
+ // checkbox)
|
|
|
+ else if (selectedValueBX == 7) {
|
|
|
+ HolonElement eleBTemp = updCon
|
|
|
+ .getActualHolonElement(null,
|
|
|
+ yBMouse, 0, tables);
|
|
|
+ String newBStuff = model
|
|
|
+ .getMultiTable()
|
|
|
+ .getValueAt(selectedValueBY,
|
|
|
+ selectedValueBX).toString();
|
|
|
+ Boolean bTemp = Boolean
|
|
|
+ .parseBoolean(newBStuff);
|
|
|
+ eleBTemp.setActive(bTemp);
|
|
|
+ } else {
|
|
|
+ //TODO: check all possible fields.
|
|
|
+ // Update of HolonElement
|
|
|
+ HolonElement eleTemp = updCon
|
|
|
+ .getActualHolonElement(null,
|
|
|
+ yMouse, 0, tables);
|
|
|
+ String newStuff = model
|
|
|
+ .getMultiTable()
|
|
|
+ .getValueAt(selectedValueY,
|
|
|
+ selectedValueX).toString();
|
|
|
+
|
|
|
+ // Name update
|
|
|
+ if (selectedValueX == 2) {
|
|
|
+ eleTemp.setEleName(newStuff);
|
|
|
+ }
|
|
|
+ // Energy Update
|
|
|
+ else if (selectedValueX == 3) {
|
|
|
+ Float ftemp = Float
|
|
|
+ .parseFloat(newStuff);
|
|
|
+ eleTemp.setEnergyPerElement(ftemp);
|
|
|
+ }
|
|
|
+ // Flexibility
|
|
|
+ else if (selectedValueX == 4) {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ // Amount of Elements update
|
|
|
+ else if (selectedValueX == 5) {
|
|
|
+ Integer iTemp = Integer
|
|
|
+ .parseInt(newStuff);
|
|
|
+ eleTemp.setAmount(iTemp);
|
|
|
+ }
|
|
|
+ else if (selectedValueX == 6) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } // ------------------ single-selection mode
|
|
|
+ // ------------------
|
|
|
+ else if (model.getSelectedCpsObjects().size() == 1) {
|
|
|
+ int selectedValueX = (int) Math
|
|
|
+ .floor(xThis
|
|
|
+ / (model.getTableHolonElement()
|
|
|
+ .getWidth() / 7));
|
|
|
+ int selectedValueBX = (int) Math
|
|
|
+ .floor(xBThis
|
|
|
+ / (model.getTableHolonElement()
|
|
|
+ .getWidth() / 7));
|
|
|
+ if (updCon.getActualCps() != null
|
|
|
+ && updCon.getActualCps().getClass() == HolonObject.class) {
|
|
|
+ HolonElement eleTemp;
|
|
|
+
|
|
|
+ // For active column (boolean with a checkbox)
|
|
|
+ if (selectedValueBX == 5) {
|
|
|
+ eleTemp = updCon.getActualHolonElement(
|
|
|
+ (HolonObject) updCon.getActualCps(),
|
|
|
+ yBMouse, 0, tables);
|
|
|
+ String newBStuff = model
|
|
|
+ .getSingleTable()
|
|
|
+ .getValueAt(selectedValueBY,
|
|
|
+ selectedValueBX).toString();
|
|
|
+ Boolean bTemp = Boolean
|
|
|
+ .parseBoolean(newBStuff);
|
|
|
+ eleTemp.setActive(bTemp);
|
|
|
+
|
|
|
+ } // For activeFlex column (boolean with a
|
|
|
+ // checkbox)
|
|
|
+ else if (selectedValueBX == 6) {
|
|
|
+ eleTemp = updCon.getActualHolonElement(
|
|
|
+ (HolonObject) updCon.getActualCps(),
|
|
|
+ yBMouse, 0, tables);
|
|
|
+ String newBStuff = model
|
|
|
+ .getSingleTable()
|
|
|
+ .getValueAt(selectedValueBY,
|
|
|
+ selectedValueBX -1).toString();
|
|
|
+ eleTemp.setActive(Boolean
|
|
|
+ .parseBoolean(newBStuff));
|
|
|
+
|
|
|
+ } else {
|
|
|
+ //TODO check all possible assignements.
|
|
|
+ // Update of HolonElement
|
|
|
+ eleTemp = updCon.getActualHolonElement(
|
|
|
+ (HolonObject) updCon.getActualCps(),
|
|
|
+ yMouse, 0, tables);
|
|
|
+ String newStuff = model
|
|
|
+ .getSingleTable()
|
|
|
+ .getValueAt(selectedValueY,
|
|
|
+ selectedValueX).toString();
|
|
|
+ // Name update
|
|
|
+ if (selectedValueX == 1) {
|
|
|
+ eleTemp.setEleName(newStuff);
|
|
|
+ } // Energy Update
|
|
|
+ else if (selectedValueX == 2) {
|
|
|
+ Float ftemp = Float
|
|
|
+ .parseFloat(newStuff);
|
|
|
+ eleTemp.setEnergyPerElement(ftemp);
|
|
|
+ } // Flexibility
|
|
|
+ else if (selectedValueX == 3) {
|
|
|
+ }
|
|
|
+ // Amount of Elements update
|
|
|
+ else if (selectedValueX == 4) {
|
|
|
+ Integer iTemp = Integer
|
|
|
+ .parseInt(newStuff);
|
|
|
+ eleTemp.setAmount(iTemp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // set all cells anew, if anything was changed
|
|
|
+ updateElementTableAfterChange(eleTemp,
|
|
|
+ selectedValueBY);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ controller.calculateStateAndVisualForTimeStep(model
|
|
|
+ .getCurIteration());
|
|
|
+ model.getSingleTable().fireTableDataChanged();
|
|
|
+ triggerUpdateController(null);
|
|
|
+ contentPane.updateUI();
|
|
|
+ unitGraph.repaint();
|
|
|
+
|
|
|
+ // trigger update of table after UnitGraph was painted
|
|
|
+ SwingUtilities.invokeLater(() -> {
|
|
|
+ triggerUpdateController(null);
|
|
|
+ });
|
|
|
+ } catch (Exception e) {
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ /***********************
|
|
|
+ * 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.getObjName()) == 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;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * if in upperNode
|
|
|
+ */
|
|
|
+ if (x <= unc.upperNode.getLeftBorder()) return;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 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;
|
|
|
+
|
|
|
+ if (x > unc.upperNode.getLeftBorder()) {
|
|
|
+
|
|
|
+ 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.upperNode);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 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());
|
|
|
+ updCon.deleteRows(model.getSingleTable());
|
|
|
+ updCon.deleteRows(model.getMultiTable());
|
|
|
+ // 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
|
|
|
+ .getObjName()) == 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
|
|
|
+ .getObjName()) == 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("<html><b>New</b><br>Add a new Category or Item to the library.</html>");
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Update of every interaction between the user and the canvas (only on
|
|
|
+ * the canvas). Basically the update of all the information concerning
|
|
|
+ * the clicked HolonObject. For multi-selection, the propertyTable would
|
|
|
+ * be disabled
|
|
|
+ */
|
|
|
+ canvas.addMouseListener(new MouseAdapter() {
|
|
|
+ @Override
|
|
|
+ public void mousePressed(MouseEvent e) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mouseReleased(MouseEvent e) {
|
|
|
+ holonEleNamesDisplayed = "None";
|
|
|
+ // If any empty space is clicked
|
|
|
+ if (temp == null || temp.getId() != model.getSelectedObjectID()) {
|
|
|
+ hideScrollGraph();
|
|
|
+ elementGraph.setText("None");
|
|
|
+ }
|
|
|
+ temp = updCon.getActualCps();
|
|
|
+ // Erase old data in the PropertyTable
|
|
|
+ if (model.getPropertyTable().getRowCount() > 0) {
|
|
|
+ for (int i = model.getPropertyTable().getRowCount() - 1; i > -1; i--) {
|
|
|
+ model.getPropertyTable().removeRow(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (e.isControlDown() && temp != null) {
|
|
|
+ if (model.getSelectedCpsObjects().contains(temp)) {
|
|
|
+ controller.removeSelectedObjectFromSelection(temp);
|
|
|
+ } else {
|
|
|
+ controller.addSelectedObject(temp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (temp instanceof HolonSwitch) {
|
|
|
+ showScrollGraph();
|
|
|
+ updateUnitGraph((GraphEditable)temp);
|
|
|
+ }
|
|
|
+ // Write new data in the PropertyTable
|
|
|
+ triggerUpdateController(temp);
|
|
|
+
|
|
|
+ // New Tab with NodeOfNode
|
|
|
+ if (doubleClick() && MouseEvent.BUTTON3 != e.getButton()
|
|
|
+ && temp instanceof GroupNode) {
|
|
|
+ openNewUpperNodeTab();
|
|
|
+ try {
|
|
|
+ controller.autoSave();
|
|
|
+ } catch (IOException e1) {
|
|
|
+ e1.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (model.getSelectedCpsObjects().size() > 1) {
|
|
|
+ model.getTableHolonElement()
|
|
|
+ .setModel(model.getMultiTable());
|
|
|
+ } else if (model.getSelectedCpsObjects().size() == 1) {
|
|
|
+ model.getTableHolonElement().setModel(
|
|
|
+ model.getSingleTable());
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // 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("<html><b>Delete</b><br>Removes a Category or a Category Item.</html>");
|
|
|
+ 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();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ model.getEdgesOnCanvas().removeAll(model.getEdgesOnCanvas());
|
|
|
+ model.getObjectsOnCanvas().removeAll(model.getObjectsOnCanvas());
|
|
|
+ controller.setSelectedObjectID(0);
|
|
|
+ controller.setSelecteEdge(null);
|
|
|
+ controller.setCurIteration(0);
|
|
|
+ hideScrollGraph();
|
|
|
+ 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 {
|
|
|
+ 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();
|
|
|
+ hideScrollGraph();
|
|
|
+ } 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();
|
|
|
+ hideScrollGraph();
|
|
|
+ } 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.setDividerLocation(distanceBetweenElementsAndGraph);
|
|
|
+ splitGraphHolonEl.setTopComponent(scrollElements);
|
|
|
+ splitGraphHolonEl.setBottomComponent(scrollGraph);
|
|
|
+ canvasSP.setViewportView(canvas);
|
|
|
+
|
|
|
+ tabbedPaneOriginal.setBorder(null);
|
|
|
+ scrollProperties.setBorder(null);
|
|
|
+ scrollGraph.setBorder(null);
|
|
|
+ scrollElements.setBorder(null);
|
|
|
+ splitPane.setBorder(null);
|
|
|
+ splitPane1.setBorder(null);
|
|
|
+ splitHolonElPro.setBorder(null);
|
|
|
+ splitGraphHolonEl.setBorder(null);
|
|
|
+ panelHolonEl.setBorder(null);
|
|
|
+ canvasSP.setBorder(null);
|
|
|
+ hideScrollGraph();
|
|
|
+ tableHolonElementScrollPane.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<File> 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<Outliner> 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<FlexWindow> iter = flexList.listIterator();
|
|
|
+ while(iter.hasNext())
|
|
|
+ {
|
|
|
+ if(iter.next().isClosed) iter.remove();
|
|
|
+ }
|
|
|
+ //update open Flex
|
|
|
+ for(FlexWindow out : flexList) {
|
|
|
+ out.update();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private void showScrollGraph() {
|
|
|
+ scrollGraph.setVisible(true);
|
|
|
+ splitGraphHolonEl.setBottomComponent(scrollGraph);
|
|
|
+ splitGraphHolonEl.setDividerLocation(distanceBetweenElementsAndGraph);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void hideScrollGraph() {
|
|
|
+ scrollGraph.setVisible(false);
|
|
|
+ splitGraphHolonEl.remove(scrollGraph);
|
|
|
+ splitGraphHolonEl.setDividerLocation(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ 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<Category> 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.getObjName()));
|
|
|
+ }
|
|
|
+ add(node1);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ });
|
|
|
+ categoryTree.setModel(treemodel);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * When changes are made to the Categories.
|
|
|
+ *
|
|
|
+ * @param categories
|
|
|
+ * the Categories
|
|
|
+ */
|
|
|
+ public void updateCategoryUI(ArrayList<Category> categories) {
|
|
|
+ DefaultTreeModel model = (DefaultTreeModel) categoryTree.getModel();
|
|
|
+ updateCategories(categories);
|
|
|
+ model.reload();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Get the Frame.
|
|
|
+ *
|
|
|
+ * @return the Frame
|
|
|
+ */
|
|
|
+ JFrame getFrmCyberPhysical() {
|
|
|
+ return holegJFrame;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Checks if a double click was made.
|
|
|
+ *
|
|
|
+ * @return true if doublecklick, false if not
|
|
|
+ */
|
|
|
+ private boolean doubleClick() {
|
|
|
+ if (click) {
|
|
|
+ click = false;
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ click = true;
|
|
|
+ Timer t = new Timer("doubleclickTimer", false);
|
|
|
+ t.schedule(new TimerTask() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ click = false;
|
|
|
+ }
|
|
|
+ }, 350);
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Open a new Tab with an UpperNodeCanvas
|
|
|
+ */
|
|
|
+ private void openNewUpperNodeTab() {
|
|
|
+ chooseTabTemp();
|
|
|
+
|
|
|
+ JScrollPane scrollPane = getScrollPaneFromTabbedPane();
|
|
|
+ if (scrollPane.getViewport().getComponent(0) instanceof MyCanvas) {
|
|
|
+ unc = new GroupNodeCanvas(model, controller, unitGraph,
|
|
|
+ (GroupNode) temp, "", scrollPane.getViewport().getComponent(0));
|
|
|
+
|
|
|
+ } else {
|
|
|
+ unc = new GroupNodeCanvas(model, controller, unitGraph,
|
|
|
+ (GroupNode) temp, ((GroupNodeCanvas) scrollPane
|
|
|
+ .getViewport().getComponent(0)).path + " -> ", scrollPane.getViewport().getComponent(0));
|
|
|
+ }
|
|
|
+ unc.setShowedInformation(canvas.getShowedInformation());
|
|
|
+
|
|
|
+ // 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)).upperNode.getId() == temp.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 (tabbedPaneSplit.getTabCount() > 0) {
|
|
|
+ JTabbedPane tabbedPaneInnerSplit = (JTabbedPane) tabbedPaneSplit
|
|
|
+ .getComponentAt(0);
|
|
|
+ if (tabbedPaneInnerSplit != null) {
|
|
|
+ JScrollPane paneSplit = (JScrollPane) tabbedPaneInnerSplit
|
|
|
+ .getComponentAt(i);
|
|
|
+ if (!initSplit
|
|
|
+ && paneSplit != null
|
|
|
+ && ((GroupNodeCanvas) paneSplit.getViewport()
|
|
|
+ .getComponent(0)).upperNode.getId() == temp
|
|
|
+ .getId()) {
|
|
|
+ dupl = true;
|
|
|
+ // set selected component to view
|
|
|
+ tabbedPaneSplit
|
|
|
+ .setSelectedComponent(tabbedPaneInnerSplit);
|
|
|
+ // set selected tab in view to found upper-node-canvas
|
|
|
+ tabbedPaneInnerSplit
|
|
|
+ .setSelectedComponent(tabbedPaneInnerSplit
|
|
|
+ .getComponentAt(i));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // if we found a duplicate, break
|
|
|
+ if (dupl) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!dupl) {
|
|
|
+ unc.setBorder(null);
|
|
|
+ unc.setBackground(Color.WHITE);
|
|
|
+ unc.setPreferredSize(new Dimension(model.getCanvasX(), model
|
|
|
+ .getCanvasY()));
|
|
|
+
|
|
|
+ unc.addMouseListener(new MouseAdapter() {
|
|
|
+ @Override
|
|
|
+ public void mousePressed(MouseEvent e) {
|
|
|
+ hideScrollGraph();
|
|
|
+ holonEleNamesDisplayed = "None";
|
|
|
+ elementGraph.setText(holonEleNamesDisplayed);
|
|
|
+
|
|
|
+ chooseTabTemp();
|
|
|
+
|
|
|
+ JScrollPane scrollPane1 = getScrollPaneFromTabbedPane();
|
|
|
+ temp = ((GroupNodeCanvas) scrollPane1.getViewport()
|
|
|
+ .getComponent(0)).tempCps;
|
|
|
+ if (doubleClick() && MouseEvent.BUTTON3 != e.getButton()
|
|
|
+ && temp instanceof GroupNode) {
|
|
|
+ openNewUpperNodeTab();
|
|
|
+ }
|
|
|
+ if (temp instanceof HolonSwitch) {
|
|
|
+ updateUnitGraph((GraphEditable)temp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ JScrollPane sp = new JScrollPane(unc);
|
|
|
+ sp.setBorder(null);
|
|
|
+
|
|
|
+ // Selected tabbed Pane = tabbedPaneOriginal or tabbedPaneSplit
|
|
|
+ if (tabTemp == tabbedPaneOriginal) {
|
|
|
+ this.tabbedPaneInnerOriginal.add(temp.getName(), sp);
|
|
|
+ this.tabbedPaneInnerOriginal.setSelectedComponent(sp);
|
|
|
+ this.tabbedPaneInnerOriginal.setTabComponentAt(
|
|
|
+ this.tabbedPaneInnerOriginal.getTabCount() - 1,
|
|
|
+ new ButtonTabComponent(this.tabbedPaneInnerOriginal,
|
|
|
+ tabbedPaneSplit));
|
|
|
+
|
|
|
+ } else {
|
|
|
+ JTabbedPane tabbedPaneInnerSplit = (JTabbedPane) tabbedPaneSplit
|
|
|
+ .getComponentAt(0);
|
|
|
+ tabbedPaneInnerSplit.add(temp.getName(), sp);
|
|
|
+ Component tempC = tabbedPaneInnerSplit.getSelectedComponent();
|
|
|
+ tabbedPaneInnerSplit.setComponentAt(
|
|
|
+ tabbedPaneInnerSplit.getSelectedIndex(), null);
|
|
|
+ tabbedPaneOriginal.setComponentAt(
|
|
|
+ tabbedPaneInnerSplit.getSelectedIndex(), tempC);
|
|
|
+ tabbedPaneInnerSplit.setSelectedComponent(sp);
|
|
|
+
|
|
|
+ tabbedPaneInnerOriginal.add(temp.getName(), null);
|
|
|
+ tabbedPaneInnerOriginal.setTabComponentAt(
|
|
|
+ tabbedPaneInnerOriginal.getTabCount() - 1,
|
|
|
+ new ButtonTabComponent(tabbedPaneInnerOriginal,
|
|
|
+ tabbedPaneInnerSplit));
|
|
|
+ }
|
|
|
+
|
|
|
+ temp = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ 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).code);
|
|
|
+ ((GroupNodeCanvas) pane).upperNode = (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) {
|
|
|
+ boolean splitView = false;
|
|
|
+ for (int i = 1; i < tabbedPaneInnerOriginal.getTabCount(); i++) {
|
|
|
+ JScrollPane scrollPaneOriginal = (JScrollPane) tabbedPaneInnerOriginal
|
|
|
+ .getComponentAt(i);
|
|
|
+
|
|
|
+ if (scrollPaneOriginal == null) {
|
|
|
+ splitView = true;
|
|
|
+ } else if (((GroupNodeCanvas) scrollPaneOriginal.getViewport()
|
|
|
+ .getComponent(0)).upperNode.getId() == cps.getId()) {
|
|
|
+ ((ButtonTabComponent) tabbedPaneInnerOriginal
|
|
|
+ .getTabComponentAt(i)).removeTabs();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // If SplitView is on and the view on
|
|
|
+ // tabbedPaneSplit is the deleted upperNode
|
|
|
+ if (splitView && tabbedPaneSplit.getComponentCount() > 0) {
|
|
|
+ JTabbedPane tabbedPaneInnerSplit = (JTabbedPane) tabbedPaneSplit
|
|
|
+ .getComponentAt(0);
|
|
|
+
|
|
|
+ if (((GroupNodeCanvas) ((JScrollPane) tabbedPaneInnerSplit
|
|
|
+ .getSelectedComponent()).getViewport().getComponent(0)).upperNode
|
|
|
+ .getId() == cps.getId()) {
|
|
|
+ ((ButtonTabComponent) tabbedPaneInnerOriginal
|
|
|
+ .getTabComponentAt(tabbedPaneInnerSplit
|
|
|
+ .getSelectedIndex())).removeTabs();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * chooses whether to set the tabTemp to tabbedPaneOriginal or
|
|
|
+ * tabbedPaneSplit
|
|
|
+ */
|
|
|
+ private void chooseTabTemp() {
|
|
|
+ // is the uppernode on tabbedPaneOriginal or tabbedPaneSplit
|
|
|
+ /* TODO: Fix or Remove SplitView */
|
|
|
+ if (tabbedPaneOriginal.getMousePosition() != null || initSplit) {
|
|
|
+ tabTemp = tabbedPaneOriginal;
|
|
|
+ } else {
|
|
|
+ tabTemp = tabbedPaneSplit;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * if flexibility was turned on, then active needs to be turned off, the
|
|
|
+ * energy currently produced/consumed
|
|
|
+ *
|
|
|
+ * @param eleBTemp
|
|
|
+ * element that needs to be updated
|
|
|
+ * @param selectedValueBY
|
|
|
+ * the y value in the table
|
|
|
+ */
|
|
|
+ private void updateElementTableAfterChange(HolonElement eleBTemp,
|
|
|
+ int selectedValueBY) {
|
|
|
+// model.getSingleTable().setValueAt(false,
|
|
|
+// selectedValueBY, 6);
|
|
|
+ model.getSingleTable().setValueAt(eleBTemp.isActive(), selectedValueBY,
|
|
|
+ 5);
|
|
|
+ model.getSingleTable().setValueAt(eleBTemp.getAmount(),
|
|
|
+ selectedValueBY, 4);
|
|
|
+ model.getSingleTable().setValueAt(
|
|
|
+ controller.getSimManager().getActualFlexManager().isAFlexInUseOfHolonElement(eleBTemp),
|
|
|
+ selectedValueBY, 3);
|
|
|
+ model.getSingleTable().setValueAt(eleBTemp.getEnergyPerElement(),
|
|
|
+ selectedValueBY, 2);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void triggerUpdateController(AbstractCanvasObject temp) {
|
|
|
+ if(model != null) { return;}
|
|
|
+ if (temp != null) {
|
|
|
+ updCon.paintProperties(temp);
|
|
|
+ }
|
|
|
+ updCon.refreshTableHolonElement(model.getMultiTable(),
|
|
|
+ model.getSingleTable());
|
|
|
+ updCon.refreshTableProperties(model.getPropertyTable());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * This Method updates the UnitGraph, saves the old LocalModeState and load the new LocalModeState.
|
|
|
+ * @param element The new Element to load the UnitGraph
|
|
|
+ */
|
|
|
+ private void updateUnitGraph(GraphEditable element){
|
|
|
+ //SaveOld LocalMode State.
|
|
|
+ if(localPeriodInput.isVisible())
|
|
|
+ {
|
|
|
+ //Save Old State
|
|
|
+ validateInput(localPeriodInput.getEditor().getItem().toString(), false);
|
|
|
+ }
|
|
|
+ //Update UnitGraph
|
|
|
+ unitGraph.initNewElement(element);
|
|
|
+ //Load LocalMode State.
|
|
|
+ changeLocalPeriodButtonAppeareance(unitGraph.isUsingLocalPeriod());
|
|
|
+ localPeriodInput.getEditor().setItem(unitGraph.getLocalPeriod());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Displayed the actual LocalModeState.
|
|
|
+ * @param enabled
|
|
|
+ */
|
|
|
+ private void changeLocalPeriodButtonAppeareance(boolean enabled) {
|
|
|
+ localPeriodInput.setVisible(enabled);
|
|
|
+ if(enabled)
|
|
|
+ {
|
|
|
+ localPeriodButtonImage.setImage(ImageImport.loadImage("/Images/Graph.png"));
|
|
|
+ }else {
|
|
|
+ localPeriodButtonImage.setImage(GrayFilter.createDisabledImage(ImageImport.loadImage("/Images/Graph.png")));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * Validate the LocalMode Input and when its valid save on the Element.
|
|
|
+ * @param text the inputText to validate.
|
|
|
+ * @param bShowMessage when true, open a MessageDialog when text invalid.
|
|
|
+ */
|
|
|
+ private void validateInput(String text, boolean bShowMessage) {
|
|
|
+ int localPeriodInputValue;
|
|
|
+ try {
|
|
|
+ localPeriodInputValue = Integer.parseInt(text);
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ if(bShowMessage)
|
|
|
+ JOptionPane.showMessageDialog(contentPane, '"' +text + '"'+ " is not a valid Input. \n Use whole numbers.");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ unitGraph.setLocalPeriod(localPeriodInputValue);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void openWebpage(String URL){
|
|
|
+ try {
|
|
|
+ java.awt.Desktop.getDesktop().browse(new URI(URL));
|
|
|
+ } catch (IOException e1) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ e1.printStackTrace();
|
|
|
+ } catch (URISyntaxException e1) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ e1.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)).upperNode == null) {
|
|
|
+ ((ButtonTabComponent) tabbedPaneInnerOriginal
|
|
|
+ .getTabComponentAt(i)).removeTabs();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void repaintCanvas() {
|
|
|
+ tabbedPaneInnerOriginal.repaint();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 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)).upperNode != null) {
|
|
|
+ ((GroupNodeCanvas) scrollPaneOriginal.getViewport()
|
|
|
+ .getComponent(0)).disable = state;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|