问题描述
我正在编写一个显示JavaFX表的程序。我理解如何通过Column.setCellFactory(TextFieldTableCell.forTableColumn());来编辑特定列中的所有数据;
I am writing a program that displays a JavaFX table. I understand how to make all the data in a specific column editable via "Column.setCellFactory(TextFieldTableCell.forTableColumn());"
但是我想做一些细胞可编辑,其他细胞不可变。这可能吗?此外,我希望可编辑单元格具有边框或具有唯一的字体颜色。
However I would like to make some of the cells editable and others immutable. Is this possible? Moreover, I would like editable cells to either have a border or have a unique font color.
推荐答案
是的,这是可能的: TableCell
有一个,继承自 Cell
类。您需要安排单元格在项目更改时相应地设置其可编辑属性(并且可能在条件控制何时应该可编辑时更改)。
Yes, this is possible: the TableCell
has an editable
property inherited from the Cell
class. You need to arrange that the cell sets its editable property accordingly when the item changes (and possibly if the condition governing when it should be editable changes).
在下面的示例中,我使用 TextFieldTableCell.forTableColumn()
创建一个默认的单元工厂,然后创建另一个单元工厂。自定义单元工厂调用默认单元工厂(以获取标准 TextField
行为),然后观察 itemProperty
单元格并相应地更新 editableProperty
(在这个简单的示例中,只有具有偶数值
的单元格是可编辑的)。
In the example below, I create a default cell factory using TextFieldTableCell.forTableColumn()
, and then create another cell factory. The custom cell factory invokes the default cell factory (to get the standard TextField
behavior), then observes the itemProperty
of the cell and updates the editableProperty
accordingly (in this simple example, only cells with an even value
are editable).
要添加边框,您需要以某种方式更新样式。最好的方法是为editable定义一个伪类,并使用外部样式表来管理可编辑单元格的样式。
To add the border, you need to update the style somehow. The best way to do this is to define a pseudoclass for "editable" and use an external style sheet to manage the style for editable cells.
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);
}
}
样式表,条件可编辑表格单元格.css:
And the stylesheet, conditionally-editable-table-cell.css:
.table-cell:editable {
-fx-border-color: red ;
}
这篇关于在JavaFX tableview中使单个单元格可编辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!