Samoa Joe
Samoa Joe

Reputation: 33

AnchorPane elements ignore Mouse click

I initialized some elements not my Anchor Pane:

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

But when I try to click on the MenuBar or the List View it doesn't works. For example, in this case I can click on the buttons (maybe) because it is the last element that I initialize in the AnchorPane constructor. I cannot use a BorderPane or any other Layout, so I need to find a solution with this configuration. These are my fxml files:

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="[email protected]" />
                            <MenuItem fx:id="email2" text="[email protected]" />
                            <MenuItem fx:id="email3" text="[email protected]" />
                        </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>

I made them with Scene Builder, I need to keep them separately because I prefer a singular file for each controller. EDIT: Output

EDIT2: This is the first AnchorPane (on the right you can see the settings): SB1 This is the second AnchorPane SB2 This is the Textarea: enter image description here

Upvotes: 0

Views: 545

Answers (1)

fabian
fabian

Reputation: 82461

AnchorPane is one of the worst layouts, if you're designing a responsive layout, since it does not allow you to take the size of other children into account, when positioning a child (except if you use listeners/bindings to update layout parameters).

Your problem in this specific case is that your button.fxml covers all the content of the other fxmls and therefore receives all the MouseEvents. To visualize the area the fxml covers, just add this attribute to the root of button.fxml: style="-fx-background-color: rgba(0, 0, 255, 0.5)".

A possible workaround would be making the child fxmls as small as possible and specifying the root position in the parent:

Identify the minimum layoutX and layoutY of the children of the inner <AnchorPane>, set those values for the root (or add them to previous values of the root) and subtract these values from all children of the the inner <AnchorPane>.

<!-- 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>

(Proceed accordingly with the other fxmls.)

It is still a terrible idea overlay nodes this way, since you're using absolute positions and any modification of one of the fxmls could require you to update multiple others to avoid overlays. Even worse looks different depending on the OS/settings. For one OS the scene could look fine, on another one one your nodes could overlap.
For this reason I recommend avoiding using absolute positioning, unless you're 100% sure the node sizes are known. A scene like the one shown is better created using BorderPane/HBox/VBox and/or GridPane...

Upvotes: 5

Related Questions