2016-11-09 110 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; 
});