【问题标题】:GridPane acts as mouseTransparent although not setGridPane 充当 mouseTransparent 虽然未设置
【发布时间】:2018-06-18 08:30:20
【问题描述】:

我想做什么?

我遇到了一个基于 fxml 的 javafx 应用程序的问题。我想创建一个简单的表单来输入一些在确认后应该存储在文件中的数值。

有什么问题?

除了我不能用鼠标单击两个 GridPanes 中的元素外,该表单完美地完成了它应该做的事情。我可以通过按选项卡按钮切换 TextFields 来输入值,但这当然不是理想的方式。我已经直接在 AnchorPane 中添加了 TextFields 和 CheckBoxes,它们是可点击的,但在 GridPanes 中这不起作用。同一 AnchorPane 中的 FlowPane 也可以正常工作。

在我看来,GridPanes 的行为好像被设置为 mouseTransparent="true",但事实并非如此,我也已经尝试将其显式设置为 false。我找不到这种行为的原因,所以也许你们中的某个人有一个想法。

编辑:在同一个选项卡中使用了一个附加的 GridPane 后,我发现这不是该文件中的一般 GridPane 问题。对于只有复选框和一个 Anchor 的 GridPane,可以访问该元素。是否有一些重叠阻止通过鼠标访问?

在单独的类的初始化函数中设置场景:

        BorderPane root = FXMLLoader.load(getClass().getResource("..\\initializeSeason\\InitializeSeason.fxml"));
        Scene scene = new Scene(root,600,900);
        stage.setScene(scene);
        stage.show();

xfml 文件的构建如下(对于德国名称,我很抱歉):

            <?xml version="1.0" encoding="UTF-8"?>

    <?import javafx.scene.layout.BorderPane?>
    <?import javafx.scene.control.TabPane?>
    <?import javafx.scene.control.Tab?>
    <?import javafx.scene.layout.FlowPane?>
    <?import javafx.scene.control.Button?>
    <?import javafx.scene.layout.AnchorPane?>
    <?import javafx.scene.layout.GridPane?>
    <?import javafx.scene.text.Text?>
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.control.TextField?>
    <?import javafx.scene.layout.ColumnConstraints?>
    <?import javafx.scene.control.RadioButton?>
    <?import javafx.scene.control.CheckBox?>

    <BorderPane  xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"  fx:controller="application.LeagueRulesController" >
        <center>
            <TabPane  tabClosingPolicy="UNAVAILABLE" >
                <tabs>
                    <Tab style="-fx-font-weight:bold" text="Liga Regeln" >
                        <AnchorPane  >
                            <children>
                                <GridPane AnchorPane.topAnchor="10.0" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" hgap="15" vgap="15" >
                                        <columnConstraints>
                                            <ColumnConstraints hgrow="ALWAYS" />
                                        </columnConstraints> 

                                    <children>
                                        <Label text="Anzahl der Zeichen im Teamnamen: " GridPane.columnIndex="0" GridPane.rowIndex="0"/>
                                        <TextField fx:id="numberOfShortNameChars" alignment="BASELINE_RIGHT" prefWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="0"/>

                                        <Label text="Anzahl der Touchdown Differenz Einträge: " GridPane.columnIndex="0" GridPane.rowIndex="1"/>
                                        <TextField fx:id="numberOfTDDiffEntries" alignment="BASELINE_RIGHT" prefWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="1"/>

                                        <GridPane fx:id="tdDiffEntrys" hgap="15" vgap="15" GridPane.columnIndex="1" GridPane.rowIndex="2" />

                                        <Label text="Erhält Gewinnerteam bei Spielaufgabe maximale Punktzahl?:" GridPane.columnIndex="0" GridPane.rowIndex="3"/>
                                        <CheckBox  fx:id="isConcedeMaxWin" GridPane.columnIndex="1" GridPane.rowIndex="3"></CheckBox>
                                    </children>
                                </GridPane>

                                <FlowPane  orientation="HORIZONTAL" alignment="BOTTOM_RIGHT" hgap="5" AnchorPane.topAnchor="10.0" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0">
                                    <Button fx:id="okButton" text="OK" onAction="#handleOK"> </Button>
                                    <Button fx:id="abbrechenButton" text="Abbrechen"  onAction="#handleAbbrechen"> </Button>                    
                                </FlowPane> 
                            </children>
                        </AnchorPane>
                    </Tab>
                    <Tab style="-fx-font-weight:bold" text="Teams verwalten">

                    </Tab>      
                </tabs>
            </TabPane>
        </center>
    </BorderPane>

虽然我确信可以在 .fxml 文件中找到问题,但我还添加了 LeagueRulesController 类。

            package application;

    import java.net.URL;
    import java.util.ArrayList;
    import java.util.ResourceBundle;

    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.geometry.Pos;
    import javafx.scene.control.Button;
    import javafx.scene.control.CheckBox;
    import javafx.scene.control.Label;
    import javafx.scene.control.TextField;
    import javafx.scene.layout.GridPane;
    import javafx.stage.Stage;

    public class LeagueRulesController implements Initializable{


        private ArrayList<TextField> tdDiffs;
        private ArrayList<TextField> points;



        @FXML
        private CheckBox isConcedeMaxWin;

        @FXML
        private Button okButton;
        @FXML
        private Button abbrechenButton;

        @FXML
        private void handleAbbrechen(ActionEvent actionEvet) {
            Stage stage = (Stage) abbrechenButton.getScene().getWindow();
            // do what you have to do
            stage.close();
        }

        @FXML
        private void handleOK(ActionEvent actionEvet) {

            Stage stage = (Stage) abbrechenButton.getScene().getWindow();
            stage.close();
        }

        @FXML
        private TextField numberOfShortNameChars;
        @FXML
        private TextField numberOfTDDiffEntries;    
        @FXML
        private GridPane tdDiffEntrys;

        @Override
        public void initialize(URL arg0, ResourceBundle arg1) {
            numberOfShortNameChars.setText("25");
            numberOfShortNameChars.textProperty().addListener(new ChangeListener<String>() {
                @Override
                public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                    numberFieldListener(numberOfShortNameChars, oldValue,newValue);
                }
            });

            numberOfTDDiffEntries.setText("5");

            initializeTDDiffArray();

            numberOfTDDiffEntries.textProperty().addListener(new ChangeListener<String>() {

                @Override
                public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                    numberFieldListener(numberOfTDDiffEntries, oldValue,newValue);
                    initializeTDDiffArray();
                }
            });
        }

        private void initializeTDDiffArray() {
            tdDiffEntrys.getChildren().clear();
            tdDiffs = new ArrayList<>();
            points = new ArrayList<>();

            tdDiffEntrys.add(new Label("TD Diff"), 0, 0);
            tdDiffEntrys.add(new Label("Punkte"), 1, 0);

            int numberOfTDDiffEntriesInt;
            if(numberOfTDDiffEntries.getText().equals(""))
                numberOfTDDiffEntriesInt = 1;
            else
                numberOfTDDiffEntriesInt =Integer.parseInt(numberOfTDDiffEntries.getText());

            for (int i = 0; i < numberOfTDDiffEntriesInt; i++) {
                tdDiffs.add(new TextField());
                points.add(new TextField());
                tdDiffs.get(tdDiffs.size()-1).setText(Integer.toString(i-numberOfTDDiffEntriesInt/2));
                points.get(points.size()-1).setText(Integer.toString(i+1));

                tdDiffs.get(tdDiffs.size()-1).setAlignment(Pos.BASELINE_RIGHT);
                points.get(points.size()-1).setAlignment(Pos.BASELINE_RIGHT);

                tdDiffs.get(tdDiffs.size()-1).setPrefWidth(1);
                points.get(points.size()-1).setPrefWidth(1);

                tdDiffs.get(tdDiffs.size()-1).textProperty().addListener(new ChangeListener<String>() {
                    @Override
                    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                        numberFieldListener(tdDiffs.get(tdDiffs.size()-1), oldValue,newValue);
                    }
                });
                points.get(points.size()-1).textProperty().addListener(new ChangeListener<String>() {
                    @Override
                    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                        numberFieldListener(points.get(points.size()-1), oldValue,newValue);
                    }
                });

                tdDiffEntrys.add(tdDiffs.get(tdDiffs.size()-1), 0, i+1);
                tdDiffEntrys.add(points.get(points.size()-1), 1,  i+1);
            }

        }

        private void numberFieldListener(TextField textField, String oldValue,String newValue) {

            if(!newValue.matches("\\d*")) {
                textField.setText(newValue.replaceAll("[^\\d]", ""));
            }
        }

    }

提前感谢您抽出宝贵时间。

【问题讨论】:

    标签: javafx fxml gridpane


    【解决方案1】:

    您的FlowPane 位于您的GridPane 之上,这会阻止鼠标事件到达GridPane。在您的 FXML 文件中,您的 GridPaneFlowPaneAnchorPane 约束设置为 10(顶部、左侧、底部和右侧)。这意味着两个节点都占用了AnchorPane 中的相同空间。并且由于您添加了您的 FlowPane 第二个 GridPane 被覆盖。请注意,添加GridPane 秒很可能允许您单击TextFields,但会阻止您单击Buttons。

    为什么不用AnchorPane 而不是VBoxVBox 设计用于垂直布局节点。您也可以将FlowPane 替换为HBox,因为这似乎是您所追求的行为。你最终会得到类似的东西:

    <Tab>
        <VBox>
            <GridPane>
                <!-- your GirdPane children -->
            </GridPane>
            <HBox>
                <!-- your buttons -->
            </HBox>
        </VBox>
    </Tab>
    

    为简洁起见,我省略了属性。您显然会将它们设置为您想要的值

    如果您走这条路,您需要将您的Label(文本设置为"Erhält Gewinnerteam bei Spielaufgabe maximale Punktzahl?:")移动到新的HBox 作为第一个孩子。这样它就与按钮保持一致。


    当然,您没有替换您的AnchorPane。如果你想保留它,你必须弄清楚如何让FlowPane 的顶部锚始终等于GridPane 的底部距顶部的距离。由于您当前在 10 处拥有 GridPane 的顶部锚点,因此 FlowPane 的顶部锚点必须类似于 10 + gridPaneHeight。我不确定您是否可以在 FXML 文件中执行此操作,这意味着您必须在控制器的初始化方法中执行此操作。如果您的应用要调整大小,您可能还必须在调整大小时更新顶部锚点。

    【讨论】:

    • 你是最棒的!非常感谢。我越来越接近某种东西重叠的感觉,但无法完全确定它是什么。非常感谢。
    猜你喜欢
    • 2015-01-14
    • 2012-04-23
    • 1970-01-01
    • 2021-04-15
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    • 2020-07-23
    • 2011-11-23
    相关资源
    最近更新 更多