在 javaFX TextField 中设置文本颜色 "Without using CSS"
Setting text color in javaFX TextField "Without using CSS"
如果你要建议 CSS 那就别费心了,我知道它很好用而且很容易使用,这只是出于好奇,因为我讨厌和 [=38 打交道=] 在 Java.
中编码
JavaFX TextField 间接扩展了 Parent,它有一个 "unmodifiable" ObservableList of children 类型的节点,其中之一必须是文本类型,所以我已经扩展了 TextField class 并编写了两个方法来检查,这个方法从 TextField 中获取所有 children。
public ArrayList<Node> getAllChildren(Parent parent) {
ArrayList<Node> res = new ArrayList<Node>();
for (Node n : parent.getChildrenUnmodifiable()) {
if (n instanceof Parent) {
res.addAll(getAllChildren((Parent) n));
} else {
res.add(n);
}
}
return res;
}
这个是打印结果的
public void printChildren() {
ArrayList<Node> nodes = getAllChildren(this);
System.out.println("size = "+nodes.size()+" {");
for (Node n : nodes) {
System.out.println(" "+n.getClass().getSimpleName());
}
System.out.println('}');
}
结果和预期的一样。
size = 3 {
Path
Text
Path
}
所以我写了这个方法来只获取文本object。
private Text findText(Parent parent) {
for (Node n : parent.getChildrenUnmodifiable()) {
if (n instanceof Text) {
return (Text) n;
} else if (n instanceof Parent) {
Text p = findText((Parent) n);
if (p != null) {
return p;
}
}
}
return null;
}
它工作正常并返回了文本 object。
所以我只需要设置填充就可以了。
public void setTextFill(Paint p) {
findText(this).setFill(p);
}
但是每当我尝试设置 textFill 时,我都会收到一个 RuntimeException,上面写着:
Text.fill : A bound value cannot be set
仅设置文本颜色有点长。
感谢任何形式的帮助。
Control
的内部结构是有意隐藏的。在这种情况下,Text
节点的文本填充使用绑定保持最新。除非在设置之前解绑节点的fill
属性(text.fillProperty().unbind()
)否则设置值会失败
如果你想和他们打交道,你应该使用 Skin
。假设您使用 JavaFX 版本 9 或更高版本,TextField
的皮肤是 public API 的一部分,您可以通过扩展它来访问 textFill
属性:
@Override
public void start(Stage primaryStage) {
TextField textField = new TextField();
textField.setSkin(new TextFieldSkin(textField) {
{
// use red color for text
setTextFill(Color.RED);
}
});
StackPane root = new StackPane(textField);
Scene scene = new Scene(root, 500, 500);
primaryStage.setScene(scene);
primaryStage.show();
}
如果您想要 TextField
的子类型和 public fill
属性,请将这样的 JavaFX 属性 添加到您的子类并覆盖 createDefaultSkin
方法到 return TextFieldSkin
的子类,为其 textFill
属性.
创建绑定
如果你要建议 CSS 那就别费心了,我知道它很好用而且很容易使用,这只是出于好奇,因为我讨厌和 [=38 打交道=] 在 Java.
中编码JavaFX TextField 间接扩展了 Parent,它有一个 "unmodifiable" ObservableList of children 类型的节点,其中之一必须是文本类型,所以我已经扩展了 TextField class 并编写了两个方法来检查,这个方法从 TextField 中获取所有 children。
public ArrayList<Node> getAllChildren(Parent parent) {
ArrayList<Node> res = new ArrayList<Node>();
for (Node n : parent.getChildrenUnmodifiable()) {
if (n instanceof Parent) {
res.addAll(getAllChildren((Parent) n));
} else {
res.add(n);
}
}
return res;
}
这个是打印结果的
public void printChildren() {
ArrayList<Node> nodes = getAllChildren(this);
System.out.println("size = "+nodes.size()+" {");
for (Node n : nodes) {
System.out.println(" "+n.getClass().getSimpleName());
}
System.out.println('}');
}
结果和预期的一样。
size = 3 {
Path
Text
Path
}
所以我写了这个方法来只获取文本object。
private Text findText(Parent parent) {
for (Node n : parent.getChildrenUnmodifiable()) {
if (n instanceof Text) {
return (Text) n;
} else if (n instanceof Parent) {
Text p = findText((Parent) n);
if (p != null) {
return p;
}
}
}
return null;
}
它工作正常并返回了文本 object。
所以我只需要设置填充就可以了。
public void setTextFill(Paint p) {
findText(this).setFill(p);
}
但是每当我尝试设置 textFill 时,我都会收到一个 RuntimeException,上面写着:
Text.fill : A bound value cannot be set
仅设置文本颜色有点长。
感谢任何形式的帮助。
Control
的内部结构是有意隐藏的。在这种情况下,Text
节点的文本填充使用绑定保持最新。除非在设置之前解绑节点的fill
属性(text.fillProperty().unbind()
)否则设置值会失败
如果你想和他们打交道,你应该使用 Skin
。假设您使用 JavaFX 版本 9 或更高版本,TextField
的皮肤是 public API 的一部分,您可以通过扩展它来访问 textFill
属性:
@Override
public void start(Stage primaryStage) {
TextField textField = new TextField();
textField.setSkin(new TextFieldSkin(textField) {
{
// use red color for text
setTextFill(Color.RED);
}
});
StackPane root = new StackPane(textField);
Scene scene = new Scene(root, 500, 500);
primaryStage.setScene(scene);
primaryStage.show();
}
如果您想要 TextField
的子类型和 public fill
属性,请将这样的 JavaFX 属性 添加到您的子类并覆盖 createDefaultSkin
方法到 return TextFieldSkin
的子类,为其 textFill
属性.