首页 文章

在JavaFX Scene Builder中加载带有自定义组件的FXML文件:重置属性并删除子项

提问于
浏览
5

我写了一个FXML文件,我在其中使用自定义组件,扩展了Group . 加载此自定义组件时,应该将一些子项(此处为:MyOverlayIcon)添加到其子列表中,并按代码设置一些属性(此处为:layoutX和layoutY) .

MyIcon.java:

public class MyIcon extends Group {

/********************************
 * Graphic
 ********************************/
private ImageView graphic;
public ImageView getGraphic() {
    if(graphic == null) {
        graphic = new ImageView();
        getChildren().add(graphic);
        // Send image to back:
        graphic.toBack();
    }
    return graphic;
}

/********************************
 * DataPath
 ********************************/
private Property<String> dataPath;
public Property<String> dataPathProperty() {
    if (dataPath == null) {
        dataPath = new SimpleStringProperty();
    }
    return dataPath;
}
public String getDataPath() {
    return dataPathProperty().getValue();
}
public void setDataPath(String dataPath) {

    this.dataPathProperty().setValue(dataPath);
    getGraphic().setImage(new Image(dataPath));
}

/********************************
 * Overlays
 ********************************/
private ObservableList<MyOverlayIcon> overlays;
public ObservableList<MyOverlayIcon> getOverlays() {
    if (overlays == null) {
        overlays = FXCollections.observableArrayList();
        overlays.addListener(new ListChangeListener<MyOverlayIcon>() {

            @Override
            public void onChanged(ListChangeListener.Change<? extends MyOverlayIcon> c) {
                double moveX = 0.0;
                double moveY = 0.0;
                double iconWidth = 48.0;
                double iconHeight = 48.0;

                ObservableList<? extends MyOverlayIcon> icons = c.getList();
                MyOverlayIcon icon = icons.get(icons.size() - 1);

                String orientation = icon.getOrientation().toString(); 

                if(orientation.endsWith("EAST")) {
                    moveX = iconWidth / 2; 
                }
                if(orientation.startsWith("SOUTH")) {
                    moveY = iconHeight / 2;
                }

                icon.setLayoutX(moveX);
                icon.setLayoutY(moveY);
                getChildren().add(icon);
            }
        });
    }
    return overlays;
}

/********************************
 * Constructor
 ********************************/
public MyIcon(){}
}

MyOverlayIcon.java:

public class MyOverlayIcon extends MyIcon {

private EnumOrientation orientation;
public EnumOrientation getOrientation() {
    return orientation;
}
public void setOrientation(EnumOrientation orientation) {
    this.orientation = orientation;
    }

public MyOverlayIcon() {}
}

MyIconView.fxml:

<Group xmlns:fx="http://javafx.com/fxml">

    <MyIcon dataPath="@/images/User1_48.png">
        <overlays>
            <MyOverlayIcon dataPath="@/images/Remove_24.png" orientation="SOUTHWEST" />
            <MyOverlayIcon dataPath="@/images/Search1_24.png" orientation="NORTHEAST" />
        </overlays>
    </MyIcon>

</Group>

当我在IDE中启动应用程序时,使用FXMLLoader加载此fxml文件,它可以正常工作:所有新子项都添加并正确显示:

enter image description here

现在我想用Scene Builder修改这个fxml文件 . 但是当我使用Scene Builder加载文件时,我只看到一个空的组实例:

enter image description here

我发现只有这两种解决方法:

1.)调用明确地将子项添加到子列表的方法(例如,在属性的setter方法中),添加并显示子项,但仅在通过修改某些内容而不是在开始时调用此setter时文件已加载 .

2.)在调试模式下运行Scene Builder时,我发现,我想要以编程方式修改的任何属性必须先在fxml中指定 . 否则,Scene Builder会将其值设置为默认值 .

例如,我通过java代码动态添加的子项,如果组件未在fxml中指定任何子节点,则再次添加和删除 . 在fxml中只将任何空节点(如Pane)添加到我的组件中,子节点不会被删除,也会在Scene Builder中显示 .

对于其他属性,它只是相同的:应该由代码设置的值(此处:layoutX和layoutY)仅在我使用任何值在fxml文件中设置时才应用 .

MyIconView_Workaround.fxml:

<Group xmlns:fx="http://javafx.com/fxml">

    <MyIcon dataPath="@/images/User1_48.png">
        <Pane />
        <overlays>
            <MyOverlayIcon dataPath="@/images/Remove_24.png" orientation="SOUTHWEST" layoutY="456">
                <Pane />
            </MyOverlayIcon>
            <MyOverlayIcon dataPath="@/images/Search1_24.png" orientation="NORTHEAST"  layoutX="123">
                <Pane />
            </MyOverlayIcon>
        </overlays>
    </MyIcon>

</Group>

enter image description here

//编辑:如果看不到链接的图像,请尝试this gallery link .


有没有人知道如何使用包含自定义组件的Scene Builder加载fxml文件,该组件通过java代码动态地将子项添加到自身并修改它们(或其)的属性值而不在fxml中指定它们?

1 回答

  • 2

    我从半年前找到了_1761540 .

    有人说,这是一个错误,我发现在最新版本的场景构建器(Scene Builder 1.1 Early Access)中,它是固定的 .

    有了这个版本,一切正常 . :)

    谢谢你的帮助!

相关问题