public void readPDB(String file) {
    PDBIterator iterator = new PDBIterator(file);
    residueList = new ArrayList<>();
    while (iterator.hasNext()) residueList.add(iterator.next());

    Residue lastResidue = null;
    for (Residue res : residueList) {
      Tooltip tip = new Tooltip(res.getId());
      Tooltip.install(res.getPhosphorRepresentation(), tip);
      Tooltip.install(res.getSugarRepresentation(), tip);
      Tooltip.install(res.getBaseRepresentation(), tip);
      root.pdbObjects.getChildren().add(res.getBaseRepresentation());
      root.pdbObjects.getChildren().add(res.getSugarRepresentation());
      root.pdbObjects.getChildren().add(res.getConnection());
      root.pdbObjects.getChildren().add(res.getPhosphorRepresentation());
      root.pdbObjects.getChildren().add(res.getConnectionPhosphor());

      if (lastResidue != null && Math.abs(lastResidue.getPosition() - res.getPosition()) == 1) {
        root.pdbObjects
            .getChildren()
            .add(Residue.createConnection(lastResidue.getPhosphor(), res.getPhosphor(), 0.3));
      }

      lastResidue = res;
    }

    centerResidues();
    colorNucleotides();

    worldRotateY = new Rotate(0, 0, 0, 0, Rotate.Y_AXIS);
    worldRotateZ = new Rotate(0, 0, 0, 0, Rotate.Z_AXIS);

    root.pdbObjects.getTransforms().addAll(worldRotateY, worldRotateZ);
  }
Beispiel #2
0
 private void setTooltip() {
   Tooltip.uninstall(this, tooltip);
   tooltip =
       new Tooltip(
           NbBundle.getMessage(
               this.getClass(), "Timeline.ui.detailview.tooltip.text", formatSpan(getDateTime())));
   Tooltip.install(this, tooltip);
 }
  private void configureCountryImageView() {
    setCountry(playerInfoBean.getCountry());

    Tooltip countryTooltip = new Tooltip(playerInfoBean.getCountry());
    countryTooltip.textProperty().bind(playerInfoBean.countryProperty());

    Tooltip.install(countryImageView, countryTooltip);
  }
 private Candle(String seriesStyleClass, String dataStyleClass) {
   setAutoSizeChildren(false);
   getChildren().addAll(highLowLine, bar);
   this.seriesStyleClass = seriesStyleClass;
   this.dataStyleClass = dataStyleClass;
   updateStyleClasses();
   tooltip.setGraphic(new TooltipContent());
   Tooltip.install(bar, tooltip);
 }
Beispiel #5
0
 /**
  * Changes the tooltip of this {@link NodeContentPart} to the given value.
  *
  * @param visual The visual of this {@link NodeContentPart}.
  * @param tooltip The new tooltip for this {@link NodeContentPart}.
  */
 protected void refreshTooltip(Group visual, Object tooltip) {
   if (tooltip instanceof String) {
     if (tooltipNode == null) {
       tooltipNode = new Tooltip((String) tooltip);
       Tooltip.install(visual, tooltipNode);
     } else {
       tooltipNode.setText((String) tooltip);
     }
   }
 }
  @FXML
  void onMouseEnterGameStatus() {
    if (playerInfoBean.getGameStatus() == GameStatus.NONE) {
      return;
    }

    GameStatusTooltipController gameStatusTooltipController =
        applicationContext.getBean(GameStatusTooltipController.class);
    gameStatusTooltipController.setGameInfoBean(gameService.getByUid(playerInfoBean.getGameUid()));

    Tooltip statusTooltip = new Tooltip();
    statusTooltip.setGraphic(gameStatusTooltipController.getRoot());
    Tooltip.install(statusImageView, statusTooltip);
  }
  private void configureAvatarImageView() {
    playerInfoBean
        .avatarUrlProperty()
        .addListener(
            (observable, oldValue, newValue) -> {
              Platform.runLater(() -> setAvatarUrl(newValue));
            });
    setAvatarUrl(playerInfoBean.getAvatarUrl());

    Tooltip avatarTooltip = new Tooltip(playerInfoBean.getAvatarTooltip());
    avatarTooltip.textProperty().bind(playerInfoBean.avatarTooltipProperty());
    avatarTooltip.setAnchorLocation(PopupWindow.AnchorLocation.CONTENT_TOP_LEFT);

    Tooltip.install(avatarImageView, avatarTooltip);
  }
 /**
  * Sets the tooltip text, with the (x, y) location being used for the anchor. If the text is
  * {@code null}, no tooltip will be displayed. This method is intended for calling by the {@link
  * TooltipHandlerFX} class, you won't normally call it directly.
  *
  * @param text the text ({@code null} permitted).
  * @param x the x-coordinate of the mouse pointer.
  * @param y the y-coordinate of the mouse pointer.
  */
 public void setTooltip(String text, double x, double y) {
   if (text != null) {
     if (this.tooltip == null) {
       this.tooltip = new Tooltip(text);
       Tooltip.install(this, this.tooltip);
     } else {
       this.tooltip.setText(text);
       this.tooltip.setAnchorX(x);
       this.tooltip.setAnchorY(y);
     }
   } else {
     Tooltip.uninstall(this, this.tooltip);
     this.tooltip = null;
   }
 }
 /*     */ public void setTooltip(String paramString) /*     */ {
   /*  58 */ WebView localWebView = this.accessor.getView();
   /*  59 */ if (paramString != null) {
     /*  60 */ if (this.tooltip == null) /*  61 */ this.tooltip = new Tooltip(paramString);
     /*     */ else {
       /*  63 */ this.tooltip.setText(paramString);
       /*     */ }
     /*  65 */ if (!this.isTooltipRegistered) {
       /*  66 */ Tooltip.install(localWebView, this.tooltip);
       /*  67 */ this.isTooltipRegistered = true;
       /*     */ }
     /*  69 */ } else if (this.isTooltipRegistered) {
     /*  70 */ Tooltip.uninstall(localWebView, this.tooltip);
     /*  71 */ this.isTooltipRegistered = false;
     /*     */ }
   /*     */ }
  public TextFieldWithCopyIcon() {
    Label copyIcon = new Label();
    copyIcon.setLayoutY(3);
    copyIcon.getStyleClass().add("copy-icon");
    Tooltip.install(copyIcon, new Tooltip("Copy to clipboard"));
    AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
    AnchorPane.setRightAnchor(copyIcon, 0.0);
    copyIcon.setOnMouseClicked(
        e -> {
          String text = getText();
          if (text != null && text.length() > 0) {
            String copyText;
            if (copyWithoutCurrencyPostFix) {
              String[] strings = text.split(" ");
              if (strings.length > 1) copyText = strings[0]; // exclude the BTC postfix
              else copyText = text;
            } else {
              copyText = text;
            }
            Utilities.copyToClipboard(copyText);
          }
        });
    textField = new TextField();
    textField.setEditable(false);
    textField.textProperty().bindBidirectional(text);
    AnchorPane.setRightAnchor(copyIcon, 5.0);
    AnchorPane.setRightAnchor(textField, 30.0);
    AnchorPane.setLeftAnchor(textField, 0.0);
    textField.focusTraversableProperty().set(focusTraversableProperty().get());
    // TODO app wide focus
    // focusedProperty().addListener((ov, oldValue, newValue) -> textField.requestFocus());

    getChildren().addAll(textField, copyIcon);
  }
 /**
  * @param node
  * @return
  */
 public static Tooltip create(Node node) {
   Tooltip tooltip = new Tooltip();
   node.setOnMouseEntered(
       (MouseEvent event) -> {
         Point2D p =
             node.localToScreen(
                 node.getLayoutBounds().getMaxX() / 2,
                 node.getLayoutBounds().getMaxY()
                     + 5); // I position the tooltip at bottom right of the node (see below for
         // explanation)
         tooltip.show(node, p.getX(), p.getY());
       });
   node.setOnMouseExited(
       (MouseEvent event) -> {
         tooltip.hide();
       });
   return tooltip;
 }
  private void configureRatingTooltip() {
    if (!playerInfoBean.getChatOnly()) {
      Tooltip userRatingTooltip = new Tooltip();

      String rating =
          i18n.get(
              "userInfo.ratingFormat",
              RatingUtil.getRoundedGlobalRating(playerInfoBean),
              RatingUtil.getLeaderboardRating(playerInfoBean));
      userRatingTooltip.setText(rating);

      addRatingListenerToTooltip(playerInfoBean.leaderboardRatingMeanProperty(), userRatingTooltip);
      addRatingListenerToTooltip(playerInfoBean.globalRatingMeanProperty(), userRatingTooltip);

      Tooltip.install(clanLabel, userRatingTooltip);
      Tooltip.install(usernameLabel, userRatingTooltip);
    }
  }
  public View23D() {
    this.setAlignment(Pos.CENTER);
    this.setPadding(new Insets(20));

    camera = new PerspectiveCamera();
    camera.setNearClip(0.1);
    camera.setFarClip(10000);
    camera.setTranslateX(0);
    camera.setTranslateY(0);
    camera.setTranslateZ(-500);

    sphere1 = createSphere(Color.BLUE);
    Tooltip.install(sphere1, new Tooltip("A Blue Sphere"));

    sphere2 = createSphere(Color.YELLOWGREEN);
    sphere2.setTranslateX(200);
    sphere2.setTranslateY(200);
    Tooltip.install(sphere2, new Tooltip("A Yellowgreen Sphere"));

    cylinder = createCylinder(Color.BLANCHEDALMOND);
    cylinder.setTranslateY(90);
    cylinder.setTranslateX(90);
    cylinder.setRotate(-45);
    Tooltip.install(cylinder, new Tooltip("A ??? Cylinder"));

    clickMe1 = new Button("Click Me!");
    clickMe1.setTranslateX(200);

    t3dobjects = new Group();

    t3dobjects.getChildren().addAll(sphere1, cylinder, sphere2, clickMe1);

    threeD = new SubScene(t3dobjects, 600, 600, true, SceneAntialiasing.BALANCED);
    t3dobjects.setTranslateX(200);
    t3dobjects.setTranslateY(200);

    topPane = new Pane();
    topPane.setPickOnBounds(false);

    clickMe2 = new Button("Click Me 2!");

    this.getChildren().addAll(threeD, topPane);
    // this.setAlignment(Pos.CENTER);
  }
 private void addRatingListenerToTooltip(FloatProperty ratingProperty, Tooltip tooltip) {
   ratingProperty.addListener(
       (observable, oldValue, newValue) -> {
         String updatedRating =
             i18n.get(
                 "userInfo.ratingFormat",
                 RatingUtil.getGlobalRating(playerInfoBean),
                 RatingUtil.getLeaderboardRating(playerInfoBean));
         tooltip.setText(updatedRating);
       });
 }
 // Explicit implementation of readObject, but called implicitly as a result of recursive calls to
 // readObject() based on Serializable interface
 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
   name = new SimpleStringProperty((String) in.readObject());
   strength = new SimpleDoubleProperty(in.readDouble());
   health = new SimpleDoubleProperty(in.readDouble());
   speed = new SimpleDoubleProperty(in.readDouble());
   createAvatar();
   getAvatar().setTranslateX(in.readDouble());
   getAvatar().setTranslateY(in.readDouble());
   tooltip = new Tooltip(toString());
   Tooltip.install(getAvatar(), tooltip);
   resetAvatarAttributes();
 } // end readObject() to support serialization
  private void load() {
    lName.setText(pipeline.getPipeline().getAbsolutePath());
    Tooltip.install(lName, new Tooltip(pipeline.getPipeline().getAbsolutePath()));

    Tooltip.install(bConfigure, new Tooltip("Configure"));
    bConfigure.setOnMouseClicked(
        (e) -> {
          try {
            Window<Parent, ?> window = new Window<>((Parent) null, "Configure");

            Parent root =
                (Parent) FXMLConfigurePipelineController.mount(new Data(pipeline, window::close));

            window.setRoot(root);

            window.open();
          } catch (ComponentException ex) {
            Dialog.showError("Error loading configuration widow!");
          }
        });
    new ButtonMagnifier<>(bConfigure).mount();
  }
Beispiel #17
0
  public void addImageTab(Path imagePath) {

    TabPane previewTabPane = controller.getPreviewTabPane();

    ImageTab tab = new ImageTab();
    tab.setPath(imagePath);
    tab.setText(imagePath.getFileName().toString());

    if (previewTabPane.getTabs().contains(tab)) {
      previewTabPane.getSelectionModel().select(tab);
      return;
    }

    Image image = new Image(IOHelper.pathToUrl(imagePath));
    ImageView imageView = new ImageView(image);
    imageView.setPreserveRatio(true);

    imageView.setFitWidth(previewTabPane.getWidth());

    previewTabPane
        .widthProperty()
        .addListener(
            (observable, oldValue, newValue) -> {
              imageView.setFitWidth(previewTabPane.getWidth());
            });

    Tooltip tip = new Tooltip(imagePath.toString());
    Tooltip.install(tab.getGraphic(), tip);

    ScrollPane scrollPane = new ScrollPane();
    scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
    scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
    scrollPane.setContent(imageView);
    scrollPane.addEventFilter(
        ScrollEvent.SCROLL,
        e -> {
          if (e.isControlDown() && e.getDeltaY() > 0) {
            // zoom in
            imageView.setFitWidth(imageView.getFitWidth() + 16.0);
          } else if (e.isControlDown() && e.getDeltaY() < 0) {
            // zoom out
            imageView.setFitWidth(imageView.getFitWidth() - 16.0);
          }
        });

    tab.setContent(scrollPane);

    TabPane tabPane = previewTabPane;
    tabPane.getTabs().add(tab);
    tabPane.getSelectionModel().select(tab);
  }
  public void createNodes(Graph graph, double[][] coordinates) {
    nodeArray = new ArrayList<>();
    double radius = graph.getNumberOfNodes() < 25 ? 100 / graph.getNumberOfNodes() : 4;
    for (int i = 0; i < coordinates.length; i++) {
      Circle nodeI = new Circle(radius);
      nodeI.setTranslateX(coordinates[i][0]);
      nodeI.setTranslateY(coordinates[i][1]);
      Tooltip tip =
          new Tooltip("node number " + (i + 1) + ", \"" + root.sequence.getText().charAt(i) + "\"");
      Tooltip.install(nodeI, tip);
      nodeI.setId(root.sequence.getText().substring(i, i + 1));
      Timeline timeline = new Timeline();

      nodeI.setOnMouseDragged(
          event -> {
            nodeI.setTranslateX(event.getSceneX() - root.nodes.getLayoutX());
            nodeI.setTranslateY(event.getSceneY() - root.nodes.getLayoutY());
          });
      final int finalI = i;
      nodeI.setOnMouseReleased(
          event -> {
            double[][] newCoordinates =
                SpringEmbedder.computeSpringEmbedding(
                    100, graph.getNumberOfNodes(), graph.getEdges(), null);
            SpringEmbedder.centerCoordinates(
                newCoordinates,
                0,
                (int) root.getWidth(),
                20,
                (int) (root.getHeight() - root.vbox.getHeight() * 1.5));
            timeline
                .getKeyFrames()
                .add(
                    new KeyFrame(
                        Duration.millis(200),
                        new KeyValue(nodeI.translateXProperty(), coordinates[finalI][0])));
            timeline
                .getKeyFrames()
                .add(
                    new KeyFrame(
                        Duration.millis(200),
                        new KeyValue(nodeI.translateYProperty(), coordinates[finalI][1])));
            timeline.play();
          });

      nodeI.disableProperty().bind(Bindings.not(root.animate.selectedProperty()));
      root.nodes.getChildren().add(nodeI);
      nodeArray.add(nodeI);
    }
  }
Beispiel #19
0
  private void drawSections() {
    if (sections.isEmpty()) return;
    sectionLayer.getChildren().clear();

    double centerX = width * 0.5;
    double centerY = height * 0.85;
    double barRadius = height * 0.54210526;
    double barWidth = width * 0.28472222;

    for (Section section : sections) {
      Arc sectionBar =
          new Arc(
              centerX,
              centerY,
              barRadius,
              barRadius,
              angleRange * 0.5 + 90 - (section.getStart() * angleStep),
              -((section.getStop() - section.getStart()) - minValue) * angleStep);
      sectionBar.setType(ArcType.OPEN);
      sectionBar.setStroke(section.getColor());
      sectionBar.setStrokeWidth(barWidth);
      sectionBar.setStrokeLineCap(StrokeLineCap.BUTT);
      sectionBar.setFill(null);
      Tooltip sectionTooltip =
          new Tooltip(
              new StringBuilder(section.getText())
                  .append("\n")
                  .append(String.format(Locale.US, "%.2f", section.getStart()))
                  .append(" - ")
                  .append(String.format(Locale.US, "%.2f", section.getStop()))
                  .toString());
      sectionTooltip.setTextAlignment(TextAlignment.CENTER);
      Tooltip.install(sectionBar, sectionTooltip);
      sectionLayer.getChildren().add(sectionBar);
    }
  }
  private void markNodeAsInvalid(Node node) {
    TreeItem<Node> invalidItem = findItem(node);

    if (invalidItem != null) {
      ImageView exclaimImage = new ImageView("/images/red_exclamation.png");
      exclaimImage.setFitHeight(20);
      exclaimImage.setFitWidth(5);

      Tooltip exclaimTooltip =
          new Tooltip(TextFactory.getText(Labels.LabelKey.PROPERTY_MISSING_LABEL));
      Tooltip.install(exclaimImage, exclaimTooltip);

      invalidItem.setGraphic(exclaimImage);
    }
  }
 /**
  * <i>Actor</i> constructor is used when building <i>Actor</i> objects automatically:
  * <i>strength</i>, <i>health</i>, <i>speed</i> fields are given randomly generated values within
  * their range; <i>name</i> is given a sequentially numbered name: <i>Auto:<b>n</b></i> where
  * <i><b>n</b></i> is the sequence number. The <i>name</i> can be edited to create an unique
  * <i>Actor</i>.
  *
  * @param subclassCount used to support automatic naming (which includes a unique serial number).
  * @param armyAllegiance used to support the <i>Army</i>-specific <i>DropShadow</i> glow around
  *     this Actor object.
  */
 public Actor(int subclassCount, Army armyAllegiance) {
   this.armyAllegiance = armyAllegiance;
   ++actorSerialNumber; // static class-oriented variable. There is one-and-only-one instance of
                        // this variable regardless of the number of Actor objects in existence
                        // (from none to infinity).
   setName(
       String.format(
           "%d:%s:%d:",
           actorSerialNumber,
           getClass().getSimpleName(),
           subclassCount)); // An alternate way to assemble a String to use as a name. Because of
                            // polymorphism "getClass().getName()" will return the subclass name
                            // when they exist.
   setStrength(SingletonRandom.instance.getNormalDistribution(MIN_STRENGTH, MAX_STRENGTH, 2.0));
   setHealth(SingletonRandom.instance.getNormalDistribution(MIN_HEALTH, MAX_HEALTH, 2.0));
   setSpeed(SingletonRandom.instance.getNormalDistribution(MIN_SPEED, MAX_SPEED, 2.0));
   createAvatar();
   tooltip = new Tooltip(toString());
   Tooltip.install(getAvatar(), tooltip);
   tt = new TranslateTransition();
   tt.setNode(getAvatar()); // reuse
 } // end Actor constructor
Beispiel #22
0
 private void handleEvents(final String EVENT_TYPE) {
   if ("RESIZE".equals(EVENT_TYPE)) {
     resize();
     redraw();
   } else if ("REDRAW".equals(EVENT_TYPE)) {
     redraw();
   } else if ("RECALC".equals(EVENT_TYPE)) {
     angleRange = Helper.clamp(90.0, 180.0, getSkinnable().getAngleRange());
     startAngle = getStartAngle();
     minValue = getSkinnable().getMinValue();
     range = getSkinnable().getRange();
     sections = getSkinnable().getSections();
     angleStep = angleRange / range;
     redraw();
   } else if ("FINISHED".equals(EVENT_TYPE)) {
     needleTooltip.setText(String.format(locale, formatString, getSkinnable().getValue()));
     double value = getSkinnable().getValue();
     if (getSkinnable().isValueVisible()) {
       Bounds bounds = pane.localToScreen(pane.getBoundsInLocal());
       double xFactor = value > getSkinnable().getRange() * 0.8 ? 0.0 : 0.25;
       double tooltipAngle = value * angleStep;
       double sinValue = Math.sin(Math.toRadians(180 + angleRange * 0.5 - tooltipAngle));
       double cosValue = Math.cos(Math.toRadians(180 + angleRange * 0.5 - tooltipAngle));
       double needleTipX =
           bounds.getMinX() + bounds.getWidth() * 0.5 + bounds.getHeight() * sinValue;
       double needleTipY =
           bounds.getMinY() + bounds.getHeight() * 0.72 + bounds.getHeight() * cosValue;
       needleTooltip.show(needle, needleTipX, needleTipY);
       needleTooltip.setAnchorX(needleTooltip.getX() - needleTooltip.getWidth() * xFactor);
     }
     if (sections.isEmpty() || sectionsAlwaysVisible) return;
     for (Section section : sections) {
       if (section.contains(value)) {
         barTooltip.setText(section.getText());
         break;
       }
     }
   } else if ("VISIBILITY".equals(EVENT_TYPE)) {
     Helper.enableNode(titleText, !getSkinnable().getTitle().isEmpty());
   }
 }
 public MenuItemBuilt tip(String tipText) {
   Tooltip tooltip = new Tooltip(tipText);
   Tooltip.install(menuItem.getGraphic(), tooltip);
   return this;
 }
 public void resetAvatarAttributes() {
   tooltip.setText(toString());
 } // Note: This updates the text in the Tooltip that was installed earlier. We re-use the
Beispiel #25
0
  /**
   * Drawing function for Circles and Lines
   *
   * @param drawPane
   * @param coords Circle Coordinates
   * @param edges array of edges
   * @param startIndex NumberOfNodes
   */
  private void drawShapes(Pane drawPane, double[][] coords, int[][] edges, int startIndex) {

    // clear previous pane
    drawPane.getChildren().clear();
    circleList = new ArrayList<>();

    // generate Circles
    for (int i = 0; i < coords.length; i++) {
      Circle currentCircle = new Circle(coords[i][0], coords[i][1], nodeSize, Color.BLACK);
      String toolTipText = "Node " + Integer.toString(i + 1);
      // expand toolTip text with nucleotide and Circle color, if possible
      if (sequenceField.getText().length() > i) {
        toolTipText += ": " + sequenceField.getText().charAt(i);
        currentCircle.setFill(getNodeColor(sequenceField.getText().charAt(i)));
      }
      Tooltip.install(currentCircle, new Tooltip(toolTipText));
      if (isAnimated) {
        currentCircle.setOnMousePressed(circleOnMousePressedEventHandler);
        currentCircle.setOnMouseDragged(circleOnMouseDraggedEventHandler);
        currentCircle.setOnMouseReleased(circleOnMouseReleasedEventHandler);
      }

      circleList.add(currentCircle);
    }

    // generate  basic Lines
    ArrayList<Line> lineList = new ArrayList<>();
    for (int i = 0; i < circleList.size() - 1; i++) {
      Line line = new Line();
      line.setStroke(Color.BLACK);
      line.setFill(Color.BLACK);
      Circle circle1 = circleList.get(i);
      Circle circle2 = circleList.get(i + 1);

      // bind ends of line:
      line.startXProperty().bind(circle1.centerXProperty().add(circle1.translateXProperty()));
      line.startYProperty().bind(circle1.centerYProperty().add(circle1.translateYProperty()));
      line.endXProperty().bind(circle2.centerXProperty().add(circle2.translateXProperty()));
      line.endYProperty().bind(circle2.centerYProperty().add(circle2.translateYProperty()));

      lineList.add(line);
    }

    // generate edges
    for (int i = startIndex - 1; i < edges.length; i++) {
      Line line = new Line();
      line.setStroke(Color.ORANGE);
      Circle circle1 = circleList.get(edges[i][0]);
      Circle circle2 = circleList.get(edges[i][1]);

      line.startXProperty().bind(circle1.centerXProperty().add(circle1.translateXProperty()));
      line.startYProperty().bind(circle1.centerYProperty().add(circle1.translateYProperty()));
      line.endXProperty().bind(circle2.centerXProperty().add(circle2.translateXProperty()));
      line.endYProperty().bind(circle2.centerYProperty().add(circle2.translateYProperty()));

      lineList.add(line);
    }

    drawPane.getChildren().addAll(lineList);
    drawPane.getChildren().addAll(circleList);
  }
Beispiel #26
0
  public void addTab(Path path, Runnable... runnables) {

    ObservableList<String> recentFiles = controller.getRecentFilesList();
    if (Files.notExists(path)) {
      recentFiles.remove(path.toString());
      return;
    }

    ObservableList<Tab> tabs = controller.getTabPane().getTabs();
    for (Tab tab : tabs) {
      MyTab myTab = (MyTab) tab;
      Path currentPath = myTab.getPath();
      if (Objects.nonNull(currentPath))
        if (currentPath.equals(path)) {
          myTab.select(); // Select already added tab
          return;
        }
    }

    AnchorPane anchorPane = new AnchorPane();
    EditorPane editorPane = webviewService.createWebView();

    MyTab tab = createTab();
    tab.setEditorPane(editorPane);
    tab.setTabText(path.getFileName().toString());

    editorPane.confirmHandler(
        param -> {
          if ("command:ready".equals(param)) {
            JSObject window = editorPane.getWindow();
            window.setMember("afx", controller);
            window.call("updateOptions", new Object[] {});
            Map<String, String> shortCuts = controller.getShortCuts();
            Set<String> keySet = shortCuts.keySet();
            for (String key : keySet) {
              window.call("addNewCommand", new Object[] {key, shortCuts.get(key)});
            }
            if (Objects.isNull(path)) return true;
            threadService.runTaskLater(
                () -> {
                  String content = IOHelper.readFile(path);
                  threadService.runActionLater(
                      () -> {
                        window.call("changeEditorMode", path.toUri().toString());
                        window.call("setInitialized");
                        window.call("setEditorValue", new Object[] {content});
                        for (Runnable runnable : runnables) {
                          runnable.run();
                        }
                      });
                });
          }
          return false;
        });

    threadService.runActionLater(
        () -> {
          TabPane tabPane = controller.getTabPane();
          tabPane.getTabs().add(tab);
          tab.select();
        });

    Node editorVBox = editorService.createEditorVBox(editorPane, tab);
    controller.fitToParent(editorVBox);

    anchorPane.getChildren().add(editorVBox);
    tab.setContent(anchorPane);
    tab.setPath(path);

    Tooltip tip = new Tooltip(path.toString());
    Tooltip.install(tab.getGraphic(), tip);

    recentFiles.remove(path.toString());
    recentFiles.add(0, path.toString());

    editorPane.focus();
  }
  /** Create and initialise the song panel. */
  public BasicSongPanel() {
    final VBox centrePanel = new VBox();
    transposeDialog = new TransposeDialog();
    GridPane topPanel = new GridPane();

    titleField = new TextField();
    GridPane.setHgrow(titleField, Priority.ALWAYS);
    Label titleLabel = new Label(LabelGrabber.INSTANCE.getLabel("title.label"));
    GridPane.setConstraints(titleLabel, 1, 1);
    topPanel.getChildren().add(titleLabel);
    titleLabel.setLabelFor(titleField);
    GridPane.setConstraints(titleField, 2, 1);
    topPanel.getChildren().add(titleField);

    authorField = new TextField();
    GridPane.setHgrow(authorField, Priority.ALWAYS);
    Label authorLabel = new Label(LabelGrabber.INSTANCE.getLabel("author.label"));
    GridPane.setConstraints(authorLabel, 1, 2);
    topPanel.getChildren().add(authorLabel);
    authorLabel.setLabelFor(authorField);
    GridPane.setConstraints(authorField, 2, 2);
    topPanel.getChildren().add(authorField);

    centrePanel.getChildren().add(topPanel);
    lyricsArea = new SpellTextArea();
    lyricsArea.setMaxHeight(Double.MAX_VALUE);

    final VBox mainPanel = new VBox();
    ToolBar lyricsToolbar = new ToolBar();
    transposeButton = getTransposeButton();
    nonBreakingLineButton = getNonBreakingLineButton();
    lyricsToolbar.getItems().add(transposeButton);
    lyricsToolbar.getItems().add(nonBreakingLineButton);
    lyricsToolbar.getItems().add(new Separator());
    Region spacer = new Region();
    HBox.setHgrow(spacer, Priority.ALWAYS);
    lyricsToolbar.getItems().add(spacer);
    dictSelector = new ComboBox<>();
    Tooltip.install(
        dictSelector, new Tooltip(LabelGrabber.INSTANCE.getLabel("dictionary.language.text")));
    for (Dictionary dict : DictionaryManager.INSTANCE.getDictionaries()) {
      dictSelector.getItems().add(dict);
    }
    dictSelector
        .selectionModelProperty()
        .get()
        .selectedItemProperty()
        .addListener(
            new ChangeListener<Dictionary>() {

              @Override
              public void changed(
                  ObservableValue<? extends Dictionary> ov, Dictionary t, Dictionary t1) {
                lyricsArea.setDictionary(dictSelector.getValue());
              }
            });

    dictSelector.getSelectionModel().select(QueleaProperties.get().getDictionary());
    lyricsToolbar.getItems().add(dictSelector);
    lyricsToolbar.getItems().add(getDictButton());
    VBox.setVgrow(mainPanel, Priority.ALWAYS);
    mainPanel.getChildren().add(lyricsToolbar);
    VBox.setVgrow(lyricsArea, Priority.ALWAYS);
    mainPanel.getChildren().add(lyricsArea);
    centrePanel.getChildren().add(mainPanel);
    setCenter(centrePanel);
  }
  // drawing
  public void drawGraph() {

    Timeline timeline = new Timeline();

    if (graph != null && finalCoordinates != null) {

      // reset pane
      drawing.getChildren().clear();
      SpringEmbedder.centerCoordinates(finalCoordinates, 20, 380, 20, 380);
      SpringEmbedder.centerCoordinates(startingCoordinates, 20, 380, 20, 380);

      // draw nucleotides
      circles = new Circle[finalCoordinates.length];
      for (int i = 0; i < finalCoordinates.length; i++) {
        // create nodes
        Circle circle = new Circle(5);
        circle.setCenterX(finalCoordinates[i][0]);
        circle.setCenterY(finalCoordinates[i][1]);
        switch (graph.getSequence().charAt(i)) {
          case 'A':
            circle.setFill(Color.YELLOW);
            break;
          case 'a':
            circle.setFill(Color.YELLOW);
            break;
          case 'U':
            circle.setFill(Color.GREEN);
            break;
          case 'u':
            circle.setFill(Color.GREEN);
            break;
          case 'C':
            circle.setFill(Color.BLUE);
            break;
          case 'c':
            circle.setFill(Color.BLUE);
            break;
          case 'G':
            circle.setFill(Color.RED);
            break;
          case 'g':
            circle.setFill(Color.RED);
            break;
        }
        circle.setStroke(Color.BLACK);
        // add tooltip
        Tooltip t =
            new Tooltip("Nucleotide: " + graph.getSequence().charAt(i) + "\nPosition: " + i);
        Tooltip.install(circle, t);

        // add drag-and-drop behaviour
        circle.setOnMousePressed(
            event -> {
              if (isAnimationActivated) {
                dragStartX = circle.getCenterX();
                dragStartY = circle.getCenterY();
              }
            });

        circle.setOnMouseDragged(
            event -> {
              if (isAnimationActivated) {
                circle.setCenterX(event.getX());
                circle.setCenterY(event.getY());
              }
            });

        circle.setOnMouseReleased(
            event -> {
              if (isAnimationActivated) {
                Timeline dragTimeline = new Timeline();
                KeyValue circlePositionXKey = new KeyValue(circle.centerXProperty(), dragStartX);
                KeyValue circlePositionYKey = new KeyValue(circle.centerYProperty(), dragStartY);
                dragTimeline
                    .getKeyFrames()
                    .add(new KeyFrame(Duration.millis(animationTime), circlePositionXKey));
                dragTimeline
                    .getKeyFrames()
                    .add(new KeyFrame(Duration.millis(animationTime), circlePositionYKey));
                dragTimeline.play();
              }
            });

        // save circle locally
        circles[i] = circle;

        // animate circles
        KeyValue startingXKey = new KeyValue(circle.centerXProperty(), startingCoordinates[i][0]);
        KeyValue finalXKey = new KeyValue(circle.centerXProperty(), circle.getCenterX());
        KeyValue startingYKey = new KeyValue(circle.centerYProperty(), startingCoordinates[i][1]);
        KeyValue finalYKey = new KeyValue(circle.centerYProperty(), circle.getCenterY());
        timeline.getKeyFrames().add(new KeyFrame(Duration.millis(0), startingXKey));
        timeline.getKeyFrames().add(new KeyFrame(Duration.millis(0), startingYKey));
        timeline.getKeyFrames().add(new KeyFrame(Duration.millis(animationTime), finalXKey));
        timeline.getKeyFrames().add(new KeyFrame(Duration.millis(animationTime), finalYKey));
      }

      // create edges
      int[][] edges = graph.getEdges();
      for (int i = 0; i < edges.length; i++) {
        // bind edges to nodes
        Line line =
            new Line(
                finalCoordinates[edges[i][0]][0],
                finalCoordinates[edges[i][0]][1],
                finalCoordinates[edges[i][1]][0],
                finalCoordinates[edges[i][1]][1]);
        line.startYProperty().bind(circles[edges[i][0]].centerYProperty());
        line.startXProperty().bind(circles[edges[i][0]].centerXProperty());
        line.endYProperty().bind(circles[edges[i][1]].centerYProperty());
        line.endXProperty().bind(circles[edges[i][1]].centerXProperty());

        // draw edges
        if (edges[i][1] - edges[i][0] != 1) {
          line.setStroke(Color.CADETBLUE);
        } else {
          line.setFill(Color.DARKGRAY);
        }
        drawing.getChildren().add(line);
      }

      // draw all circles in order to overlap the edges
      drawing.getChildren().addAll(circles);

      if (isAnimationActivated) {
        timeline.play();
      }

    } else {
      throw new IllegalArgumentException(
          "graph is null: "
              + graph.equals(null)
              + "\ncoordinates is null: "
              + finalCoordinates.equals(null));
    }
  }
  @Override
  protected void updateItem(IlliquidMainSalesStatusBean item, boolean empty) {
    super.updateItem(item, empty);
    if ((!isEmpty()) && (item != null)) {
      StringBuilder tooltext = new StringBuilder();
      HBox hb = new HBox();
      hb.setAlignment(Pos.CENTER);
      VBox vb = new VBox();
      vb.setAlignment(Pos.CENTER);

      double totalCount =
          item.getCountTvr() + item.getDays30sale() + item.getDays60sale() + item.getDays90sale();
      double proc30;
      double proc60;
      double proc90;
      if (totalCount > 0) {
        proc30 = item.getDays30sale() / totalCount;
        proc60 = item.getDays60sale() / totalCount;
        proc90 = item.getDays90sale() / totalCount;
      } else {
        proc30 = 1;
        proc60 = 1;
        proc90 = 1;
      }

      if (proc30 == 0) {
        hb.getChildren().add(new ImageView(imEmpty));
        vb.getChildren().add(new ImageView(imEmpty));
      } else if (proc30 < 0.10) {
        hb.getChildren().add(new ImageView(imRed));
        vb.getChildren().add(new ImageView(imRed));
      } else if (proc30 >= 0.10 && proc30 < 0.30) {
        hb.getChildren().add(new ImageView(imYelow));
        vb.getChildren().add(new ImageView(imYelow));
      } else if (proc30 >= 0.30) {
        hb.getChildren().add(new ImageView(imGreen));
        vb.getChildren().add(new ImageView(imGreen));
      }
      tooltext
          .append("1 міс. {")
          .append(DateConverters.getDateToStr(per30From))
          .append(" - ")
          .append(DateConverters.getDateToStr(now))
          .append("}:  ")
          .append(String.format("%.2f", proc30 * 100))
          .append("%\n");

      if (proc60 == 0) {
        hb.getChildren().add(new ImageView(imEmpty));
        vb.getChildren().add(new ImageView(imEmpty));
      } else if (proc60 < 0.10) {
        hb.getChildren().add(new ImageView(imRed));
        vb.getChildren().add(new ImageView(imRed));
      } else if (proc60 >= 0.10 && proc60 < 0.30) {
        hb.getChildren().add(new ImageView(imYelow));
        vb.getChildren().add(new ImageView(imYelow));
      } else if (proc60 >= 0.30) {
        hb.getChildren().add(new ImageView(imGreen));
        vb.getChildren().add(new ImageView(imGreen));
      }
      tooltext
          .append("2 міс. {")
          .append(DateConverters.getDateToStr(per60From))
          .append(" - ")
          .append(DateConverters.getDateToStr(per30From))
          .append("}:  ")
          .append(String.format("%.2f", proc60 * 100))
          .append("%\n");

      if (proc90 == 0) {
        hb.getChildren().add(new ImageView(imEmpty));
        vb.getChildren().add(new ImageView(imEmpty));
      } else if (proc90 < 0.10) {
        hb.getChildren().add(new ImageView(imRed));
        vb.getChildren().add(new ImageView(imRed));
      } else if (proc90 >= 0.10 && proc90 < 0.30) {
        hb.getChildren().add(new ImageView(imYelow));
        vb.getChildren().add(new ImageView(imYelow));
      } else if (proc90 >= 0.30) {
        hb.getChildren().add(new ImageView(imGreen));
        vb.getChildren().add(new ImageView(imGreen));
      }
      tooltext
          .append("3 міс. {")
          .append(DateConverters.getDateToStr(per90From))
          .append(" - ")
          .append(DateConverters.getDateToStr(per60From))
          .append("}:  ")
          .append(String.format("%.2f", proc90 * 100))
          .append("%");
      tooltip.setText(tooltext.toString());
      tooltip.setGraphic(vb);
      setTooltip(tooltip);
      setGraphic(hb);
    } else {
      setGraphic(null);
    }
  }
 public void updateTooltip(double open, double close, double high, double low) {
   TooltipContent tooltipContent = (TooltipContent) tooltip.getGraphic();
   tooltipContent.update(open, close, high, low);
 }