2013-10-04 15 views
5

value.setCellFactory(NUMBER_CELL_FACTORY);という行がコメントアウトされていると、下のプログラムが正常に動作します。カスタムセルファクトリで空の行にコンテンツが表示される

しかし、含まれていると、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); 
     } 
    } 
} 
関連する問題