2016-11-09 113 views
0

我有這個簡單的代碼:JavaFX的表視圖行上色

import javafx.application.Application; 
import javafx.beans.property.BooleanProperty; 
import javafx.beans.property.SimpleBooleanProperty; 
import javafx.beans.property.SimpleObjectProperty; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableRow; 
import javafx.scene.control.TableView; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 

public class Example extends Application 
{ 
    @Override 
    public void start(Stage stage) throws Exception 
    { 
     TableView<Integer> table = new TableView<>(); 

     TableColumn<Integer, Integer> column = new TableColumn<>(); 
     column.setCellValueFactory(param -> new SimpleObjectProperty<>(param.getValue())); 
     ObservableList<Integer> items = FXCollections.observableArrayList(); 
     table.getColumns().add(column); 
     table.setItems(items); 
     table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); 

     for (int i = 0; i < 500; i++) 
      items.add((int) (Math.random() * 500)); 

     BooleanProperty disable = new SimpleBooleanProperty(); 

     table.setRowFactory(param -> 
     { 
      TableRow<Integer> row = new TableRow<>(); 

      row.disableProperty().bind(disable); 

      row.disableProperty().addListener((observable, oldValue, newValue) -> 
      { 
       if (newValue) 
        row.setStyle("-fx-background-color: red"); 
       else 
        row.setStyle(""); 
      }); 

      return row; 
     }); 

     Button button = new Button("Disable all rows"); 
     button.setOnAction(event -> disable.set(true)); 

     stage.setScene(new Scene(new VBox(table, button))); 
     stage.show(); 
    } 

    public static void main(String[] args) 
    { 
     launch(args); 
    } 
} 

當我運行它,然後按下按鈕,就應該顏色的所有行。它可以工作,直到你向下滾動表格。然後,一些奇怪的事情開始發生,有些行不會變得豐富多彩,當您向後滾動時,它們將變得豐富多彩,而其他一些行則不會。

但是當你先滾動,然後按下按鈕,它會正常工作。我不知道那裏發生了什麼,這對我來說似乎是一個錯誤。

在原始代碼中,我需要禁用某些行,因爲我需要禁用表格複選框。儘管如此,即使我們將disable屬性切換到editable屬性也不起作用。

有沒有人有一個想法如何解決這個問題,爲什麼它不工作?

回答

1

當您滾動時,表格可能需要創建幾行。如果在按下按鈕後創建行,則您將第一個綁定新行的disable屬性到您創建的布爾屬性(因此該行的disable屬性設置爲true),然後您向該行註冊了一個偵聽器禁用更改樣式的屬性。由於行的禁用屬性在註冊偵聽器後永遠不會更改,因此永遠不會調用它,並且樣式永遠不會更改。

你可以做

table.setRowFactory(param -> 
    { 
     TableRow<Integer> row = new TableRow<>(); 

     row.disableProperty().addListener((observable, oldValue, newValue) -> 
     { 
      if (newValue) 
       row.setStyle("-fx-background-color: red"); 
      else 
       row.setStyle(""); 
     }); 

     row.disableProperty().bind(disable); 

     return row; 
    }); 

,或者你也可以只使用一個直接綁定:

table.setRowFactory(param -> 
    { 
     TableRow<Integer> row = new TableRow<>(); 

     row.styleProperty().bind(Bindings 
      .when(disable) 
      .then("-fx-background-color: red;") 
      .otherwise("")); 

     row.disableProperty().bind(disable); 

     return row; 
    }); 

,或者你可以使用一個外部的樣式表

.table-row-cell:disabled { 
    -fx-background-color:red ; 
} 

,並省略聽衆/完全綁定風格:

table.setRowFactory(param -> 
{ 
    TableRow<Integer> row = new TableRow<>(); 

    row.disableProperty().bind(disable); 

    return row; 
});