JavaFX:如何在focusProperty更改侦听器上设置优先级

时间:2015-02-21 18:29:19

标签: java events javafx focus

我的场景:我有一个TextField和一个ListView。当用户在文本字段中键入文本时,会出现建筑材料建议列表(从数据库加载)。

所需功能:我希望用户能够点击材料建议并让它自动使用材料的全名填充TextField。但是,如果用户停止聚焦TextField(并在其他任何地方单击),并且数据库中不存在该材料,则应显示一个对话框,要求他们将材料添加到数据库中。

当前功能:当用户点击TextField时,弹出的对话框一切正常。但是,当用户单击ListView中的一个建议时,TextField的focusProperty更改事件将在ListView的selectedItemProperty更改事件之前调用。因此,当用户想要简单地选择ListView中的一个建议时,用户会弹出一个要求他们向DB添加材料的弹出窗口。

我的问题是,有没有办法让我设置焦点更改事件的优先级,以便在"有效材料"之前调用select item事件。检查是由焦点事件进行的?如果没有,我还可以解决这个问题吗?

我的初始化方法:

@FXML
public void initialize() { 
    // Search list
    searchList.getItems().addAll(StockedMaterial.getStockedMaterials());
    searchList.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> {
        if (newValue != null) {
            setStockedMaterial(newValue);
        }
    });

    nameField.focusedProperty().addListener((observable, oldValue, newValue) -> {
        if (!newValue) commit();
    });

    updateAll();

    //This needs to be after the above, as setText will trigger it 
    nameField.textProperty().addListener((obs, oldVal, newVal) -> searchMaterials(oldVal, newVal));
}

提交检查有效材料的方法,如果无效则添加它:

@FXML
public void commit() {
    requiredMaterial.setQuantityRequired(quantityField.getDouble());

    StockedMaterial stockedMaterial = StockedMaterial.getStockedMaterialByName(nameField.getText());

    if (stockedMaterial == null && (stage == null || !stage.isShowing())) {
        if (!nameField.getText().equals("")) {
            stage = StageUtil.createDialogStage(Resources.getResource("materials.add"));
            stage.setOnCloseRequest(e -> {
                delete();
            });

            VBox vbox = new VBox(10);
            vbox.setPadding(new Insets(10));
            vbox.setAlignment(Pos.CENTER);
            SceneUtil.changeScene(stage, vbox);

            Label infoLabel = new Label(Resources.getResource("quotes.materialCreated", nameField.getText()));
            vbox.getChildren().add(infoLabel);

            GridPane grid = new GridPane();
            grid.setHgap(5);
            grid.setVgap(5);
            grid.setAlignment(Pos.CENTER);
            vbox.getChildren().add(grid);

            Label quantityLabel = new Label(Resources.getResource("materials.quantityInStock"));
            DoubleTextField quantity = new DoubleTextField();
            grid.addRow(0, quantityLabel, quantity);

            Label quantityTypeLabel = new Label(Resources.getResource("materials.quantityType"));
            ComboBox<QuantityType> combo = new ComboBox<QuantityType>(FXCollections.observableArrayList(QuantityType.values()));
            grid.addRow(1, quantityTypeLabel, combo);

            combo.getSelectionModel().selectFirst();

            Button add = new Button(Resources.getResource("materials.add"));
            add.setOnAction(e -> {
                StockedMaterial newMaterial = new StockedMaterial();
                newMaterial.setNewModel(true);
                newMaterial.setName(nameField.getText());
                newMaterial.setQuantityInStock(quantity.getDouble());
                newMaterial.setQuantityTypeId(combo.getSelectionModel().getSelectedItem().getId());
                newMaterial.save();

                requiredMaterial.setStockedMaterial(newMaterial);
                updateAll();
                SceneUtil.closeScene(add);
            });

            vbox.getChildren().add(add);
            stage.sizeToScene();
        } else {
            delete();
        }
    } else {
        setStockedMaterial(stockedMaterial);
    }
}

截图:

当我输入&#34; br&#34;并尝试单击Brick,我得到下面的对话框,只有当我点击ListView中的Brick项目以外的任何其他内容时才会出现。

0 个答案:

没有答案