2017-02-12 1 views
0

В JavaFx/TableView можно ли получить TableCell с несколькими цветами для текста? Я пробовал следующий код, используя «Текст», где каждый символ будет в RED/BLUE/RED/BLUE ... но ячейки остаются черными.Jfx/TableColumn.setCellFactory с несколькими цветами в одном TableCell

(...) 
    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 экземпляров и установить его как графический элемент для ячейки. Также обратите внимание, что у вас есть ошибка (это станет очевидным, если вы удалите элементы из списка таблицы или, возможно, прокрутите их): вам нужно очистить текст и графику, если ячейка пуста.

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

Смежные вопросы