【问题标题】:AnchorPane elements ignore Mouse clickAnchorPane 元素忽略鼠标单击
【发布时间】:2018-11-20 11:26:09
【问题描述】:

我初始化了一些不是我的锚窗格的元素:

AnchorPane root = new AnchorPane(listLoader.load(), textareaLoader.load(), fieldLoader.load(), menuLoader.load(), buttonLoader.load());

但是当我尝试单击菜单栏或列表视图时,它不起作用。例如,在这种情况下,我可以单击按钮(也许),因为它是我在 AnchorPane 构造函数中初始化的最后一个元素。我不能使用 BorderPane 或任何其他布局,因此我需要找到具有此配置的解决方案。 这些是我的 fxml 文件:

list.fxml

<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mailbox.ListController">
<children>
    <AnchorPane> 
        <children>
            <ListView fx:id="listView" layoutX="1.0" layoutY="31.0" prefHeight="371.0" prefWidth="239.0" />
        </children>
    </AnchorPane> 
</children>

menuBar.fxml

<AnchorPane xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="mailbox.MenuBarController">
<children>
    <AnchorPane> 
        <children>
            <MenuBar fx:id="menuBar" layoutX="0.0" layoutY="0.0">
                <menus>
                    <Menu text="File">
                        <items>
                            <MenuItem onAction="#elimina" text="Elimina" />
                        </items>
                    </Menu>
                    <Menu text="Cambia Account">
                        <items>
                            <MenuItem fx:id="email1" text="filippo@hotmail.it" />
                            <MenuItem fx:id="email2" text="giancarlo@yahoo.it" />
                            <MenuItem fx:id="email3" text="alessandro@gmail.it" />
                        </items>
                    </Menu>
                </menus>
            </MenuBar>
        </children>
    </AnchorPane>
</children>

textArea.fxml

<AnchorPane xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="mailbox.TextAreaController">
<children>
    <AnchorPane> 
        <children>
            <TextArea fx:id="textarea" editable="false" layoutX="246.0" layoutY="255.0" prefHeight="144.0" prefWidth="350.0" />
        </children>
    </AnchorPane>
</children>

button.fxml

<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mailbox.ButtonController">
<children>
    <AnchorPane> 
        <children>
            <Button id="scrivi" layoutX="268.0" layoutY="200.0" mnemonicParsing="false" prefHeight="27.0" prefWidth="65.0" text="Scrivi" />
            <Button id="reply" layoutX="342.0" layoutY="200.0" mnemonicParsing="false" prefHeight="27.0" prefWidth="65.0" text="Reply" />
            <Button id="replyall" layoutX="420.0" layoutY="200.0" mnemonicParsing="false" prefHeight="27.0" prefWidth="75.0" text="Reply-All" />
            <Button id="forward" layoutX="511.0" layoutY="200.0" mnemonicParsing="false" prefHeight="27.0" prefWidth="75.0" text="Forward" />
        </children>
    </AnchorPane>
</children>

textfield.fxml

<AnchorPane mouseTransparent="false" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mailbox.TextFieldController">
<children>
    <AnchorPane> 
        <children>
            <TextField fx:id="id" editable="false" layoutX="355.0" layoutY="39.0" mouseTransparent="false" prefHeight="27.0" prefWidth="35.0" />
            <TextField fx:id="mitt" editable="false" layoutX="355.0" layoutY="72.0" mouseTransparent="false" prefHeight="27.0" prefWidth="182.0" />
            <TextField fx:id="dest" editable="false" layoutX="355.0" layoutY="108.0" mouseTransparent="false" prefHeight="27.0" prefWidth="182.0" />
            <TextField fx:id="oggetto" editable="false" layoutX="355.0" layoutY="144.0" mouseTransparent="false" prefHeight="27.0" prefWidth="182.0" />
            <TextField fx:id="data" editable="false" layoutX="437.0" layoutY="39.0" mouseTransparent="false" prefHeight="27.0" prefWidth="100.0" />
            <Label layoutX="329.0" layoutY="44.0" text="ID:" />
            <Label layoutX="291.0" layoutY="77.0" text="Mittente:" />
            <Label layoutX="398.0" layoutY="44.0" text="Data:" />
            <Label layoutX="268.0" layoutY="113.0" text="Destinatario:" />
            <Label layoutX="292.0" layoutY="149.0" text="Oggetto:" />
        </children>
    </AnchorPane>
</children>

我使用 Scene Builder 制作了它们,我需要将它们分开保存,因为我更喜欢为每个控制器单独保存一个文件。 编辑:

编辑2: 这是第一个 AnchorPane(右侧可以看到设置): 这是第二个 AnchorPane 这是文本区域:

【问题讨论】:

  • 为什么不能使用BorderPane 或任何其他layout
  • 因为我应该重新设计所有应用程序并修改所有 fxml 文件。如您所见,使用 AnchorPane,我已经将所有元素定位在需要它们的位置
  • 尝试在窗口中添加鼠标事件过滤器以查看实际的EventTarget 是什么。如果它不是 ListView 或其子节点之一,那么您可能有一些节点与它重叠。
  • @Slaw “重叠”是指一个元素在另一个元素上?因为我试图单独添加它们并且如果我设置前两个元素它可以工作,但是一旦我设置了文本区域和文本字段,我就不能再点击前两个元素了。我将编辑问题以向您显示应用程序的输出。
  • 某些节点可能仍与其他节点重叠,即使您看不到它。添加用于加载 FXML 文件的代码,以便我们可以在我们自己的机器上运行/调试您的应用程序(即包括 minimal reproducible example)。

标签: java javafx fxml


【解决方案1】:

AnchorPane 是最糟糕的布局之一,如果您正在设计响应式布局,因为它不允许您在定位孩子时考虑其他孩子的大小(除非您使用侦听器/绑定更新布局参数)。

在这种特定情况下,您的问题是您的button.fxml 涵盖了其他 fxmls 的所有内容,因此接收了所有MouseEvents。要可视化 fxml 覆盖的区域,只需将此属性添加到 button.fxml 的根:style="-fx-background-color: rgba(0, 0, 255, 0.5)"

一种可能的解决方法是使子 fxml 尽可能小并在父 fxml 中指定根位置:

确定内部&lt;AnchorPane&gt; 的孩子的最小layoutXlayoutY,为根设置这些值(或将它们添加到根的先前值)并从所有孩子中减去这些值内&lt;AnchorPane&gt;

<!-- specify min layoutX/Y as position for root -->
<AnchorPane xmlns="http://javafx.com/javafx/8"
    xmlns:fx="http://javafx.com/fxml/1"
    layoutX="268"
    layoutY="200"
    fx:controller="mailbox.ButtonController">
    <children>
        <AnchorPane>
            <children>
                <!-- subtract root layoutX/Y from positions -->
                <Button id="scrivi" mnemonicParsing="false" prefHeight="27.0"
                    prefWidth="65.0" text="Scrivi" />
                <Button id="reply" layoutX="74" mnemonicParsing="false"
                    prefHeight="27.0" prefWidth="65.0" text="Reply" />
                <Button id="replyall" layoutX="152" mnemonicParsing="false"
                    prefHeight="27.0" prefWidth="75.0" text="Reply-All" />
                <Button id="forward" layoutX="243" mnemonicParsing="false"
                    prefHeight="27.0" prefWidth="75.0" text="Forward" />
            </children>
        </AnchorPane>
    </children>
</AnchorPane>

(对其他 fxml 进行相应处理。)

以这种方式覆盖节点仍然是一个糟糕的想法,因为您使用的是绝对位置,并且对其中一个 fxmls 的任何修改都可能需要您更新多个其他文件以避免覆盖。根据操作系统/设置,更糟糕的是看起来会有所不同。对于一个操作系统,场景可能看起来不错,而在另一个操作系统上,您的节点可能会重叠。
出于这个原因,我建议避免使用绝对定位,除非您 100% 确定节点大小是已知的。使用BorderPane/HBox/VBox 和/或GridPane 可以更好地创建如图所示的场景...

【讨论】:

  • 非常感谢!现在我唯一不能选择的是列表视图,如果我正确理解了您的代码,您是否通过查看第一个按钮的位置来设置 AnchorPane 的尺寸?所以对于列表视图,我应该选择一个 layoutX="1.0" 和一个 layoutY="31.0"?
  • @SamoaJoe button.fxml 只是最顶层的孩子。您需要确保在包含ListView 的那个之后没有孩子覆盖ListView。这是通过识别最左边的坐标(最小 layoutX)和最顶部的坐标(最小 layoutY),为 fxml 根设置这些值并从窗格中包含的所有元素的属性中减去它们来完成的。
  • 我应该考虑元素的 prefHeight 和 prefWidth 吗?还是只是布局?
  • 我们正在尝试找到合适的容器左上角坐标,所以不,宽度和高度无关紧要。
  • 我发现了问题,就是textArea。我试图像这样编辑它&lt;AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mailbox.TextAreaController"&gt; &lt;children&gt; &lt;AnchorPane&gt; &lt;children&gt; &lt;TextArea id="textarea" layoutX="255.0" layoutY="255.0" prefHeight="144.0" prefWidth="330.0" /&gt; &lt;/children&gt; &lt;/AnchorPane&gt; &lt;/children&gt; &lt;/AnchorPane&gt;
    在场景生成器中,它显示 AnchorPane 比 textarea 大得多。我将编辑问题以向您展示问题
猜你喜欢
  • 2014-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-04
  • 2020-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多