Search code examples
treeviewjavafxradiobuttonlist

JavaFX: Making a Tree View with Radio Buttons


Use case: I am trying to offer a functionality where the user assembles/combines elements into a final solution. Elements would have versions. To do that, I need a combination of CheckBoxes to define which elements to include, and then Radio Buttons (nested under each check box) to define what version should be used for the selected element.

I am currently using a CheckTreeView control, from ControlsFX. but I can't find a way to put RadioButtonMenuItems as children for CheckBoxTreeItem in the tree. Is there a way to change the CheckBoxTreeItem to look like a RadioButton?

My current solution is that I am using CheckBoxItems for all tree nodes, but those that are being used for defining the version act like Radio buttons--selecting one would unselect the rest.

Any ideas on how to approach this?

EDIT: posted new question + code here here


Solution

  • For starters you'll need to create your own custom TreeCellFactory that'll display a checkbox or a radiobutton as needed. Something like:

    public class TreeCellFactory implements Callback<TreeView<Object>,TreeCell<Object>>
    {
        @Override
        public TreeCell call( TreeView param )
        {
            return new TreeCell<Object>()
            {
                private final CheckBox  check = new CheckBox();
                private final RadioButton  radio = new RadioButton();
                private Property<Boolean>  prevRadioProp;
                {
                    setContentDisplay( ContentDisplay.GRAPHIC_ONLY );
                }
    
                @Override
                public void updateItem( Object item, boolean empty )
                {
                    if ( prevRadioProp != null )
                    {
                        radio.selectedProperty().unbindBidirectional( prevRadioProp );
                        prevRadioProp = null;
                    }
                    check.selectedProperty().unbind();
    
                    if ( ! empty && item != null )
                    {
                        Property<Boolean> selectedProp = ....;
    
                        if ( getTreeItem().isLeaf() )  // display radio button
                        {
                            radio.setText( ... );
                            radio.selectedProperty().bindBidirectional( selectedProp );
                            prevRadioProp = selectedProp;
                            setGraphic( radio );
                        }
                        else                          // display checkbox
                        {
                            check.setText( ... );
                            check.selectedProperty().bind( selectedProp );
                            setGraphic( check );
                        }
                    }
                    else
                    {
                        setGraphic( null );
                        setText( null );
                    }
                }
            };
        }
    }