2015-04-05 212 views

回答

4

基于此solution,这是一个快速实现的方法,以提供背景FlowPane内着色所有Text节点,使用CSS和设置由commas分开的一系列涂料值的能力(高达Text项目),插图为他们每个人:

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

这将导致这样的:

Flow1

和调整大小后的场景:

Flow2

EDIT

基于使用TextFlow布局代替FlowPane的OP请求,因为Text节点可以一个TextFlow内跨越了几行,给定的解决方案将不再有效,因为每个文本节点的边界框将与其他边界框重叠。

作为一种变通方法,我们可以在一个单词拆分Text节点Text节点,同时保持相同的背景色为那些在相同的原始短语。

我不会进入拆分逻辑,但我会添加一个索引列表,其中每个索引都将文本节点与其背景颜色索引进行映射。

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

Flow3

+0

很好的解决方法谢谢!但是,当输入文本逐渐显现时,这会变得非常缓慢。在我的情况下,它是一个MUD的输出,它基本上是使用ANSI颜色的telnet协议。 – 2015-04-05 11:39:48

+0

嗯,这是一个解决方法......你有多少个“文本”节点? – 2015-04-05 11:43:11

+0

不完全是我想要的,因为您使用的FlowPane不会自动打破长行,并且当我将其更改为TextFlow时,颜色会变得混乱。 – 2015-04-05 11:52:51

2

Text对象没有背景。你必须将它与一个形状(矩形,椭圆等)分组,并设置该形状的颜色,或者你可以把对象放在一个StackPane中,并设置StackPane的背景颜色。

+0

没有IM细跟TextFlow的,问题是[文本](https://docs.oracle.com/javafx/ 2/api/javafx/scene/text/Text.html)对象。 – 2015-04-05 02:45:42

+0

该问题询问如何设置“文本”对象的背景,而不是“TextFlow”对象。 – 2015-04-05 02:46:39

+0

糟糕。你是对的。我误解了这个问题。我的错!我更新并修复了我的答案,以回答这次的正确问题! – 2015-04-05 02:57:02