如果注释掉行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);
}
}
}
答案 0 :(得分: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并没有真正反映底层列表的状态。但是在那里使用null设置器,一切都正确同步。这是一个问题...
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);
}
}
}