スタイル付きテキストを表示するために TextFlow といくつかの Text アイテムを使用していますが、Textアイテムに単純な背景色を設定する方法が見つかりません。
塗りつぶしの色とフォントを設定できますが、背景色を設定する Java メソッドまたは CSS プロパティがありません。
スタイル付きテキストを表示するために TextFlow といくつかの Text アイテムを使用していますが、Textアイテムに単純な背景色を設定する方法が見つかりません。
塗りつぶしの色とフォントを設定できますが、背景色を設定する Java メソッドまたは CSS プロパティがありません。
このソリューションに基づいて、これはText
内のすべてのノードに背景色を提供するメソッドの迅速な実装であり、 CSS と、コンマ(項目と同じくらい) でFlowPane
区切られた一連のペイント値とそれぞれのインセットを設定する機能を使用します。そのうちの: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()+";");
}
これにより、次のようになります。
シーンのサイズを変更した後:
編集
TextFlow
の代わりにレイアウトを使用するという OP 要求に基づいて、FlowPane
ノード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
。