在JavaFX tableview中使单个单元格可编辑

时间:2015-02-09 16:46:05

标签: javafx javafx-8

我正在编写一个显示JavaFX表的程序。我了解如何通过“Column.setCellFactory(TextFieldTableCell.forTableColumn());”编辑特定列中的所有数据;“

但是我想让一些单元格可编辑而其他单元格不可变。这可能吗?此外,我希望可编辑单元格具有边框或具有唯一的字体颜色。

1 个答案:

答案 0 :(得分:3)

是的,这是可能的:TableCell有一个editable property继承自Cell类。您需要安排单元格在项目更改时相应地设置其可编辑属性(并且可能在管理应该可编辑的条件发生更改时)。

在下面的示例中,我使用TextFieldTableCell.forTableColumn()创建默认单元工厂,然后创建另一个单元工厂。自定义单元工厂调用默认单元工厂(以获取标准TextField行为),然后观察单元的itemProperty并相应地更新editableProperty(在此简单示例中,仅显示单元格)偶数value是可编辑的。

要添加边框,您需要以某种方式更新样式。最好的方法是为“editable”定义一个伪类,并使用外部样式表来管理可编辑单元格的样式。

import java.util.function.Function;

import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.css.PseudoClass;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;

public class ConditionallyEditableTableCell extends Application {

    @Override
    public void start(Stage primaryStage) {
        TableView<Item> table = new TableView<>();

        table.setEditable(true);

        TableColumn<Item, String> nameCol = createCol("Name", Item::nameProperty);
        TableColumn<Item, Number> canEditCol = createCol("Value", Item::valueProperty);

        PseudoClass editableCssClass = PseudoClass.getPseudoClass("editable");

        Callback<TableColumn<Item, String>, TableCell<Item, String>> defaultTextFieldCellFactory 
            = TextFieldTableCell.<Item>forTableColumn();

        nameCol.setCellFactory(col -> {
            TableCell<Item, String> cell = defaultTextFieldCellFactory.call(col);
            cell.itemProperty().addListener((obs, oldValue, newValue) -> {
                TableRow row = cell.getTableRow();
                if (row == null) {
                    cell.setEditable(false);
                } else {
                    Item item = (Item) cell.getTableRow().getItem();
                    if (item == null) {
                        cell.setEditable(false);
                    } else {
                        cell.setEditable(item.getValue() % 2 == 0);
                    }
                }
                cell.pseudoClassStateChanged(editableCssClass, cell.isEditable());
            });
            return cell ;
        });

        table.getColumns().addAll(canEditCol, nameCol);

        for (int i=1; i<=20; i++) {
            table.getItems().add(new Item("Item "+i, i));
        }

        Scene scene = new Scene(new BorderPane(table), 600, 400);

        scene.getStylesheets().add("conditionally-editable-table-cell.css");

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

    private <S,T> TableColumn<S,T> createCol(String title, Function<S, ObservableValue<T>> property) {
        TableColumn<S,T> col = new TableColumn<>(title);
        col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
        return col ;
    }

    public static class Item {
        private final IntegerProperty value = new SimpleIntegerProperty();
        private final StringProperty name = new SimpleStringProperty();


        public Item(String name, int value) {
            setName(name);
            setValue(value);
        }

        public final StringProperty nameProperty() {
            return this.name;
        }
        public final java.lang.String getName() {
            return this.nameProperty().get();
        }
        public final void setName(final java.lang.String name) {
            this.nameProperty().set(name);
        }

        public final IntegerProperty valueProperty() {
            return this.value;
        }
        public final int getValue() {
            return this.valueProperty().get();
        }
        public final void setValue(final int value) {
            this.valueProperty().set(value);
        }
    }

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

样式表,conditionally-editable-table-cell.css:

.table-cell:editable {
    -fx-border-color: red ;
}