title: JavaFX - Draw Popup where mouse is?
body: <p>I currently have the following class which <code>extends Popup</code>:</p>
  
  <pre><code>package application;
  
  import java.io.File;
  import java.util.HashMap;
  import java.util.Map;
  
  import javafx.animation.KeyFrame;
  import javafx.animation.KeyValue;
  import javafx.animation.Timeline;
  import javafx.beans.property.BooleanProperty;
  import javafx.beans.property.ReadOnlyBooleanProperty;
  import javafx.beans.property.SimpleBooleanProperty;
  import javafx.collections.ObservableList;
  import javafx.geometry.Insets;
  import javafx.geometry.Pos;
  import javafx.scene.Node;
  import javafx.scene.control.Label;
  import javafx.scene.image.Image;
  import javafx.scene.image.ImageView;
  import javafx.scene.layout.VBox;
  import javafx.scene.paint.Color;
  import javafx.stage.Popup;
  import javafx.util.Duration;
  import logic.Item;
  import logic.ItemQuality;
  import logic.Manager;
  
  /**
   * Frame which displays an Item, ideally used
   * for when the user hovers over a given element.
   * The frame's labels are all made to look
   * Diablo 2-esque which ends up creating a nice 
   * looking frame which fades in and out on use.
   * @author Kevin
   *
   */
  class ItemFrame_Animated extends Popup
  {
      private final BooleanProperty hiding;
  
      ItemFrame_Animated(Item reference)
      {
          VBox frame = new VBox();
          frame.setAlignment(Pos.CENTER);
          frame.setPadding(new Insets(10));
          frame.setSpacing(4);
  
          Color titleColor = reference.getQuality().getColor();
  
          // This item has a surname, such as 'ENGIMA'.
          if (!reference.getSpecialName().isEmpty())
          {
              Label surname = new Label(reference.getSpecialName());
              surname.setTextFill(titleColor);
              frame.getChildren().add(surname);
          }
  
          // Base name, such as 'Long Bow'.
          Label basename = new Label(reference.getIdentifier());
          // One special case is that if the quality is runeword, the item's base needs to be Gray.
          basename.setTextFill((reference.getQuality() == ItemQuality.RUNEWORD) ?
                  ItemQuality.BASE_MODIFIED.getColor() : titleColor);
          frame.getChildren().add(basename);
  
          // If the item has a level.
          if (reference.getLevel() &gt; 0)
          {
              Label level = new Label("Required Level: " + reference.getLevel());
              // Level is ALWAYS white colored.
              level.setTextFill(ItemQuality.BASE.getColor());
              frame.getChildren().add(level);
          }
  
          // Add the Affixes.
          for (String i : reference.getAffixes())
          {
              Label affix = new Label(i);
              // Affixes are ALWAYS blue colored.
              affix.setTextFill(ItemQuality.MAGIC.getColor());
              frame.getChildren().add(affix);
          }
  
          if (reference.getSockets() &gt; 0)
          {
              Label sockets = new Label("Socketed: (" + reference.getSockets() + ")");
              sockets.setTextFill(ItemQuality.BASE_MODIFIED.getColor());
              frame.getChildren().add(sockets);
          }
  
          // Change the font of every label.
          for (Node i : frame.getChildren())
          {
              i.getStyleClass().clear();
              ((Label) i).setFont(GUI.diabloFont);
          }
  
          // Add the item's picture to the Frame.
          String path = "./res/Images/" + Manager.itemDatabase.get(reference.getIdentifier()).getImageURL().hashCode() + ".jpg";
          ImageView itemImage = new ImageView(new Image(new File(path).toURI().toString()));
          frame.getChildren().add(itemImage);
  
          // Set the content of the page to the VBox.
          getContent().add(frame);
          frame.setStyle("-fx-background-color: #020202;");
  
          // Don't allow this Popup to be closed.
          setHideOnEscape(false);
          setWidth(400);
          setHeight(500);
  
          this.hiding = new SimpleBooleanProperty(this, "hiding", false);
      }
  
      public ReadOnlyBooleanProperty hidingProperty()
      {
          return hiding;
      }
  
      public boolean isHiding()
      {
          return hiding.get();
      }
  
      @Override public void hide()
      {
          // If the Window is not already in the process of being hidden...
          if (!hiding.get())
          {
              // Inform the Popup that we are now attempting to hide.
              hiding.set(true);
  
              // Grab all the nodes in this PopUp and track their opacities.
              final ObservableList&lt;Node&gt; nodes = this.getContent();
              final Map&lt;Node, Double&gt; opacities = new HashMap&lt;Node, Double&gt;();
              KeyValue[] keyValues = new KeyValue[nodes.size()];
              for (int i = 0; i &lt; keyValues.length; i++)
              {
                  // Set the KeyValues for each node.
                  Node node = nodes.get(i);
                  opacities.put(node, node.getOpacity());
                  keyValues[i] = new KeyValue(nodes.get(i).opacityProperty(), 0);
              }
  
              KeyFrame frame = new KeyFrame(Duration.seconds(1), keyValues);
              Timeline timeline = new Timeline(frame);
              timeline.setOnFinished(e -&gt;
              {
                  // We are no longer hiding the frame.
                  hiding.set(false);
                  ItemFrame_Animated.super.hide();
                  for (Node node : nodes)
                  {
                      node.setOpacity(opacities.get(node));
                  }
              });
  
              // Play the animation.
              timeline.play();
          }
      }
  }
  </code></pre>
  
  <p>Honestly the code isn't important, just trust me that it displays a Popup like so when a User hovers over one of my <code>Item</code> objects, as so:</p>
  
  <p><a href="https://i.stack.imgur.com/VcSw4.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/VcSw4.png" alt="Item Frame"></a></p>
  
  <p>This Popup window opened right in the middle of my screen. If I move the window, the Popup will open in that same location. I need my Popup window to somehow open under the Mouse pointer. I know <code>Tooltip</code> has this functionality (allegedly) but I've already committed to designing this <code>Popup</code> window which has many of my design goals.</p>
  
  <p>Is this possible to have the <code>Popup</code> window to show in a certain location? </p>
  
  <p>Thank you.</p>