gpt4 book ai didi

JavaFX TableView CheckBoxTableCell 使用 boolean 值而不是 SimpleBooleanProperty

转载 作者:行者123 更新时间:2023-12-02 03:38:38 25 4
gpt4 key购买 nike

我想知道如何在没有 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.setOnEditCancelcolActive.setOnEditCommitcolActive.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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com