2017-02-12 39 views
0

在JavaFx/TableView中,是否可以使用多種顏色的文本獲取TableCell?我試過以下代碼,使用'文本',其中每個字符都在紅色/藍色/紅色/藍色......但單元格保持黑色。在一個TableCell中有多種顏色的Jfx/TableColumn.setCellFactory

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

有什麼辦法可以做到這一點?謝謝。

回答

1

創建一個TextFlow來保存Text實例並將其設置爲單元的圖形。還要注意,你有一個bug(如果你從表格列表中刪除項目,或者如果你滾動的話,這個bug會變得明顯):如果單元格爲空,你需要清除文本和圖形。

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

enter image description here