javafx - 如何将 DoubleProperty 绑定到 JavaFX 中其他两个 DoubleProperty 的差异?
问题描述
我有一个带有自定义单元格的 ListView:这些单元格由一个标签和一个删除按钮组成。
我希望 Label 的 PreferedWidthProperty 始终等于 ListView 的宽度减去按钮的宽度。
因此,在自定义单元类的 updateItem 中,我添加了以下代码:
label.prefWidthProperty().bind(listViewWidth.subtract(delButton.widthProperty()));
但是这样一来, Button 的宽度并没有减去,标签的宽度等于 ListView 的宽度:出现水平滚动条,并且按钮超出了框架。
经过一些测试,在执行此代码时按钮的宽度似乎等于零(因为按钮本身尚未显示)但它永远不会重新计算:它始终保持为零,因此 substration 总是等于 ListView 的未修改宽度。
如何强制绑定始终等于减去这些对象的当前值?
那是 :
- 每行由一个标签和一个按钮组成
- 按钮位于行尾
- 文本上升到按钮并换行,没有水平滚动条。
文本换行好了....但是 Label 具有 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;
}
});
“DeletableCell”从以下 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" 不足以做到这一点。
解决方案
设置MaxWidthProperty
单元格的HBox
应该可以做到这一点。我们将该值绑定到宽度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();
}
}
结果:
推荐阅读
- linux - 每次更改 bashrc 目录时列出所有文件的脚本?
- c# - 将非 void 方法声明为 lambda
- git - Git 忽略已编译的 CSS,但保留最新版本的生产就绪状态
- vhdl - 用 Yosys 合成 verilog
- java - 测试 java 程序是否调用 System.exist - 不退出 Junit
- angular - pouchdb-find 操作很慢
- android-studio - Android Studio 不渲染布局并引发异常
- php - php curl 输出 ehco 它自己
- javascript - Javascript Timing:是否有可能以及如何将变量传递给 setTimeout() 和 setInterval() 的第二个参数?
- forms - 在滚动或单击多部分表单中的“下一步”按钮之前,需要为表单字段填写或提供空字段警报吗?