添加了以前在我所有子类中都可见的子节点,如此处的示例所示。
由于我最近做了一些更改(在非常旧的Java SWING代码的大量移植中),例如,TextField
或TextArea
中的子项仍然可见,但Button
中没有(ish)控件,即使添加内容在列表中。
显然,我并不了解有关增加子女的政策。有什么想法吗?
public class QButton extends Button {
...
public QButton(String str) {
...
ObservableList<Node> children = getChildren();
System.out.println("Children: " + children);
Rectangle rect = new Rectangle(0., 0., 200., 200.);
rect.setStroke(Color.RED);
rect.setFill(Color.TRANSPARENT);
rect.setStrokeWidth(2);
getChildren().add(rect);
rect.setVisible(true);
children = getChildren();
System.out.println("Children: " + children);
}
...
答案 0 :(得分:3)
在JavaFX中,UI控件使用MVC(模型/视图/控制器)模式。 Control本身(例如Button
)是Model,渲染被委托给在JavaFX中称为Skin的View。 Control的节点图由View(Skin)维护,因此无法简单地修改Control的子节点。有关架构的详细概述,请参阅https://wiki.openjdk.java.net/display/OpenJFX/UI+Controls+Architecture。
另一种方法可能是将Button
和Rectangle
放入Group
,以便Rectangle
覆盖Button
,然后使用{ {1}}在应用程序的场景图中。
否则,如果您真的想要继承Group
并在其中添加Button
,则需要为Rectangle
创建自定义外观。以下示例显示了如何完成此操作 - 一个缺点是Buttons(Button
)的基础外观类不是公共的,因此您需要扩展非公共类(您通常不应该这样做,但是除了复制来自ButtonSkin
的一大堆代码之外,我目前还没有看到其他选择。在Java 9中,皮肤类将在com.sun.javafx
包中公开(请参阅
javafx.scene.control.skin
的{{3}}。
以下代码显示了如何完成:
ButtonSkin
基本上,package com.example;
import javafx.scene.control.Button;
import javafx.scene.control.Skin;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
// DO NOT DO THIS - com.sun is not public!
// (However, it seems that there is currently no alternative besides duplicating the code)
// With Java 9, change to javafx.scene.control.skin.ButtonSkin
class QButtonSkin extends com.sun.javafx.scene.control.skin.ButtonSkin {
private Rectangle rect = null;
public QButtonSkin(Button button) {
super(button);
}
@Override
protected void updateChildren() {
super.updateChildren();
if (rect == null) {
rect = new Rectangle(0., 0., 200., 200.);
rect.setStroke(Color.RED);
rect.setFill(Color.TRANSPARENT);
rect.setStrokeWidth(2);
}
getChildren().add(rect);
}
}
public class QButton extends Button {
public QButton(String str) {
super(str);
}
@Override
protected Skin<?> createDefaultSkin() {
Skin<?> result = new QButtonSkin(this);
return result;
}
}
会创建一个新的默认外观(您也可以在CSS中执行此操作)。新的Skin覆盖QButton
以将矩形添加到控件的子节点。这里我们需要考虑调用序列 - 超类的构造函数调用updateChildren()
本身,因此我们无法在Skin的构造函数中创建updateChildren()
。
根据您的使用情况,您可能需要添加一些其他代码,例如管理Rectangle
的边界和几何。