简体   繁体   English

在 javaFX TextField 中设置文本颜色“不使用 CSS”

[英]Setting text color in javaFX TextField "Without using CSS"

If you're going to suggest CSS then don't bother, I know it works fine and is so easy to use, this is just out of curiosity and because I hate dealing with CSS while coding in Java.如果您打算推荐 CSS,请不要打扰,我知道它运行良好且易于使用,这只是出于好奇,因为我讨厌在用 Java 编码时处理 CSS。

JavaFX TextField undirectly extends Parent which has an "unmodifiable" ObservableList of children of type Node, and one of them has to be of type Text, so I have extended the TextField class and written two methods to check, this method to get all the children out of the TextField. JavaFX TextField 间接扩展了 Parent,它有一个 Node 类型的“不可修改”的 ObservableList,其中一个必须是 Text 类型,所以我扩展了 TextField 类并编写了两个方法来检查,这个方法来获取所有的孩子出文本字段。

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;
}

This one is to print out the result.这是打印结果。

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('}');
}

The result is quite as expected.结果完全符合预期。

size = 3 {
    Path
    Text
    Path
}

So I have written this method to get only the Text object.所以我编写了这个方法来只获取 Text 对象。

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;
}

It worked fine and returned a Text object.它工作正常并返回一个 Text 对象。

So I only needed to setFill and I would be done.所以我只需要 setFill 就可以了。

public void setTextFill(Paint p) {
    findText(this).setFill(p);
}

But whenever I try to set the textFill I get a RuntimeException that says:但是每当我尝试设置 textFill 时,我都会收到一个 RuntimeException ,上面写着:

Text.fill : A bound value cannot be set

That's a little long to keep up with for only setting the color for a text.仅设置文本的颜色就有点长了。

Any kind of help is appreciated.任何形式的帮助表示赞赏。

The internals of Control s are hidden on purpose. Control的内部是故意隐藏的。 In this case the text fill of the Text node is kept up to date using a binding.在这种情况下, Text节点的文本填充使用绑定保持最新。 Unless you unbind the fill property of the node before setting it ( text.fillProperty().unbind() ), setting the value will fail.除非您在设置节点之前取消绑定它的fill属性( text.fillProperty().unbind() ),否则设置值将失败。

If you want to mess around with them, you should do so using the Skin .如果你想弄乱它们,你应该使用Skin Assuming you use JavaFX version 9 or later, the skin for TextField is part of the public API and you can access the textFill property by extending it:假设您使用 JavaFX 版本 9 或更高版本, TextField的外观是公共 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();
}

If you want a subtype of TextField with a public fill property, add such a JavaFX property to your subclass and override the createDefaultSkin method to return a subclass of TextFieldSkin creating a binding for for it's textFill property.如果您想要具有公共fill属性的TextField子类型,请将此类 JavaFX 属性添加到您的子类并覆盖createDefaultSkin方法以返回TextFieldSkin的子类,从而为其textFill属性创建绑定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM