在JavaFx / TableView中,是否可以为文本获取具有多种颜色的TableCell?我使用'Text'尝试了以下代码,其中每个字符都是RED / BLUE / RED / BLUE ......但是单元格仍然是黑色。
(...)
tableColumn.setCellFactory(tc -> new TableCell<MyObject, String>() {
@Override
protected void updateItem(final String item, boolean empty) {
super.updateItem(item, empty);
if(item==null) return;
this.setText(item);
final List<Text> L=new ArrayList<>(item.length());
for(int i=0;i< item.length();++i) {
final Text txt=new Text(String.valueOf(item.charAt(i)));
txt.setStroke(i%2==0?Color.RED:Color.BLUE);
L.add(txt);
}
this.getChildren().setAll(L);
}
});
(...)
有没有办法实现这个目标?感谢。
答案 0 :(得分:1)
创建TextFlow
以保存Text
个实例并将其设置为单元格的图形。另请注意,您有一个错误(如果从表的列表中删除项目,或者滚动时可能会显而易见):如果单元格为空,则需要清除文本和图形。
tableColumn.setCellFactory(tc -> new TableCell<MyObject, String>() {
final TextFlow textFlow = new TextFlow();
@Override
protected void updateItem(final String item, boolean empty) {
super.updateItem(item, empty);
if(item==null) {
setText(null);
setGraphic(null);
return ;
}
this.setText(item);
final List<Text> L=new ArrayList<>(item.length());
for(int i=0;i< item.length();++i) {
final Text txt=new Text(String.valueOf(item.charAt(i)));
txt.setStroke(i%2==0?Color.RED:Color.BLUE);
L.add(txt);
}
textFlow.getChildren().setAll(L);
setGraphic(textFlow);
}
});
这是一个SSCCE:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;
public class TableWithAlternateColorText extends Application {
private final Random rng = new Random();
private final String[] bases = "ACGT".split("") ;
@Override
public void start(Stage primaryStage) {
TableView<StringProperty> table = new TableView<>();
TableColumn<StringProperty, String> col = new TableColumn<>("Sequence");
col.setCellValueFactory(CellDataFeatures::getValue);
col.setCellFactory(tc -> new TableCell<StringProperty, String>() {
final TextFlow textFlow = new TextFlow();
@Override
protected void updateItem(final String item, boolean empty) {
super.updateItem(item, empty);
if(item==null) {
setText(null);
setGraphic(null);
return ;
}
List<Text> texts = new ArrayList<>();
for(int i=0;i< item.length();++i) {
char base = item.charAt(i);
final Text txt=new Text(String.valueOf(base));
txt.setStroke(isPyrimidine(base) ? Color.RED : Color.BLUE);
texts.add(txt);
}
textFlow.getChildren().setAll(texts);
setGraphic(textFlow);
setPrefHeight(textFlow.prefHeight(-1));
}
});
table.getColumns().add(col);
for (int i = 0 ; i < 100 ; i++) {
table.getItems().add(new SimpleStringProperty(randomSequence(20)));
}
primaryStage.setScene(new Scene(table, 600, 600));
primaryStage.show();
}
private boolean isPyrimidine(char base) {
return base == 'C' || base == 'T' ;
}
private String randomSequence(int seqLength) {
return rng.ints(seqLength, 0, bases.length)
.mapToObj(i -> bases[i])
.collect(Collectors.joining());
}
public static void main(String[] args) {
launch(args);
}
}