private void initChangeListeners() {
   overlayCloseProperty()
       .addListener(
           (o, oldVal, newVal) -> {
             if (overlayPane != null) {
               if (newVal) overlayPane.addEventHandler(MouseEvent.MOUSE_PRESSED, closeHandler);
               else overlayPane.removeEventHandler(MouseEvent.MOUSE_PRESSED, closeHandler);
             }
           });
 }
  private void initialize() {
    this.setVisible(false);
    this.getStyleClass().add(DEFAULT_STYLE_CLASS);

    contentHolder = new StackPane();
    contentHolder.setBackground(
        new Background(new BackgroundFill(Color.WHITE, new CornerRadii(2), null)));
    JFXDepthManager.setDepth(contentHolder, 4);
    contentHolder.setPickOnBounds(false);
    // ensure stackpane is never resized beyond it's preferred size
    contentHolder.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
    overlayPane = new StackPane();
    overlayPane.getChildren().add(contentHolder);
    overlayPane.getStyleClass().add("jfx-dialog-overlay-pane");
    StackPane.setAlignment(contentHolder, Pos.CENTER);
    overlayPane.setVisible(false);
    overlayPane.setBackground(
        new Background(new BackgroundFill(Color.rgb(0, 0, 0, 0.1), null, null)));
    // close the dialog if clicked on the overlay pane
    if (overlayClose.get()) overlayPane.addEventHandler(MouseEvent.MOUSE_PRESSED, closeHandler);
    // prevent propagating the events to overlay pane
    contentHolder.addEventHandler(MouseEvent.ANY, (e) -> e.consume());
  }
  private static Node createHUBNode(HUB hubObject, Pane canvas, ContextMenu contextMenu) {
    // each hub is represented by a blue rectangle
    Rectangle node = new Rectangle(Data.nodeLength, Data.nodeWidth);
    node.setFill(Color.AQUAMARINE);

    // the hub name in the rectangle
    Label lnodeName = new Label(hubObject.getName());

    // this stackpane stack the label on top of the rectangle to make them
    // one entity
    StackPane nodeContainer = new StackPane();
    nodeContainer.getChildren().addAll(node, lnodeName);
    nodeContainer.relocate(hubObject.getPosX(), hubObject.getPosY());

    // add a popover when one of the hub is clicked
    nodeContainer.addEventHandler(
        MouseEvent.MOUSE_CLICKED,
        new EventHandler<MouseEvent>() {
          @Override
          public void handle(MouseEvent event) {
            if (event.getButton() == MouseButton.PRIMARY) {
              PopOver popOver =
                  new PopOver(createHUBPopOverContent(hubObject, canvas, contextMenu));
              popOver.setDetachable(false);
              popOver.show(nodeContainer);
              popOver.setOnHiding(
                  new EventHandler<WindowEvent>() {
                    @Override
                    public void handle(WindowEvent e) {
                      hubNodeHidingListener(popOver, hubObject, canvas, contextMenu);
                    }
                  });
            }
            if (event.getButton() == MouseButton.SECONDARY) {
              // if user right click on a HUB then enable the "delete"
              // menu
              contextMenu.getItems().get(2).setDisable(false);
              // when user select an object to delete
              contextMenu
                  .getItems()
                  .get(2)
                  .setOnAction(
                      new EventHandler<ActionEvent>() {
                        @Override
                        public void handle(ActionEvent e) {
                          String hubName = hubObject.getName();
                          TreeSet<String> interfaces = hubObject.getInfs();
                          for (String inf : interfaces) {
                            Pattern pat = Pattern.compile(Data.hubInfPattern);
                            Matcher matcher = pat.matcher(inf);
                            // delete the VM interface that is connected to
                            // the hub
                            if (matcher.find()) {
                              String vmName = matcher.group(1);
                              String vmEth = matcher.group(2);
                              Data.vmMap.get(vmName).removeInf(vmEth);
                            }
                          }
                          // delete the hub
                          Data.hubMap.remove(hubName);
                          draw(canvas, contextMenu);
                        }
                      });
              // disable the "delete option when the popover closes"
              contextMenu.setOnHidden(
                  new EventHandler<WindowEvent>() {
                    @Override
                    public void handle(WindowEvent e) {
                      contextMenu.getItems().get(2).setDisable(true);
                    }
                  });
            }
          }
        });

    return nodeContainer;
  }
  private static Node createVMNode(VM vmObject, Pane canvas, ContextMenu contextMenu) {
    // each vm is represented by a red rectangle
    Rectangle node = new Rectangle(Data.nodeLength, Data.nodeWidth);
    node.setFill(Color.RED);

    // the hub name in the rectangle
    Label lnodeName = new Label(vmObject.getName());

    // this stackpane stack the label on top of the rectangle to make them
    // one entity
    StackPane nodeContainer = new StackPane();
    nodeContainer.getChildren().addAll(node, lnodeName);
    nodeContainer.relocate(vmObject.getPosX(), vmObject.getPosY());

    // add a popover when one of the hub is clicked
    nodeContainer.addEventHandler(
        MouseEvent.MOUSE_CLICKED,
        new EventHandler<MouseEvent>() {
          @Override
          public void handle(MouseEvent event) {
            if (event.getButton() == MouseButton.PRIMARY) {
              PopOver popOver = new PopOver(createVMPopOverContent(vmObject, canvas, contextMenu));
              popOver.setDetachable(false);
              popOver.show(nodeContainer);
              popOver.setOnHiding(
                  new EventHandler<WindowEvent>() {
                    @Override
                    public void handle(WindowEvent e) {
                      vmNodeHidingListener(popOver, vmObject, canvas, contextMenu);
                    }
                  });
            } else if (event.getButton() == MouseButton.SECONDARY) {
              System.out.println(Data.vmMap);
              // if user right click on a HUB then enable the "delete"
              // menu
              contextMenu.getItems().get(2).setDisable(false);
              // when user select an object to delete
              contextMenu
                  .getItems()
                  .get(2)
                  .setOnAction(
                      new EventHandler<ActionEvent>() {
                        @Override
                        public void handle(ActionEvent e) {
                          System.out.println("Delete is clicked");
                          String vmName = vmObject.getName();
                          LinkedHashMap<String, HUB> tempHubMap = Data.hubMap;
                          // look in every hubObject
                          for (Map.Entry<String, HUB> hubEntry : tempHubMap.entrySet()) {
                            TreeSet<String> hubInf =
                                tempHubMap.get(hubEntry.getValue().getName()).getInfs();
                            Pattern pat = Pattern.compile(Data.hubInfPattern);
                            boolean deleteInf = false;
                            ArrayList<String> toRemove = new ArrayList<String>();
                            // look in each hubInf
                            for (String inf : hubInf) {
                              Matcher matcher = pat.matcher(inf);
                              if (matcher.find()) {
                                if (matcher.group(1).toLowerCase().equals(vmName.toLowerCase())) {
                                  toRemove.add(inf);
                                  deleteInf = true;
                                }
                              }
                            }
                            System.out.println(toRemove);
                            if (deleteInf == true) {
                              for (String item : toRemove) {
                                Data.hubMap.get(hubEntry.getValue().getName()).removeInf(item);
                              }
                            }
                          }
                          // delete the vm
                          Data.vmMap.remove(vmName);
                          draw(canvas, contextMenu);
                        }
                      });
              // disable the "delete option when the popover closes"
              contextMenu.setOnHidden(
                  new EventHandler<WindowEvent>() {
                    @Override
                    public void handle(WindowEvent e) {
                      contextMenu.getItems().get(2).setDisable(true);
                    }
                  });
            }
          }
        });
    return nodeContainer;
  }