当前位置: 首页 > 知识库问答 >
问题:

在自定义JavaFX FXML控件上添加特定节点的列表

唐照
2023-03-14

我试图在JavaFX中创建一个工具栏来使用FXML添加按钮,如下所示:

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

<?import java.lang.*?>
<?import java.net.*?


<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import com.supridatta.javafx.*?>

<BorderPane xmlns:fx="http://javafx.com/fxml/1" prefHeight="200" prefWidth="320" fx:controller="com.supridatta.javafx.MainController">
    <stylesheets>
        <URL value="@main.css"/>
    </stylesheets>
    <top>
        <com.supridatta.javafx.ButtonBar fx:id="buttonBar">
            <buttons>
                <ButtonBarButton path="/com/supridatta/javafx/icons/plus.png"/>
                <ButtonBarButton path="/com/supridatta/javafx/icons/minus.png"/>
                <ButtonBarButton path="/com/supridatta/javafx/icons/last.png"/>
            </buttons>
        </com.supridatta.javafx.ButtonBar>
    </top>
    <bottom>
        <Button text="Exibir todos" onAction="#showAllButtons"/>
    </bottom>
</BorderPane>

下面是相应的java类:

package com.supridatta.javafx;

import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;

public class ButtonBar extends StackPane {

    private final HBox contentPane = new HBox();
    private final ObservableList<ButtonBarButton> buttons = FXCollections.observableArrayList();

    public ButtonBar() {
        initButtonBar();
    }

    private void initButtonBar() {
        getChildren().add(contentPane);
        setAlignment(Pos.CENTER);
        buttons.addListener(new ListChangeListener<Node>() {

            @Override
            public void onChanged(ListChangeListener.Change<? extends Node> c) {
                while (c.next()) {
                    if (c.wasAdded()) {
                        for (Node node : c.getAddedSubList()) {
                            contentPane.getChildren().add(node);
                        }
                    }
                    if (c.wasRemoved()) {
                        for (Node node : c.getAddedSubList()) {
                            contentPane.getChildren().remove(node);
                        }
                    }
                }
            }
        });
    }

    public void setButtons(ObservableList<ButtonBarButton> contents) {
        this.buttons.setAll(contents);
    }

    public ObservableList<ButtonBarButton> getButtons() {
        return buttons;
    }

    public void addButton(ButtonBarButton button) {
        buttons.add(button);
    }

    public void removeButton(ButtonBarButton button) {
        buttons.remove(button);
    }

}

当我运行这个项目时,我得到了这个异常

java.lang.IllegalArgumentException: Unable to coerce ButtonBarButton@2fd0ac8f[styleClass=button ButtonBarButton]'' to

interface javafx.collections.ObservableList.

提前谢谢。

共有1个答案

明越
2023-03-14

由于定义了setButtons方法,因此FXMLLoader将尝试传入

如果您有一个返回列表的getButton()方法,而没有setButton方法,那么FXMLLoader将执行您想要的操作,并将每个元素对应的值传递给调用的add方法在调用getButton()的结果上。即它确实如此

getButtons().add(new ButtonBarButton(...));
getButtons().add(new ButtonBarButton(...));
...

你要么想让它这么做,要么你想让它这么做

   setButtons(FXCollections.observableArrayList(new ButtonBarButton(...), new ButtonBarButton(...), ...)); 

因此,您有两个修复方法:从按钮栏中删除设置按钮(…)方法,或者安排传入可观察列表

        <buttons>
            <FXCollections fx:factory="observableArrayList">
                <ButtonBarButton path="/com/supridatta/javafx/icons/plus.png"/>
                <ButtonBarButton path="/com/supridatta/javafx/icons/minus.png"/>
                <ButtonBarButton path="/com/supridatta/javafx/icons/last.png"/>
            </FXCollections>
        </buttons>

 类似资料:
  • 我对覆盆子皮和结节红很陌生。我想添加自定义节点到firebase使用节点-红色节点。下面是我的数据库截图: 我已经使用firebase节点的push选项来创建多个具有自动生成ID的节点。我想在node-red中使用firebase节点给出自定义ID,如“user1”、“user2”等。如何才能做到这一点。

  • 我想创建一个自定义控件,在其中我可以设置另一个自定义控件的列表,并且我想能够像在JavaFXTableView中一样使用FXML(请参见列列表): 我只想写这样的东西: 我已经知道如何实现简单的自定义控件,但我还没有找到任何关于以这种方式组合自定义控件的方法。你能给我指个方向吗?

  • 自定义控件用JavaScript和原生平台支持的语言编写。它们使用原生Tabris.js客户端的接口,并被封装在Cordova插件中。本文将介绍JavaScript的实现部分。 用JavaScript定义自定义控件 自定义控件必须继承自Widget。它能够与自定义控件的原生部分进行通信。 自定义控件类必须覆写_nativeType属性的getter以返回与原生实现匹配的类型: class MyCu

  • PyQt5 有丰富的组件,但是肯定满足不了所有开发者的所有需求,PyQt5 只提供了基本的组件,像按钮,文本,滑块等。如果你还需要其他的模块,应该尝试自己去自定义一些。 自定义组件使用绘画工具创建,有两个基本方式:根据已有的创建或改进;通过自己绘图创建。 Burning widget 这个组件我们会在 Nero,K3B,或者其他 CD/DVD 烧录软件中见到。 #!/usr/bin/python3

  • 问题内容: 我想将自定义搜索端点添加到我现有的用户存储库中。 我的用户存储库如下所示: 定制控制器: 这将为用户返回正确的搜索端点: 但是对于其他端点,例如Invites: 如何将其仅限于用户?谢谢 问题答案: 我假设您的邀请端点也返回?!每当spring-data- rest序列化a时,都会调用your 。如果您想为用户提供不同的链接并邀请您,则可以选择以下方法: 为搜索端点使用不同的返回类型,

  • 问题内容: 我已经构建了自己的自定义react-bootstrap Popover组件: 该组件的呈现方式如下: 现在,我想向组件中添加自定义道具,例如:我的文字,并使用新道具在弹出框中设置一些内容,例如- 但随后我在浏览器中收到此警告: 警告:标签上的未知道具。从元素中删除这些道具。 现在,我想我可以删除零件并逐个插入所有原始道具,而无需自定义道具,但是这样我就失去了“淡入淡出”效果,这也是处理