代码之家  ›  专栏  ›  技术社区  ›  Mr. Leeds

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

  •  1
  • Mr. Leeds  · 技术社区  · 8 年前

    我试图模拟一个弹出式容器,它将显示一些关于正确地址格式的提示。每当 addressTextfield 获得关注。弹出窗口应出现在 地址文本字段 . 问题是,我使用了 VBox , HBox FlowPane 用于我的布局。默认值 layoutX layoutY 为零,并且似乎在运行时不会更改。

    我的弹出控件

    enter image description here

    我的地址字段和层次结构

    enter image description here

    到目前为止我得到的。。。

    enter image description here

    我的弹出控件保持在顶部。我试着绑定弹出菜单 layoutXProperty() addressTextFields layoutXProperty() 在中相同 layoutYProperty() . 我试着添加一个 MouseEvent.MOUSE_CLICKED 在…上 addressTextField ,添加了一个 MouseLocationProperty 将于更新 MouseEvent.MouseClicked 把它绑在我的弹出菜单上 layoutXProperty() . 但仍然没有使其出现在 地址文本字段 .

    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());
        }
    }
    

    我的CustomTextField类

    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();
        }
    }
    

    有什么方法可以得到 地址文本字段 相对于我的表格?

    注意:我的弹出窗口添加在 Pane 特别是 coverPane 在我的表格上面,他们都在下面 StackPane .

    1 回复  |  直到 8 年前
        1
  •  1
  •   Gus    8 年前

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

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

    然后使用

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

    获取组件相对于场景的值