如何将DoubleProperty绑定到JavaFX中其他两个DoubleProperty的差异?

如何将DoubleProperty绑定到JavaFX中其他两个DoubleProperty的差异?,javafx,Javafx,我有一个自定义单元格的列表视图:这些单元格由一个标签和一个删除按钮组成 我希望标签的PreferedWidthProperty始终等于ListView的宽度减去按钮的宽度 因此,在自定义单元格类的updateItem中,我添加了以下代码: label.prefWidthProperty().bind(listViewWidth.subtract(delButton.widthProperty())); 但这样,按钮的宽度就不会被减除,标签的宽度就等于ListView的宽度:一个水平滚动条出现,

我有一个自定义单元格的列表视图:这些单元格由一个标签和一个删除按钮组成

我希望标签的PreferedWidthProperty始终等于ListView的宽度减去按钮的宽度

因此,在自定义单元格类的updateItem中,我添加了以下代码:

label.prefWidthProperty().bind(listViewWidth.subtract(delButton.widthProperty()));
但这样,按钮的宽度就不会被减除,标签的宽度就等于ListView的宽度:一个水平滚动条出现,按钮就在框架之外

经过一点测试后,在执行此代码时,按钮的宽度似乎等于零(因为按钮本身尚未显示),但从未重新计算:它始终保持为零,因此子部分始终等于ListView未修改的宽度

如何强制绑定始终等于这些对象当前值的减法

编辑: 我想要的是这种极其简单的外观:

即:

  • 每行由一个标签和一个按钮组成
  • 按钮在这条线的尽头
  • 文本上升到按钮并换行,没有水平滚动条
我得到的是:

文本很好地包装了。。。。但是标签有ListView的宽度,因此按钮超出了框架,需要滚动以删除该行,这看起来有点可笑

我的工厂很简单:

fx_listBoxMain.setCellFactory(new Callback<ListView<String>, ListCell<String>>()
{
    @Override
    public ListCell<String> call(ListView<String> param)
    {
    DeletableCell result = null;
    try
    {
        result = new DeletableCell();
    }
    catch (IOException e)
    {
        //Deal with that case as soon as the basics are working
    }
    return result;
    }
});
fx_listBoxMain.setCellFactory(新回调()
{
@凌驾
公共ListCell调用(ListView参数)
{
DeletableCell result=null;
尝试
{
结果=新的可删除单元格();
}
捕获(IOE异常)
{
//一旦基本工作开始,立即处理该案件
}
返回结果;
}
});
“可删除单元格”由以下fxml充气:

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<HBox fx:controller="DeletableCellController"  xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
    <children>
    <Label fx:id="fx_labelView" wrapText="true"/>
    <Button fx:id="fx_delButton" mnemonicParsing="false" text="X" onAction="#deleteAction" />
    </children>
</HBox>

这是一个非常简单的HBox,有一个标签和一个按钮,我希望标签的宽度是包含列表视图的宽度减去按钮的宽度


我需要设置PreferedWidth属性,因为如果没有它,文本将不会换行,而且我会有更难看的东西:只有一条长线的标签和一个巨大的水平滚动条。因此,我环顾四周,想知道如何避免这种情况,发现您需要设置PreferedWidth,因为wrapText=“true”不足以做到这一点。

设置单元格的
HBox的
MaxWidthProperty
应该可以做到这一点。我们将该值绑定到
ListView
的宽度减去
ListView
填充的宽度:

maxWidthProperty().bind(listView.widthProperty().subtract(25));
下面是一个演示它的快速示例程序。这确实用Java(而不是FXML)构建了定制的
ListCell
,但总体思路是相同的

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ListCellWrap extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        // Simple Interface
        VBox root = new VBox(10);
        root.setAlignment(Pos.CENTER);
        root.setPadding(new Insets(10));

        ListView<String> listView = new ListView<>();

        // Sample data
        listView.getItems().addAll(
                "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
                "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
        );

        // Override the ListCell
        listView.setCellFactory(lv -> new ListCell<String>() {

            // Create our cell's layout
            final Label label = new Label() {{
                setWrapText(true);
            }};
            final Button button = new Button("X") {{
                setOnAction(event -> {
                    // Processing here
                });
            }};

            final HBox root = new HBox(5, label, button) {{
                maxWidthProperty().bind(listView.widthProperty().subtract(25));
            }};

            @Override
            protected void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);

                if (item == null || empty) {
                    setGraphic(null);
                } else {
                    label.setText(item);
                    setGraphic(root);
                }
            }
        });

        root.getChildren().add(listView);

        // Show the stage
        primaryStage.setScene(new Scene(root));
        primaryStage.setTitle("Sample");
        primaryStage.show();
    }
}
导入javafx.application.application;
导入javafx.geometry.Insets;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.Label;
导入javafx.scene.control.ListCell;
导入javafx.scene.control.ListView;
导入javafx.scene.layout.HBox;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
公共类ListCellWrap扩展了应用程序{
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
公共无效开始(阶段primaryStage){
//简单接口
VBox根=新的VBox(10);
根部设置对齐(位置中心);
根。设置填充(新插图(10));
ListView ListView=新建ListView();
//样本数据
listView.getItems().addAll(
“知识本身是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德。”有时,如果你不自以为是,就必须为自己的行为负责。”,
“知识本身是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德,是一种美德。”有时,如果你不自以为是,就必须为自己的行为负责。”
);
//覆盖列表单元格
setCellFactory(lv->new ListCell()){
//创建我们单元的布局
最终标签=新标签(){{
setWrapText(真);
}};
最终按钮=新按钮(“X”){{
设置操作(事件->{
//在这里处理
});
}};
最终HBox根=新HBox(5,标签,按钮){{
maxWidthProperty().bind(listView.widthProperty().subtract(25));
}};
@凌驾
受保护的void updateItem(字符串项,布尔值为空){
super.updateItem(项,空);
如果(项==null | |空){
设置图形(空);
}否则{
label.setText(项目);
设定图形(根);
}
}
});
root.getChildren().add(listView);
//上台
primaryStage.setScene(新场景(根));
初级阶段。设置标题(“样本”);
primaryStage.show();
}
}
结果:


设置单元格的
HBox
MaxWidthProperty
应该可以实现这一点。我们将该值绑定到
ListView
的宽度减去
ListView
pa的宽度