Text JavaFX:设置文本控件的背景色

Text JavaFX:设置文本控件的背景色,text,background,javafx,textflow,Text,Background,Javafx,Textflow,我正在使用一个文本流和一些文本项来显示一个样式化的文本,但是我找不到一种方法来为这些项设置一个简单的背景色 我可以设置填充颜色和字体,但它没有设置背景颜色的java方法或css属性。文本对象没有背景。您可以将其与形状(矩形、椭圆等)组合并设置该形状的颜色,也可以将对象放在StackPane中并设置StackPane的背景色。基于此,这是一种快速实现的方法,用于为流程窗格中的所有文本节点提供背景着色,使用CSS和设置一系列绘制值的功能,这些绘制值由(多达文本项)分隔,并为每个绘制值插入: priv

我正在使用一个文本流和一些文本项来显示一个样式化的文本,但是我找不到一种方法来为这些项设置一个简单的背景色


我可以设置填充颜色和字体,但它没有设置背景颜色的java方法或css属性。

文本对象没有背景。您可以将其与形状(矩形、椭圆等)组合并设置该形状的颜色,也可以将对象放在StackPane中并设置StackPane的背景色。

基于此,这是一种快速实现的方法,用于为
流程窗格
中的所有
文本
节点提供背景着色,使用CSS和设置一系列绘制值的功能,这些绘制值由(多达
文本
项)分隔,并为每个绘制值插入:

private FlowPane flow;
private Scene scene;

@Override
public void start(Stage primaryStage) {
    Text text0 = new Text("These are several ");
    Text text1 = new Text("Text Nodes ");
    Text text2 = new Text("wrapped in ");
    Text text3 = new Text("a FlowPane");
    text0.setFill(Color.WHEAT);
    text0.setFont(new Font("Times New Roman", 20));
    text1.setFill(Color.WHITE);
    text1.setFont(new Font("Verdana", 32));
    text2.setFill(Color.WHITESMOKE);
    text2.setFont(new Font("Arial", 24));
    text3.setFill(Color.WHITESMOKE);
    text3.setFont(new Font("Arial", 18));

    flow = new FlowPane(text0, text1, text2, text3);
    scene = new Scene(flow, 300, 200);

    primaryStage.setTitle("Hello World!");
    primaryStage.setScene(scene);
    primaryStage.show();

    setBackgroundColors();
    flow.needsLayoutProperty().addListener((obs,d,d1)->setBackgroundColors());        
}

private void setBackgroundColors(){
    final Bounds out = flow.getBoundsInLocal();
    final StringBuilder sbColors = new StringBuilder();
    final StringBuilder sbInsets = new StringBuilder();
    AtomicInteger cont = new AtomicInteger();
    flow.getChildrenUnmodifiable().forEach(n->{
        sbColors.append("hsb(")
                .append((((double)cont.get())/((double)flow.getChildren().size()))*360d)
                .append(", 60%, 90%)");
        Bounds b = ((Text)n).getBoundsInParent();
        sbInsets.append(b.getMinY()).append(" ");
        sbInsets.append(Math.min(scene.getWidth(),out.getMaxX())-b.getMaxX()).append(" ");
        sbInsets.append(Math.min(scene.getHeight(),out.getMaxY())-b.getMaxY()).append(" ");
        sbInsets.append(b.getMinX());
        if(cont.getAndIncrement()<flow.getChildren().size()-1){
            sbColors.append(", ");
            sbInsets.append(", ");
        }
    });
    flow.setStyle("-fx-background-color: "+sbColors.toString()+"; -fx-background-insets: "+sbInsets.toString()+";");
}
private FlowPane flow;
private Scene scene;

private final List<Integer> indices=Arrays.asList(0,0,0,1,1,2,2,3,3);

@Override
public void start(Stage primaryStage) {
    List<Text> text0 = Arrays.asList(new Text("These "), new Text("are "), new Text("several "));
    List<Text> text1 = Arrays.asList(new Text("Text "), new Text("Nodes "));
    List<Text> text2 = Arrays.asList(new Text("wrapped "), new Text("in "));
    List<Text> text3 = Arrays.asList(new Text("a "), new Text("FlowPane"));
    text0.forEach(t->t.setFill(Color.WHEAT));
    text0.forEach(t->t.setFont(new Font("Times New Roman", 20)));
    text1.forEach(t->t.setFill(Color.WHITE));
    text1.forEach(t->t.setFont(new Font("Verdana", 32)));
    text2.forEach(t->t.setFill(Color.WHITESMOKE));
    text2.forEach(t->t.setFont(new Font("Arial", 24)));
    text3.forEach(t->t.setFill(Color.WHITESMOKE));
    text3.forEach(t->t.setFont(new Font("Arial", 18)));

    flow = new FlowPane();
    flow.getChildren().addAll(text0);
    flow.getChildren().addAll(text1);
    flow.getChildren().addAll(text2);
    flow.getChildren().addAll(text3);
    scene = new Scene(flow, 300, 200);

    primaryStage.setTitle("Hello World!");
    primaryStage.setScene(scene);
    primaryStage.show();

    setBackgroundColors();
    flow.needsLayoutProperty().addListener((obs,d,d1)->setBackgroundColors());        
}

private void setBackgroundColors(){
    final Bounds out = flow.getBoundsInLocal();
    final StringBuilder sbColors = new StringBuilder();
    final StringBuilder sbInsets = new StringBuilder();
    AtomicInteger cont = new AtomicInteger();
    flow.getChildrenUnmodifiable().forEach(n->{
        sbColors.append("hsb(")
                .append((double)indices.get(cont.get())/(double)(indices.get(flow.getChildren().size()-1)+1)*360d)
                .append(", 60%, 90%)");
        Bounds b = ((Text)n).getBoundsInParent();
        sbInsets.append(b.getMinY()).append(" ");
        sbInsets.append(Math.min(scene.getWidth(),out.getMaxX())-b.getMaxX()-1).append(" ");
        sbInsets.append(Math.min(scene.getHeight(),out.getMaxY())-b.getMaxY()).append(" ");
        sbInsets.append(b.getMinX());
        if(cont.getAndIncrement()<flow.getChildren().size()-1){
            sbColors.append(", ");
            sbInsets.append(", ");
        }
    });
    flow.setStyle("-fx-background-color: "+sbColors.toString()+"; -fx-background-insets: "+sbInsets.toString()+";");
}
FlowPane
现在的行为类似于
TextFlow


不,我对TextFlow没意见,问题是对象。问题是如何设置
Text
对象的背景,而不是
TextFlow
object.Oops。是的,你是对的。我误解了这个问题。我的错!这次我更新并修正了我的答案以回答正确的问题!这并没有达到预期的效果,TextFlow将StackPane视为单个对象,而不是像TextFlow自动包装的文本对象。在我的应用程序中,我只需要突出显示单个简短的单词,因此StackPane是最简单的解决方案。但我发现TextFlow会在突出显示的单词后面增加额外的行距。经过多次修改后,我发现在Text对象上执行setLayoutY(10)不会影响文本的位置,但可以防止额外的行距。我不知道为什么:)很好的解决方法谢谢!但是,当输入文本逐渐出现时,这会变得非常缓慢。在我的例子中,它是MUD的输出,基本上是带有ANSI颜色的telnet协议。。。你有多少个
Text
节点?不完全是我想要的,因为你使用了一个不会自动打断长线的流程窗格,当我将其更改为一个可以这样做的TextFlow时,颜色会变得混乱。好吧,你可以数上千个节点,也许XD我改变了主意,我将使用WebView并逐步向其中添加html节点。它没有使用javascript那么快,必须在JavaFX线程中完成,但仍然比使用大量文本对象的TextFlow好。是的,它不适用于
TextFlow
,因为每个
Text
节点可以跨多行,其边界框与其他节点重叠。使用
FlowPane
可以将
文本
节点拆分为较小的节点(保持它们的背景色相同)。无论如何,这对于大量节点来说太慢了。