我正在编写一个显示JavaFX表的程序。我了解如何通过“Column.setCellFactory(TextFieldTableCell.forTableColumn());”编辑特定列中的所有数据;“
但是我想让一些单元格可编辑而其他单元格不可变。这可能吗?此外,我希望可编辑单元格具有边框或具有唯一的字体颜色。
答案 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 ;
}