2013-10-04 96 views
5

下面的程序如果線路value.setCellFactory(NUMBER_CELL_FACTORY);被註釋掉工作正常空行。如果只包含TableView,那麼TableView的表現會很奇怪* - 如果您只需複製代碼,啓動它並在+按鈕上單擊幾次,您將看到表格底部的空行中會出現內容。內容出現在自定義電池廠

我錯過了什麼?

*測試上了JavaFx 8 - B106。

import javafx.application.Application; 
import javafx.beans.property.DoubleProperty; 
import javafx.beans.property.SimpleDoubleProperty; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.TableCell; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableView; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.layout.AnchorPane; 
import javafx.scene.layout.VBox; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 
import javafx.util.Callback; 

public class TestFX extends Application { 

    @Override 
    public void start(final Stage stage) throws Exception { 
     MyTable table = new MyTable(); 

     Scene scene = new Scene(table); 

     stage.setScene(scene); 
     stage.show(); 
    } 

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

    static class MyTable extends AnchorPane { 

     private static final Callback NUMBER_CELL_FACTORY = (p) -> new NumberTableCell<>(); 

     private final Button addRow = new Button("+"); 
     private final TableView<Item> table = new TableView<>(); 

     MyTable() { 
      super(); 
      initTableView(); 
      addRow.setOnMouseClicked((e) -> addItem()); 
      VBox vbox = new VBox(); 
      vbox.getChildren().addAll(addRow, table); 
      getChildren().add(vbox); 
     } 

     public void addItem() { 
      table.getItems().addAll(new Item()); 
     } 

     private void initTableView() { 
      TableColumn<Item, Double> value = new TableColumn<>("Value"); 
      value.setCellValueFactory(new PropertyValueFactory<>("value")); 
      value.setCellFactory(NUMBER_CELL_FACTORY); 

      table.getColumns().add(value); 
      table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); 
     } 
    } 

    public static class Item { 
     private final DoubleProperty value = new SimpleDoubleProperty(); 

     public DoubleProperty valueProperty() { 
      return value; 
     } 
    } 

    static class NumberTableCell<T> extends TableCell<T, Double> { 
     private final Color fill = Color.LIGHTGREY; 

     @Override 
     protected void updateItem(Double item, boolean empty) { 
      super.updateItem(item, empty); 
      if (empty) return; 
      setText(String.valueOf(item)); 
      setTextFill(fill); 
     } 
    } 
} 

回答

6

我試過Win7上Java7b108示例程序,它似乎很好地工作的NumberTableCell,但它仍然有一些問題。

的問題是,細胞被重用,所以如果一個細胞變成空的任何原因,你需要清除你在小區中設置的任何自定義值,以便它呈現像一個默認的空單元格。下面的代碼演示瞭如何做到這一點:

@Override 
    protected void updateItem(Double item, boolean empty) { 
     super.updateItem(item, empty); 
     if (empty || item == null) { 
      setText(null); 
      setTextFill(null); 
      return; 
     } 
     setText(String.valueOf(item)); 
     setTextFill(fill); 
    } 

這裏是一個小更新,你的程序,它更容易複製的問題,並演示了修復。如果註釋掉setText(null)和setTextFill(null)行,然後按幾次+按鈕,然後開始按下 - 按鈕,您將看到TableView並不真正反映基礎列表的狀態。但是在那裏有空設置器,一切都正確同步。這是一個疑難雜症......

import javafx.application.Application; 
import javafx.beans.property.*; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.*; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.layout.AnchorPane; 
import javafx.scene.layout.VBox; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 
import javafx.util.Callback; 

public class TestFX extends Application { 

    @Override 
    public void start(final Stage stage) throws Exception { 
     MyTable table = new MyTable(); 

     System.getProperties().list(System.out); 

     Scene scene = new Scene(table); 

     stage.setScene(scene); 
     stage.show(); 
    } 

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

    static class MyTable extends AnchorPane { 

     private static final Callback NUMBER_CELL_FACTORY = (p) -> new NumberTableCell<>(); 

     private final Button addRow = new Button("+"); 
     private final Button removeRow = new Button("-"); 
     private final TableView<Item> table = new TableView<>(); 

     MyTable() { 
      super(); 
      initTableView(); 
      addRow.setOnMouseClicked((e) -> addItem()); 
      removeRow.setOnMouseClicked((e) -> removeItem()); 
      VBox vbox = new VBox(5); 
      vbox.getChildren().addAll(addRow, removeRow, table); 
      getChildren().add(vbox); 
     } 

     public void addItem() { 
      table.getItems().addAll(new Item()); 
     } 

     public void removeItem() { 
      if (table.getItems().size() > 0) { 
       table.getItems().remove(0); 
      } 
     } 

     private void initTableView() { 
      TableColumn<Item, Double> value = new TableColumn<>("Value"); 
      value.setCellValueFactory(new PropertyValueFactory<>("value")); 
      value.setCellFactory(NUMBER_CELL_FACTORY); 

      table.getColumns().add(value); 
      table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); 
     } 
    } 

    public static class Item { 
     private final DoubleProperty value = new SimpleDoubleProperty(); 

     public DoubleProperty valueProperty() { 
      return value; 
     } 
    } 

    static class NumberTableCell<T> extends TableCell<T, Double> { 
     private final Color fill = Color.LIGHTGREY; 

     @Override 
     protected void updateItem(Double item, boolean empty) { 
      super.updateItem(item, empty); 
      if (empty || item == null) { 
       setText(null); 
       setTextFill(null); 
       return; 
      } 
      setText(String.valueOf(item)); 
      setTextFill(fill); 
     } 
    } 
}