Javafx:如何在TreeTableView

时间:2017-11-21 09:49:15

标签: java checkbox javafx jcheckbox treetableview

我正在尝试在javafx中实现TreeTableView,其中第一列包含字符串值,第三列将呈现为3状态复选框。 使用以下MCVE,我可以获得treetable但复选框中的所有选项都不会在父级折叠/展开或调整大小时保留。
MCVE
A类是父母 B级延伸A并且是孩子 C类代表第二列,(呈现为复选框)
类MVCECheckBox构建treetable并显示它。

A.java

package mcve.checkbox;

import java.util.List;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

/**
 *
 * @author returncode13
 */
public class A {
    StringProperty name=new SimpleStringProperty();
    C check=new C();
    List<A> children;

    public StringProperty getName() {
        return name;
    }

     public void setName(String name) {
        this.name.set(name);
    }

    public C getCheck() {
        return check;
    }

    public void setCheck(C check) {
        this.check = check;
    }

    public StringProperty nameProperty(){
        return name;
    }

    public List<A> getChildren() {
        return children;
    }

    public void setChildren(List<A> children) {
        this.children = children;
    }


    }

B.java

package mcve.checkbox;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

/**
 *
 * @author returncode13
 */
public class B extends A{
    StringProperty name=new SimpleStringProperty();
    C Check=new C();

    @Override
    public StringProperty getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name.set(name);
    }

    @Override
    public C getCheck() {
        return Check;
    }

    @Override
    public void setCheck(C Check) {
        this.Check = Check;
    }

    @Override
     public StringProperty nameProperty(){
        return name;
    }

}

C.java

package mcve.checkbox;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;

/**
 *
 * @author returncode13
 */
public class C {
    BooleanProperty checkUncheck=new SimpleBooleanProperty();
    BooleanProperty indeterminate=new SimpleBooleanProperty();

    public BooleanProperty getCheckUncheck() {
        return checkUncheck;
    }

    public void setCheckUncheck(BooleanProperty checkUncheck) {
        this.checkUncheck = checkUncheck;
    }

    public BooleanProperty getIndeterminate() {
        return indeterminate;
    }

    public void setIndeterminate(BooleanProperty indeterminate) {
        this.indeterminate = indeterminate;
    }

    public BooleanProperty checkUncheckProperty(){
        return checkUncheck;
    }

    public BooleanProperty indeterminateProperty(){
        return indeterminate;
    }
} 

MCVECheckBox.java

package mcve.checkbox;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableCell;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.cell.TreeItemPropertyValueFactory;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;

/**
 *
 * @author returncode13
 */
public class MCVECheckBox extends Application {
    A selectedItem;
    private TreeTableView<A> treetable=new TreeTableView<>();
    @Override
    public void start(Stage primaryStage) {
       //setting up parents (A) and children (B)
        A a1=new A();                       
        a1.setName("A1");

        List<A> A1Children=new ArrayList();
        B b11=new B();
        b11.setName("B11");
        B b12=new B();
        b12.setName("B12");
        A1Children.add(b11);
        A1Children.add(b12);
        a1.setChildren(A1Children);


        A a2=new A();
        a2.setName("A2");

        List<A> A2Children=new ArrayList();
        B b21=new B();
        b21.setName("B21");
        B b22=new B();
        b22.setName("B22");
        A2Children.add(b21);
        A2Children.add(b22);
        a2.setChildren(A2Children);



        //tree columns . first one holds strings
        TreeTableColumn<A,String> name=new TreeTableColumn<>("Name");
        name.setCellValueFactory(new TreeItemPropertyValueFactory<>("name"));


        //2nd tree columns. rendered as checkboxes. boolean values
        TreeTableColumn<A,Boolean> checks=new TreeTableColumn<>("Checks");
        checks.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<A, Boolean>, ObservableValue<Boolean>>() {
            @Override
            public ObservableValue<Boolean> call(TreeTableColumn.CellDataFeatures<A, Boolean> param) {
                A a=param.getValue().getValue();
                SimpleBooleanProperty checkUncheck=new SimpleBooleanProperty();
                SimpleBooleanProperty indeterminate=new SimpleBooleanProperty();

                checkUncheck=(SimpleBooleanProperty) a.getCheck().getCheckUncheck();
                indeterminate=(SimpleBooleanProperty) a.getCheck().getIndeterminate();

                //to do: set parents status based on children status.


                if(indeterminate.get()){
                    return indeterminate;
                }else{
                    return checkUncheck;
                }

            }
        });


        checks.setCellFactory(new Callback<TreeTableColumn<A, Boolean>, TreeTableCell<A, Boolean>>() {
            @Override
            public TreeTableCell<A, Boolean> call(TreeTableColumn<A, Boolean> param) {
                return new CheckBoxCell();
            }
        });


        //building the tree;
        TreeItem<A> a1item=new TreeItem<>(a1);
        TreeItem<A> b11item=new TreeItem<>(b11);
        TreeItem<A> b12item=new TreeItem<>(b12);
        a1item.getChildren().add(b11item);
        a1item.getChildren().add(b12item);

        TreeItem<A> a2item=new TreeItem<>(a2);
        TreeItem<A> b21item=new TreeItem<>(b21);
        TreeItem<A> b22item=new TreeItem<>(b22);
        a2item.getChildren().add(b21item);
        a2item.getChildren().add(b22item);




        TreeItem<A> root=new TreeItem<>();
        root.getChildren().add(a1item);
        root.getChildren().add(a2item);

        treetable.getColumns().addAll(name,checks);

        treetable.setRoot(root);
        treetable.setShowRoot(false);
        treetable.setEditable(true);


      //  StackPane rootSp = new StackPane();
        Scene scene = new Scene(treetable, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }


    //to render checkboxes in treetable


    private  class CheckBoxCell extends TreeTableCell<A, Boolean> {


        CheckBox checkbox;

        public CheckBoxCell() {
            checkbox=new CheckBox();
            checkbox.setAllowIndeterminate(true);

            checkbox.selectedProperty().addListener((obs,wasSelected,isNowSelected) -> {
            if(isNowSelected){
               selectedItem=getTreeTableRow().getItem();
            }
            });

        }


        @Override
        public void updateItem(Boolean b,boolean empty){
            super.updateItem(b, empty);

            if(empty){
                setGraphic(null);
            }else{
                checkbox.setSelected(b);
                setGraphic(checkbox);
            }
        }
    }

}

我之前尝试使用CheckTreeTableCell在第二列上设置单元格工厂,但很快发现CheckTreeTableCell不支持3状态(检查,取消选中,不确定)复选框。 之后我尝试实现上面的代码。虽然我能够引入三态复选框,但我无法让它们的状态持续存在。每次折叠/展开父级时,对其子级的检查都将被取消选中 感谢您在确定修复方面提供的任何帮助。

0 个答案:

没有答案