title: JavaFx - Get the coordinates(x,y) of a node or control whose parent is not a Pane
body: <p>I am trying to emulate a popup container that will show some hints about the proper format of address. The popup will show whenever the <code>addressTextfield</code> gained focus. The popup should appear under the <code>addressTextfield</code>. The problem is, I used combinations of <code>VBox</code>, <code>HBox</code>, and <code>FlowPane</code> for my layout. The default <code>layoutX</code> and <code>layoutY</code> is zero, and it seem they do not change on runtime.</p>
  
  <p>My Popup Control</p>
  
  <p><a href="https://i.stack.imgur.com/vC8tA.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/vC8tA.jpg" alt="enter image description here"></a></p>
  
  <p>My AddressField and the hierarchy</p>
  
  <p><a href="https://i.stack.imgur.com/kTUPX.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/kTUPX.jpg" alt="enter image description here"></a></p>
  
  <p>What I got so far...</p>
  
  <p><a href="https://i.stack.imgur.com/f2idR.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/f2idR.jpg" alt="enter image description here"></a></p>
  
  <p>My Popup control stays on top. I tried binding my popup <code>layoutXProperty()</code> to <code>addressTextFields</code>'s <code>layoutXProperty()</code>same in <code>layoutYProperty()</code>. I tried adding a <code>MouseEvent.MOUSE_CLICKED</code>on <code>addressTextField</code>, added a <code>MouseLocationProperty</code> which will be updated on <code>MouseEvent.MouseClicked</code> and binded it to my popup's <code>layoutXProperty()</code>. But still not making it appear under the <code>addressTextField</code>.</p>
  
  <p>My AddNewAccount Class</p>
  
  <pre><code>package com.strongandwhite.pages.dentistadnstaff;
  
  import com.strongandwhite.customcontrols.CustomComboBox;
  import com.strongandwhite.customcontrols.CustomDatePicker;
  import com.strongandwhite.customcontrols.CustomPasswordField;
  import com.strongandwhite.customcontrols.CustomTextField;
  import com.strongandwhite.main.MainWindow;
  import com.strongandwhite.models.User;
  import com.strongandwhite.pages.Page;
  import com.strongandwhite.rules.*;
  import javafx.beans.property.SimpleDoubleProperty;
  import javafx.fxml.FXML;
  import javafx.fxml.FXMLLoader;
  import javafx.scene.control.Button;
  import javafx.scene.control.DateCell;
  import javafx.scene.control.ScrollPane;
  import javafx.scene.layout.AnchorPane;
  import javafx.scene.layout.HBox;
  import javafx.scene.layout.Pane;
  
  import java.io.IOException;
  import java.time.LocalDate;
  import java.time.chrono.ChronoLocalDate;
  import java.util.ArrayList;
  
  public class AddNewAccount extends Page {
      private ArrayList&lt;String&gt; gender;
      private ArrayList&lt;String&gt; type;
      private ArrayList&lt;String&gt; position;
      public User user;
      private SimpleDoubleProperty mouseX;
      private SimpleDoubleProperty mouseY;
  
      @FXML private HBox firstNameHBox;
      private CustomTextField firstNameTextField;
  
      @FXML private HBox middleNameHBox;
      private CustomTextField middleNameTextField;
  
      @FXML private HBox lastNameHBox;
      private CustomTextField lastNameTextField;
  
      @FXML private HBox ageHBox;
      private CustomTextField ageTextField;
  
      @FXML private HBox genderHBox;
      private CustomComboBox&lt;String&gt; genderComboBox;
  
      @FXML private HBox addressHBox;
      private CustomTextField addressTextField;
  
      @FXML private HBox contactHBox;
      private CustomTextField contactTextField;
  
      @FXML private HBox nationalityHBox;
      private CustomTextField nationalityTextField;
  
      @FXML private HBox religionHBox;
      private CustomTextField religionTextField;
  
      @FXML private HBox emailAddressHBox;
      private CustomTextField emailAddressTextField;
  
      @FXML private HBox birthdateHBox;
      private CustomDatePicker birtdateDatePicker;
  
      @FXML private HBox accountIDHBox;
      private CustomTextField accountIDTextField;
  
      @FXML private HBox passwordHBox;
      private CustomPasswordField passwordTextField;
  
      @FXML private HBox confirmPasswordHBox;
      private CustomPasswordField confirmPasswordTextField;
  
      @FXML private HBox accountTypeHBox;
      private CustomComboBox&lt;String&gt; accountTypeComboBox;
  
      @FXML private HBox positionHBox;
      private CustomComboBox&lt;String&gt; positionComboBox;
  
      @FXML private HBox question1HBox;
      private CustomTextField question1TextField;
  
      @FXML private HBox question2HBox;
      private CustomTextField question2TextField;
  
      @FXML private HBox question3HBox;
      private CustomTextField question3TextField;
  
      @FXML private HBox answer1HBox;
      private CustomTextField answer1TextField;
  
      @FXML private HBox answer2HBox;
      private CustomTextField answer2TextField;
  
      @FXML private HBox answer3HBox;
      private CustomTextField answer3TextField;
  
      @FXML private Button clearButton;
  
      private AnchorPane addressInfo;
      private Pane coverPane;
      private ScrollPane scrollPane;
  
      public AddNewAccount(User user, MainWindow mainWindow) {
          this.user = user;
  
          FXMLLoader loader = new FXMLLoader(getClass().getResource("AddNewAccount.fxml"));
          loader.setController(this);
          loader.setRoot(this);
          try {
              loader.load();
          } catch (IOException e) {
              e.printStackTrace();
          }
          loadTitle("AddNewAccountTitle.fxml");
  
          FXMLLoader loader1 = new FXMLLoader(getClass().getResource("AddressInfo.fxml"));
          try {
              addressInfo = loader1.load();
          } catch (IOException e) {
              e.printStackTrace();
          }
  
          coverPane = new Pane();
  
          firstNameTextField = new CustomTextField(firstNameHBox, customControls);
          firstNameTextField.setRule(new NameRule("First Name"));
  
          middleNameTextField = new CustomTextField(middleNameHBox, customControls);
          middleNameTextField.setRule(new NameRule("Middle Name"));
  
          lastNameTextField = new CustomTextField(lastNameHBox, customControls);
          lastNameTextField.setRule(new NameRule("Last Name"));
  
          birtdateDatePicker = new CustomDatePicker(birthdateHBox, customControls);
          birtdateDatePicker.setRule(new DateRule());
  
          ageTextField = new CustomTextField(ageHBox, customControls);
          ageTextField.setRule(new NumbersOnlyRule());
  
          genderComboBox = new CustomComboBox&lt;&gt;(genderHBox, customControls);
          genderComboBox.setRule(new WordRule("Gender"));
  
          addressTextField = new CustomTextField(addressHBox, customControls);
          addressTextField.setRule(new AddressRule());
  
          contactTextField = new CustomTextField(contactHBox, customControls);
          contactTextField.setRule(new ContactNumberRule());
  
          nationalityTextField = new CustomTextField(nationalityHBox, customControls);
          nationalityTextField.setRule(new NameRule("Nationality"));
  
          religionTextField = new CustomTextField(religionHBox, customControls);
          religionTextField.setRule(new NameRule("Religion"));
  
          emailAddressTextField = new CustomTextField(emailAddressHBox, customControls);
          emailAddressTextField.setRule(new EmailAddressRule());
  
          accountIDTextField = new CustomTextField(accountIDHBox, customControls);
          accountIDTextField.setRule(new AccountIDRule());
  
          passwordTextField = new CustomPasswordField(passwordHBox, customControls);
          passwordTextField.setRule(new PasswordRule());
  
          confirmPasswordTextField = new CustomPasswordField(confirmPasswordHBox, customControls);
          confirmPasswordTextField.setRule(new PasswordRule());
  
          accountTypeComboBox = new CustomComboBox&lt;&gt;(accountTypeHBox, customControls);
          accountTypeComboBox.setRule(new WordRule("Account Type"));
  
          positionComboBox = new CustomComboBox&lt;&gt;(positionHBox, customControls);
          positionComboBox.setRule(new WordRule("Position"));
  
          question1TextField = new CustomTextField(question1HBox, customControls);
          question1TextField.setRule(new WordRule("Question"));
  
          question2TextField = new CustomTextField(question2HBox, customControls);
          question2TextField.setRule(new WordRule("Question"));
  
          question3TextField = new CustomTextField(question3HBox, customControls);
          question3TextField.setRule(new WordRule("Question"));
  
          answer1TextField = new CustomTextField(answer1HBox, customControls);
          answer1TextField.setRule(new WordRule("Answer"));
  
          answer2TextField = new CustomTextField(answer2HBox, customControls);
          answer2TextField.setRule(new WordRule("Answer"));
  
          answer3TextField = new CustomTextField(answer3HBox, customControls);
          answer3TextField.setRule(new WordRule("Answer"));
  
          clearButton.setOnAction(event -&gt; clearPageFields());
  
          birtdateDatePicker.setDefaultDate(LocalDate.now().minusYears(18));
          birtdateDatePicker.setDayCellFactory(param -&gt; new DateCell() {
              @Override
              public void updateItem(LocalDate item, boolean empty) {
                  super.updateItem(item, empty);
                  if(item.isBefore(ChronoLocalDate.from(LocalDate.now().minusYears(76).minusMonths(1)))||item.isAfter(ChronoLocalDate.from(LocalDate.now().minusYears(18).plusMonths(1)))) {
                      this.setDisable(true);
                  }
              }
          });
  
          user.ageProperty().bind(birtdateDatePicker.ageProperty());
          ageTextField.textProperty().bind(user.ageProperty().asString());
  
          gender = new ArrayList&lt;&gt;();
          gender.add("Male");
          gender.add("Female");
          genderComboBox.setItems(gender);
  
          type = new ArrayList&lt;&gt;();
          type.add("Administrator");
          type.add("Standard");
          type.add("Limited");
          accountTypeComboBox.setItems(type);
  
          position = new ArrayList&lt;&gt;();
          position.add("Dentist");
          position.add("Receptionist");
          position.add("Staff");
          positionComboBox.setItems(position);
  
          answer1TextField.editableProperty().bind(question1TextField.textProperty().isNotEmpty());
          answer1TextField.editableProperty().addListener(event-&gt; {
              if(question1TextField.textProperty().getValue().trim().isEmpty()) answer1TextField.clear();
          });
  
          answer2TextField.editableProperty().bind(question2TextField.textProperty().isNotEmpty());
          answer2TextField.editableProperty().addListener(event-&gt; {
              if(question2TextField.textProperty().getValue().trim().isEmpty()) answer2TextField.clear();
          });
  
          answer3TextField.editableProperty().bind(question3TextField.textProperty().isNotEmpty());
          answer3TextField.editableProperty().addListener(event-&gt; {
              if(question3TextField.textProperty().getValue().trim().isEmpty()) answer3TextField.clear();
          });
  
          mainWindow.getActivePagePane().getChildren().add(getPageTitle());
  
          scrollPane = (ScrollPane) mainWindow.getActivePagePane().getChildren().get(0);
          scrollPane.vvalueProperty().addListener(event-&gt; scrollPane.requestFocus());
  
          addressInfo.visibleProperty().bind(addressTextField.getTextField().focusedProperty());
          coverPane.setPickOnBounds(false);
          mainWindow.getActivePagePane().getChildren().add(coverPane);
          coverPane.getChildren().add(addressInfo);
          addressInfo.layoutXProperty().bind(addressTextField.getTextField().layoutXProperty());
          addressInfo.layoutYProperty().bind(addressTextField.getTextField().layoutYProperty());
      }
  }
  </code></pre>
  
  <p>My CustomTextField Class</p>
  
  <pre><code>package com.strongandwhite.customcontrols;
  
  import javafx.beans.property.BooleanProperty;
  import javafx.beans.property.StringProperty;
  import javafx.scene.control.Button;
  import javafx.scene.control.Label;
  import javafx.scene.control.TextField;
  import javafx.scene.layout.HBox;
  import javafx.scene.layout.StackPane;
  import javafx.scene.layout.VBox;
  
  import java.util.ArrayList;
  
  public class CustomTextField extends CustomControl {
      private TextField textField;
      private Label textLabel;
      private Button clearButton;
  
      public CustomTextField(HBox control, ArrayList&lt;CustomControl&gt; customControls) {
          setContainer(control);
          textLabel = (Label) ((VBox)control.getChildren().get(0)).getChildren().get(0);
          setErrorLabel((Label) ((VBox)control.getChildren().get(0)).getChildren().get(2));
          textField = (TextField) ((StackPane)((VBox)control.getChildren().get(0)).getChildren().get(1)).getChildren().get(0);
          clearButton = (Button) ((StackPane)((VBox)control.getChildren().get(0)).getChildren().get(1)).getChildren().get(1);
          textLabel.visibleProperty().bind(textField.textProperty().isNotEmpty());
          clearButton.visibleProperty().bind(textField.textProperty().isNotEmpty().and(textField.focusedProperty()).and(textField.editableProperty()));
          clearButton.setOnAction(event -&gt; textField.clear());
          textField.textProperty().addListener((observable, oldValue, newValue) -&gt; executeRule(getRule(), textField.getText()));
          customControls.add(this);
      }
  
      public StringProperty textProperty() {
          return textField.textProperty();
      }
  
      public BooleanProperty editableProperty() {
          return textField.editableProperty();
      }
  
      public String getText() {
          return textField.getText();
      }
  
      public void setText(String text) {
          textField.setText(text);
      }
  
      public TextField getTextField() {
          return textField;
      }
  
      public void setTextField(TextField textField) {
          this.textField = textField;
      }
  
      @Override
      public void clear() {
          textField.clear();
      }
  }
  </code></pre>
  
  <p>Is there any way I can get the coordinates of <code>addressTextField</code> relative to my Form?</p>
  
  <p>NOTE: My popup is added on a <code>Pane</code> particulary the <code>coverPane</code> which is above my Form and they are all under <code>StackPane</code>.</p>