我正在研究表示机器人控制程序的TreeView
,每个TreeCell
表示一条语句,并且TreeCell
可以嵌套在另一个程序中。像在编程中一样,语句可以嵌套在if
或for
语句中。
在这里,我创建了一个简单的演示,其中填充了一些随机块。
Demo Screenshot
为了自定义TreeCell
的呈现,我创建了一个扩展TreeCell
的类:
public class TreeDataCell extends TreeCell<TreeData> {
public void updateItem(TreeData item, boolean empty) {
super.updateItem(item, empty);
setText(null);
if (item == null || empty) {
setGraphic(null);
} else {
setGraphic(getCellGraphic(item));
}
}
private Group getCellGraphic(TreeData data) {
Group grp = new Group();
VBox vbox = new VBox();
vbox.setMinWidth(100);
vbox.setMaxWidth(200);
vbox.setBorder(new Border(new BorderStroke(
Color.LIGHTGRAY.darker(),
BorderStrokeStyle.SOLID,
new CornerRadii(10.0),
new BorderWidths(2.0))));
vbox.setBackground(new Background(new BackgroundFill(Color.LIGHTGRAY, new CornerRadii(10.0), null)));
vbox.setEffect(new DropShadow(2.0, 3.0, 3.0, Color.DIMGRAY));
Region header = new Region();
header.setPrefHeight(5.0);
Region footer = new Region();
footer.setPrefHeight(5.0);
Label labTitle = new Label();
labTitle.setFont(new Font("San Serif", 20));
labTitle.setText(data.getTitle());
Label labDesc = null;
if (data.getDescription() != null) {
labDesc = new Label();
labDesc.setWrapText(true);
labDesc.setText(data.getDescription());
}
vbox.getChildren().addAll(header, labTitle);
if (labDesc != null) {
vbox.getChildren().add(labDesc);
}
vbox.getChildren().add(footer);
grp.getChildren().add(vbox);
return grp;
}
}
TreeData
是包含2个String
的简单类:public class TreeData {
private String title;
private String desc;
/* getters + setters */
}
如您所见,两个级别之间的缩进太小了,我们几乎看不到语句嵌套。
由于尚未学习FXML + CSS,因此我正在用Java编写所有样式的代码。
我想知道是否可以在Java中设置缩进的大小吗?我找不到用于此目的的任何API。另外,是否可以在父节点及其子节点之间画线,例如
JTree
中的Swing
?谢谢。
最佳答案
关于JTree
中的行,从JavaFX 11开始,没有内置的方式可以做到这一点。有一个功能请求(JDK-8090579),但似乎没有实现它的任何计划。您也许可以自己实现它,但我不确定如何实现。
至于修改TreeCell
的缩进,最简单的方法是使用CSS。
如JavaFX CSS Reference Guide中所述,TreeCell
具有一个名为-fx-indent
的CSS属性,其值为<size>
。您可以使用样式表设置此属性,也可以通过style
property内联该属性。使用内联样式的示例:
public class TreeDataCell extends TreeCell<TreeData> {
public TreeDataCell() {
setStyle("-fx-indent: <size>;");
}
}
但是,由于您当前未使用CSS或FXML,因此还有另一个纯粹是代码的选项:修改
indent
的TreeCellSkin
属性。该类在JavaFX 9中成为公共API。JavaFX8中可能有等效的内部API,但我不确定。默认情况下,
Skin
的TreeCell
将是TreeCellSkin
的实例。这意味着您可以获取此外观并根据需要设置缩进值。但是,您必须要小心,因为皮肤是懒惰的。在TreeView
实际上是显示窗口的一部分之前,它不一定可用。如果只想设置一次属性,一种方法是拦截
createDefaultSkin()
内部的皮肤:public class TreeDataCell extends TreeCell<TreeData> {
@Override
protected Skin<?> createDefaultSkin() {
TreeCellSkin<?> skin = (TreeCellSkin<?>) super.createDefaultSkin();
skin.setIndent(/* your value */);
return skin;
}
}
您还可以扩展
TreeCellSkin
并对其进行自定义。只要记住要覆盖createDefaultSkin()
并返回自定义外观即可。