簡體   English   中英

JavaFX TableView CheckBoxTableCell,帶有布爾值而不是SimpleBooleanProperty

[英]JavaFX TableView CheckBoxTableCell with boolean instead of SimpleBooleanProperty

我想知道如何在沒有ObservableProperty的情況下使用CheckBoxTableCell。 我正在使用一個簡單的布爾值,因為我想將數據序列化到我的DerbyDB。

肯定有可能創建一個SimpleBooleanProperty並使用@Transient並將其包裝在我的普通boolean active

我的布爾值顯示正確,但在單擊Tableview中的Checkbox后,我無法存儲新值。

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屬性。 我建議使用這些屬性,只需通過定義readObjectwriteObject方法來自定義序列化機制。 這是一個像這樣定義的類的演示:

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將自動綁定到PropertyValueFactory返回的PropertyValueFactory

另一種方法是創建一個BooleanProperty專門用於綁定到復選框選中狀態。 請注意,根據Javadocs ,因為CheckBoxTableCell永遠不會進入或離開編輯狀態,所以永遠不會調用編輯回調onEditCommit等:

請注意,CheckBoxTableCell呈現CheckBox'live',這意味着CheckBox始終是交互式的,可以由用戶直接切換。 這意味着單元格不必進入其編輯狀態(通常是用戶雙擊單元格)。 這樣做的副作用是不會調用通常的編輯回調(例如編輯提交)。 如果希望收到更改通知,建議直接觀察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);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM