簡體   English   中英

JavaFX:使用自定義樣式表將文本顏色應用於TableCell?

[英]JavaFX: Apply text color to TableCell using custom style sheet?

JavaFX: 如何使用自定義樣式表將文本顏色應用於TableCell?

當我直接在我的CellFactory中使用setTextFill()時,它工作正常,但我想使用外部CSS文件應用自定義樣式。 我可以證明我的CSS類已應用,因為字體變為粗體。 但是,不應用CSS文件的字體顏色。

@Override
protected void updateItem(MyObject item, boolean empty) {
    super.updateItem(item, empty);

    if (null != item) {        
        // EITHER:
        this.getStyleClass().add("styleImportant"); // Does NOT set color.

        // OR:
        this.setTextFill(Color.RED); // Does set color.
    }
    else {
        this.getStyleClass().remove("styleImportant");
    }

}

樣式表:

.styleImportant {
    -fx-font-weight: bold; /** Does work. */
    -fx-text-fill: red; /** Does NOT work. */
}

它在某種程度上與CSS選擇器的特異性有關,但我沒有找到任何有效的設置。


編輯:我設法使用CSS同時應用自定義文本顏色和背景顏色。 我的實現現在使用包裹在VBoxLabel來使背景顏色填充整個表格單元格。 但是,在刪除自定義樣式時,仍然存在一些未清除背景顏色的問題。

有沒有比應用清晰風格更好的解決方案?

colExample.setCellFactory(new Callback<TableColumn<Example, Example>, TableCell<Example, Example>>() {
  @Override
  public TableCell<Example, Example> call(TableColumn<Example, Example> tableColumn) {
     return new TableCell<Example, Example>() {
        private VBox container;
        private Label text;

        // Anonymous constructor
        {
           this.container = new VBox();
           this.text = this.createLabel();

           this.container.getChildren().add(this.text);
           this.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
           this.setStyle("-fx-padding: -1 -1 -1 -1;"); // Remove padding from cell

           this.setGraphic(this.container);
        }

        private final Label createLabel() {
           Label label = new Label();

           VBox.setVgrow(label, Priority.ALWAYS);
           label.setMaxWidth(Double.MAX_VALUE);
           label.setMaxHeight(Double.MAX_VALUE);
           label.setAlignment(Pos.CENTER);

           return label;
        }

        @Override
        protected void updateItem(Example example, boolean empty) {
           super.updateItem(example, empty);

           // Reset column styles
           if (null != this.text && null != this.text.getStyleClass()) {
              String[] possibleStyles = new String[] { "styleImportant", "clearStyle" };

              for (String style: possibleStyles) {
                 if (this.text.getStyleClass().contains(style)) {
                    // Will not reset background, even though style is removed?
                    this.text.getStyleClass().remove(style);
                 }
              }

              // Apply reset style to clear background color
              this.text.getStyleClass().add("clearStyle");
           }

           if (null != example) {
              this.text.setText(example.getContent());

              if (example.isImportant()) {
                 this.text.getStyleClass().add("styleImportant");
              }
           }
        }
     };
  }
});

我的樣式表:

/** Keep black text color, when user selects row */
.table-row-cell:focused {
   -fx-dark-text-color: #000000;
   -fx-mid-text-color: #000000;
   -fx-light-text-color: #000000;
}

/** Style to reset background color */
.clearStyle {
   -fx-background-color: transparent;
}

/** Style for important cells */
.styleImportant {
   /** Red text color on any background */
   -fx-dark-text-color: #FF0000;
   -fx-mid-text-color: #FF0000;
   -fx-light-text-color: #FF0000;

   -fx-background-color: #FF9999;
}

正如José在他的回答中指出的那樣,如果你在單元格中設置圖形,你(可能)需要將css樣式類應用於圖形(取決於圖形是什么)。 如果您只是調用setText(...)您的代碼應該可以工作。

設置為圖形的Label不會從表格單元格繼承-fx-text-fill的原因是Label還具有-fx-text-fill 在默認樣式表中, TableCellLabel都具有以下設置:

-fx-text-fill: -fx-text-background-color ;

fx-text-background-color是一種被定義為梯形的查找顏色 ,如下所示:

-fx-text-background-color: ladder(
    -fx-background,
    -fx-light-text-color 45%,
    -fx-dark-text-color  46%,
    -fx-dark-text-color  59%,
    -fx-mid-text-color   60%
);

這個(相當復雜的)設置意味着-fx-text-background-color的值取決於-fx-background的值。 如果-fx-background小於最大強度的45%(即它是暗的),則-fx-text-background-color值設置為-fx-light-text-color 如果-fx-background強度介於46%和59%之間,則該值等於-fx-drak-text-color 如果它是60%或更多,則設置為-fx-mid-text-color 這里的想法是文本顏色將自動調整為背景以保持可見。 -fx-dark-text-color-fx-mid-text-color-fx-light-text-color分別設置為黑色,深灰色(#333)和白色。

由於Label不會覆蓋-fx-text-background-color的值,因此只需更改表格單元格的值即可實現所需:

.styleImportant {
    -fx-text-background-color: red ;
}

現在,這將覆蓋表格單元格的查找顏色值,並且由於單元格內的圖形本身不會覆蓋該值,因此它會從單元格繼承該值。

更復雜的方法是重新定義-fx-[light|mid|dark]-text-color s。 這樣做的好處是,如果更改背景,顏色將適當調整:特別是如果選擇了單元格,則可以確保文本保持可見:

.styleImportant {
    -fx-light-text-color: white ;
    -fx-mid-text-color:   #c00 ;
    -fx-dark-text-color:  red ;
}

由於我不知道單元格中的對象類型,我將使用Label

這就是你在做什么:

@Override
public void start(Stage primaryStage) {
    TableView<Label> table = new TableView<>();
    TableColumn<Label,String> column = new TableColumn<>();
    column.setCellValueFactory(param -> param.getValue().textProperty());
    column.setCellFactory((TableColumn<Label, String> param) -> {
        TableCell<Label, String> cell = new TableCell<Label, String>(){

            @Override
            protected void updateItem(String item, boolean empty){
                super.updateItem(item, empty);
                if(!empty){
                    this.getStyleClass().add("styleImportant");
                    Label label = new Label(item);
                    setGraphic(label);
                }
            }
        };
        return cell;
    });
    table.getColumns().add(column);
    ...
}

這將為您提供粗體文字,但黑色。

如果您想要一個帶有紅色文本的對象(在我的情況下是一個Label ),請將樣式表應用於該對象:

            @Override
            protected void updateItem(String item, boolean empty){
                super.updateItem(item, empty);
                if(!empty){
                    Label label = new Label(item);
                    label.getStyleClass().add("styleImportant");
                    setGraphic(label);
                }
            }

編輯

這是示例的完整代碼:

@Override
public void start(Stage primaryStage) {
    TableView<Label> table = new TableView<>();

    ObservableList<Label> data = FXCollections.observableArrayList(
             new Label("Some Text"), new Label("Some More Text"));

    TableColumn<Label,String> column = new TableColumn<>("Column");
    column.setCellValueFactory(param -> param.getValue().textProperty());
    column.setCellFactory((TableColumn<Label, String> param) -> {
        TableCell<Label, String> cell = new TableCell<Label, String>(){

            @Override
            protected void updateItem(String value, boolean empty){
                super.updateItem(value, empty);

                if(!empty){
                    Label label = new Label(value);
                    label.getStyleClass().add("styleImportant");
                    setGraphic(label);
                } else {
                    setGraphic(null);
                } 
            }
        };
        return cell;
    });
    column.setPrefWidth(100);
    table.getColumns().add(column);

    table.setItems(data);

    Scene scene = new Scene(table, 300, 250);
    scene.getStylesheets().add(getClass().getResource("table.css").toExternalForm());
    primaryStage.setScene(scene);
    primaryStage.show();

}

table.css中的位置:

.styleImportant {
    -fx-font-weight: bold;
    -fx-text-fill: red;
}

運行此簡短示例應如下所示:

風格標簽

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM