- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想知道如何在没有 ObservableProperty 的情况下使用 CheckBoxTableCell。我使用一个简单的 boolean 值,因为我想将数据序列化到我的 DerbyDB。
当然,有可能创建一个 SimpleBooleanProperty 并用 @Transient
对其进行注释,并将其包裹在我的正常 boolean active
周围。
我的 boolean 值显示正确,但在单击表格 View 中的复选框后我无法存储新值。
private void setupColActive() {
colActive.setCellValueFactory(new PropertyValueFactory<UserVillage, Boolean>("active"));
colActive.setCellFactory(CheckBoxTableCell.forTableColumn(colActive));
colActive.setEditable(true);
}
我已经尝试过将 colActive.setOnEditCancel
、colActive.setOnEditCommit
和 colActive.setOnEditStart
与打印轮廓结合使用,但我无法捕获新值来存储它。我想找到一种方法使其正常工作,而无需包装到 @Transient SimpleBooleanProperty active
中。
最佳答案
序列化问题不会阻止您在模型类 UserVillage
中使用 JavaFX 属性。我建议使用这些属性,并通过定义 readObject 和 writeObject 方法来自定义序列化机制。这是这样定义的类的演示:
public class Item implements Serializable {
private StringProperty name ;
private IntegerProperty value ;
private BooleanProperty active ;
public Item(String name, int value, boolean active) {
this.name = new SimpleStringProperty(name) ;
this.value = new SimpleIntegerProperty(value);
this.active = new SimpleBooleanProperty(active);
}
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 final BooleanProperty activeProperty() {
return this.active;
}
public final boolean isActive() {
return this.activeProperty().get();
}
public final void setActive(final boolean active) {
this.activeProperty().set(active);
}
private void writeObject(ObjectOutputStream out) throws IOException {
out.writeObject(getName());
out.writeInt(getValue());
out.writeBoolean(isActive());
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
this.name = new SimpleStringProperty((String)in.readObject());
this.value = new SimpleIntegerProperty(in.readInt());
this.active = new SimpleBooleanProperty(in.readBoolean());
}
// Quick test:
public static void main(String[] args) throws IOException, ClassNotFoundException {
Item testItem = new Item("Item", 42, true);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(testItem);
oos.close();
byte[] bytes = out.toByteArray();
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes));
Item result = (Item) in.readObject();
System.out.println(result.getName());
System.out.println(result.getValue());
System.out.println(result.isActive());
}
}
通过这种方法,CheckBoxTableCell
将自动绑定(bind)到 PropertyValueFactory
返回的属性。
另一种方法是创建一个 BooleanProperty
专门用于绑定(bind)到复选框选定状态。请注意,根据Javadocs ,因为 CheckBoxTableCell
永远不会进入或离开编辑状态,因此永远不会调用编辑回调 onEditCommit
等:
Note that the CheckBoxTableCell renders the CheckBox 'live', meaning that the CheckBox is always interactive and can be directly toggled by the user. This means that it is not necessary that the cell enter its editing state (usually by the user double-clicking on the cell). A side-effect of this is that the usual editing callbacks (such as on edit commit) will not be called. If you want to be notified of changes, it is recommended to directly observe the boolean properties that are manipulated by the CheckBox.
这是使用此技术的演示。再说一遍,我并不真正推荐这种方法,因为您最终会创建一堆可以快速进行垃圾回收的 BooleanProperty
。预期的方法是让模型使用 JavaFX 属性。
import java.util.stream.IntStream;
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class TableViewCheckBoxTest extends Application {
@Override
public void start(Stage primaryStage) {
TableView<Item> table = new TableView<>();
table.setEditable(true);
table.getColumns().add(createColumn("Name", "name"));
table.getColumns().add(createColumn("Value", "value"));
TableColumn<Item, Boolean> activeCol = createColumn("Active", "active");
table.getColumns().add(activeCol);
activeCol.setCellFactory(col -> {
CheckBoxTableCell<Item, Boolean> cell = new CheckBoxTableCell<>(index -> {
BooleanProperty active = new SimpleBooleanProperty(table.getItems().get(index).isActive());
active.addListener((obs, wasActive, isNowActive) -> {
Item item = table.getItems().get(index);
item.setActive(isNowActive);
});
return active ;
});
return cell ;
});
Button listActiveButton = new Button("List active");
listActiveButton.setOnAction(e ->
table.getItems().stream()
.filter(Item::isActive)
.map(Item::getName)
.forEach(System.out::println));
IntStream.rangeClosed(1, 100)
.mapToObj(i -> new Item("Item "+i, i, false))
.forEach(table.getItems()::add);
BorderPane root = new BorderPane(table, null, null, listActiveButton, null) ;
BorderPane.setAlignment(listActiveButton, Pos.CENTER);
BorderPane.setMargin(listActiveButton, new Insets(10));
Scene scene = new Scene(root, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
private <S,T> TableColumn<S,T> createColumn(String title, String propertyName) {
TableColumn<S,T> col = new TableColumn<>(title);
col.setCellValueFactory(new PropertyValueFactory<>(propertyName));
return col;
}
public static class Item implements Serializable {
private String name ;
private int value ;
private boolean active ;
public Item(String name, int value, boolean active) {
this.name = name ;
this.value = value ;
this.active = active ;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
}
public static void main(String[] args) {
launch(args);
}
}
关于JavaFX TableView CheckBoxTableCell 使用 boolean 值而不是 SimpleBooleanProperty,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32172084/
我正在开发一个简单的 Java 程序来执行一些简单的 mySQL 操作。它有一个用 JavaFX 制作的小 GUI。 GUI的 Controller 有一个SimpleBooleanProperty,
我想知道如何在没有 ObservableProperty 的情况下使用 CheckBoxTableCell。我使用一个简单的 boolean 值,因为我想将数据序列化到我的 DerbyDB。 当然,有
如果我这样做: BooleanProperty b = new SimpleBooleanProperty(); b.setValue(null); System.out.println(b.getV
我是一名优秀的程序员,十分优秀!