JavaFx - 获取父节点不是Pane的节点或控件的坐标(x,y)

时间:2017-11-14 05:45:00

标签: javafx scenebuilder

我正在尝试模拟一个弹出式容器,该容器将显示有关正确格式的地址的一些提示。只要addressTextfield获得焦点,弹出窗口就会显示。弹出窗口应显示在addressTextfield下方。问题是,我使用VBoxHBoxFlowPane的组合作为我的布局。默认layoutXlayoutY为零,似乎它们在运行时不会更改。

我的弹出控件

enter image description here

我的地址字段和层次结构

enter image description here

到目前为止我得到了什么......

enter image description here

我的弹出窗口控件保持最佳状态。我尝试将我的弹出窗口layoutXProperty()绑定到addressTextFields layoutXProperty() layoutYProperty() MouseEvent.MOUSE_CLICKED。我尝试在addressTextField上添加MouseLocationProperty,添加MouseEvent.MouseClickedlayoutXProperty()将更新addressTextField并将其绑定到我的弹出窗口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<String> gender; private ArrayList<String> type; private ArrayList<String> 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<String> 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<String> accountTypeComboBox; @FXML private HBox positionHBox; private CustomComboBox<String> 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<>(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<>(accountTypeHBox, customControls); accountTypeComboBox.setRule(new WordRule("Account Type")); positionComboBox = new CustomComboBox<>(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 -> clearPageFields()); birtdateDatePicker.setDefaultDate(LocalDate.now().minusYears(18)); birtdateDatePicker.setDayCellFactory(param -> 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<>(); gender.add("Male"); gender.add("Female"); genderComboBox.setItems(gender); type = new ArrayList<>(); type.add("Administrator"); type.add("Standard"); type.add("Limited"); accountTypeComboBox.setItems(type); position = new ArrayList<>(); position.add("Dentist"); position.add("Receptionist"); position.add("Staff"); positionComboBox.setItems(position); answer1TextField.editableProperty().bind(question1TextField.textProperty().isNotEmpty()); answer1TextField.editableProperty().addListener(event-> { if(question1TextField.textProperty().getValue().trim().isEmpty()) answer1TextField.clear(); }); answer2TextField.editableProperty().bind(question2TextField.textProperty().isNotEmpty()); answer2TextField.editableProperty().addListener(event-> { if(question2TextField.textProperty().getValue().trim().isEmpty()) answer2TextField.clear(); }); answer3TextField.editableProperty().bind(question3TextField.textProperty().isNotEmpty()); answer3TextField.editableProperty().addListener(event-> { if(question3TextField.textProperty().getValue().trim().isEmpty()) answer3TextField.clear(); }); mainWindow.getActivePagePane().getChildren().add(getPageTitle()); scrollPane = (ScrollPane) mainWindow.getActivePagePane().getChildren().get(0); scrollPane.vvalueProperty().addListener(event-> 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()); } } 。但仍未将其显示在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<CustomControl> 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 -> textField.clear()); textField.textProperty().addListener((observable, oldValue, newValue) -> 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(); } } 下。

我的AddNewAccount类

addressTextField

我的CustomTextField类

Pane

有什么方法可以得到coverPane相对于我的表格的坐标?

注意:我的弹出式广告已添加到StackPane特定的window.location = "/signin"; 上方,该window.location = "/signin?q=1"; 位于我的表单之上且全部位于signin下。

1 个答案:

答案 0 :(得分:1)

These guys建议您使用以下内容:

Bounds boundsInScene = addressTextField.localToScene(addressTextField.getBoundsInLocal());

然后使用

boundsInScene.getMinX()
boundsInScene.getMinY()
boundsInScene.getMaxX()
boundsInScene.getMaxY()
boundsInScene.getWidth()
boundsInScene.getHeight() 

获取组件相对于场景的值