javafx如何禁用checkboxTreeItem中的一项?

javafx如何禁用checkboxTreeItem中的一项?,java,javafx,treeview,treeviewitem,Java,Javafx,Treeview,Treeviewitem,我是JavaFX新手,在复选框树视图中遇到问题我想禁用根值**序列号中的一项,但根据JavaFX文档,这似乎是不可能的。 我已禁用单击效果cbTreeViewdisable(treeItems,3) 是否有任何方法灰显任何一个值(或设置id),以便用户知道它已被禁用 private TreeView cbTreeView; @凌驾 公共无效开始(阶段primaryStage){ StackPane root=新的StackPane(); cbTreeView=新树视图(); CheckboxTr

我是JavaFX新手,在复选框树视图中遇到问题
我想禁用根值**序列号中的一项,但根据JavaFX文档,这似乎是不可能的。

我已禁用单击效果cbTreeViewdisable(treeItems,3)
是否有任何方法灰显任何一个值(或设置id),以便用户知道它已被禁用

private TreeView cbTreeView;
@凌驾
公共无效开始(阶段primaryStage){
StackPane root=新的StackPane();
cbTreeView=新树视图();
CheckboxTreeItem rootItem=新的CheckboxTreeItem(“序列号”);
最终CheckboxTreeItem[]treeItems=新的CheckboxTreeItem[6];
对于(int i=0;i<6;i++){
treeItems[i]=新的CheckboxTreeItem(“+i+”);
getChildren().addAll(treeItems[i]);
}
root.setExpanded(true);
CheckboxTreeItem rootItem2=新的CheckboxTreeItem(“child1”);
最终CheckboxTreeItem[]treeItems2=新的CheckboxTreeItem[6];
对于(int i=0;i<6;i++){
treeItems2[i]=新的CheckboxTreeItem(“+i+”);
rootItem2.getChildren().addAll(treeItems2[i]);
}
cbTreeView.setRoot(rootItem);
cbTreeView.setCellFactory(CheckboxTreeCell.forTreeView());
getChildren().set(2,rootItem2);
cbTreeViewdisable(treeItems,3);
//其余的代码导入css并绘制与我的问题无关的阶段
}
私有void cbTreeViewdisable(最终复选框treeItem[]treeItems,最终整数id){
treeItems[id].setIndependent(Boolean.TRUE);
treeItems[id].setValue(treeItems[id].getValue().toString()+“注意:您不能选择此!)”;
treeItems[id].selectedProperty().addListener(新的ChangeListener()){
@凌驾

更改公众假期(ObservalEvalue允许禁用树的单个项的一种方法是将其单元格禁用属性绑定到运行时可以修改的外部属性。为此,当我们设置单元格工厂时,我们可以将此绑定添加到单元格实现中。但是我们需要一个引用,因此为了简单起见,我们将使用该项的值(这需要唯一的值)

让我们使用这个pojo:

class Wrap {

    public Wrap(String name){
        this.name.set(name);
        this.disabled.set(false);
    }

    private final StringProperty name = new SimpleStringProperty();

    public String getName() {
        return name.get();
    }

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

    public StringProperty nameProperty() {
        return name;
    }
    private final BooleanProperty disabled = new SimpleBooleanProperty();

    public boolean isDisabled() {
        return disabled.get();
    }

    public void setDisabled(boolean value) {
        disabled.set(value);
    }

    public BooleanProperty disabledProperty() {
        return disabled;
    }
}
因此,我们可以为树状视图上的所有项目创建一个集合:

private TreeView<String> cbTreeView; 
private final List<Wrap> disableList = new ArrayList<>();

@Override
public void start(Stage primaryStage) {
    cbTreeView = new TreeView();

    CheckBoxTreeItem<String> rootItem = new CheckBoxTreeItem("Serial No.");
    final List<CheckBoxTreeItem<String>> treeItems = new ArrayList<>(6);
    for (int i = 0; i < 6; i++) {
        CheckBoxTreeItem<String> item = new CheckBoxTreeItem("0"+i+"");
        item.setIndependent(true);
        treeItems.add(item);  
        disableList.add(new Wrap("0"+i+""));
    }
    rootItem.getChildren().addAll(treeItems);

    rootItem.setExpanded(true);
    rootItem.setIndependent(true);
    CheckBoxTreeItem<String> rootItem2 = new CheckBoxTreeItem("child1");
    final List<CheckBoxTreeItem<String>> treeItems2 = new ArrayList<>(6);
    for (int i = 0; i < 6; i++) {
        CheckBoxTreeItem<String> item = new CheckBoxTreeItem("1"+i+"");
        item.setIndependent(true);
        treeItems2.add(item); 
        disableList.add(new Wrap("1"+i+""));
    }
    rootItem2.getChildren().addAll(treeItems2);
    rootItem2.setIndependent(true);
    rootItem.getChildren().set(2,rootItem2);

    cbTreeView.setRoot(rootItem);
}


非常感谢@Pereda。如果root设置为独立的,效果会很好。因为我正在使用Java 7,所以我替换了代码

Wrap wrap=disableList.stream()
                    .filter(w->w.getName().equals(s1))
                    .findFirst().orElse(null);
            if(wrap!=null){
                cell.disableProperty().bind(wrap.disabledProperty());
            }
用这个

for (int i = 0; i < disabledList.size();i++) {
    if (disabledList.get(i).getName().equals(s1)) {
        cell.disabledProperty.bind(disabledList.get(i).disabledProperty());
    }
}
for(int i=0;i

但是,如果root未设置为独立,我单击root,禁用的子级也会得到一个不正确的勾号。那么这种情况下的解决方案是什么?

我想到了扩展CheckBoxTreeItem类的想法。在这里,我添加了缺少的disabled属性:

import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.control.CheckBoxTreeItem;


public class CheckBoxTreeItemExt<T> extends CheckBoxTreeItem<T>
{
    public SimpleBooleanProperty disabledProperty = new SimpleBooleanProperty(false);

    public CheckBoxTreeItemExt(T t)
    {
        super(t);
    }

    public boolean isDisabled()
    {
        return disabledProperty.get();
    }

    public void setDisabled(boolean disabled)
    {
        disabledProperty.set(disabled);
    }
}
导入javafx.beans.property.SimpleBoleAnProperty;
导入javafx.scene.control.CheckBoxTreeItem;
公共类CheckBoxTreeItemText扩展了CheckBoxTreeItem
{
public simpleboleanproperty disabledProperty=新的simpleboleanproperty(false);
公共CheckBoxTreeItemText(T)
{
超级(t);
}
公共布尔值已禁用()
{
返回disabledProperty.get();
}
公共无效集禁用(布尔禁用)
{
禁用属性集(禁用);
}
}
然后我创建了一个CheckBoxTreeCell,它监听新的disabledProperty:

import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.TreeItem;
import javafx.scene.control.cell.CheckBoxTreeCell;


public class CheckBoxTreeCellExt<T> extends CheckBoxTreeCell<T> implements ChangeListener<Boolean>
{
    protected SimpleBooleanProperty linkedDisabledProperty;

    @Override
    public void updateItem(T item, boolean empty)
    {
        super.updateItem(item, empty);

        if(item != null)
        {
            TreeItem<T> treeItem = treeItemProperty().getValue();
            if(treeItem != null)
            {
                if(treeItem instanceof CheckBoxTreeItemExt<?>)
                {
                    CheckBoxTreeItemExt<T> checkItem = (CheckBoxTreeItemExt<T>)treeItem;
                    if(checkItem != null)
                    {                               
                        if(linkedDisabledProperty != null)
                        {
                            linkedDisabledProperty.removeListener(this);
                            linkedDisabledProperty = null;
                        }

                        linkedDisabledProperty = checkItem.disabledProperty;                        
                        linkedDisabledProperty.addListener(this);

                        setDisable(linkedDisabledProperty.get());
                    }
                }
            }           
        }
    }

    @Override
    public void changed(ObservableValue<? extends Boolean> arg0, Boolean oldVal, Boolean newVal)
    {       
        setDisable(newVal);
    }
}
导入javafx.beans.property.SimpleBoleAnProperty;
导入javafx.beans.value.ChangeListener;
导入javafx.beans.value.observeValue;
导入javafx.scene.control.TreeItem;
导入javafx.scene.control.cell.CheckBoxTreeCell;
公共类CheckBoxTreeCellExt扩展了CheckBoxTreeCell实现了ChangeListener
{
受保护的SimpleBoleAnProperty LinkedDisableProperty;
@凌驾
public void updateItem(T项,布尔值为空)
{
super.updateItem(项,空);
如果(项!=null)
{
TreeItem TreeItem=treeItemProperty().getValue();
if(treeItem!=null)
{
if(CheckBoxTreeItemExt的treeItem实例)
{
CheckBoxTreeItemText checkItem=(CheckBoxTreeItemText)treeItem;
if(checkItem!=null)
{                               
if(LinkedDisableProperty!=null)
{
LinkedDisableProperty.removeListener(此);
LinkedDisableProperty=null;
}
LinkedDisableProperty=checkItem.disabledProperty;
LinkedDisableProperty.addListener(此);
setDisable(linkedDisableProperty.get());
}
}
}           
}
}
@凌驾
公共无效已更改(可观察值)
具有可绑定布尔值的扩展TreeItem类

行“cell.pseudoClassStateChanged()”只是为了防止需要独立样式,否则也可以使用默认的伪类

如何控制控制器中的禁用状态

@FXML
私有无效句柄(){
对象选择=getFocusedSelectedItem();
如果(选择!=null){
这个.剪贴板.添加(选择);
if(节点数据模型的选择实例){
NodeDataModel toPaste=(NodeDataModel)选择;
TreeItemDeactivatable tid=toPaste.getTreeItem();
tid.setDisabled(正确);
}
}
}

我想这段代码从未见过编译器……扩展ChackBoxTreeCell以保持“禁用”状态并改变其外观如何?如果root未设置为独立,我单击root,禁用的子级也会得到一个不正确的勾号。那么这种情况下的解决方案是什么?没有简单的解决方案。
for (int i = 0; i < disabledList.size();i++) {
    if (disabledList.get(i).getName().equals(s1)) {
        cell.disabledProperty.bind(disabledList.get(i).disabledProperty());
    }
}
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.control.CheckBoxTreeItem;


public class CheckBoxTreeItemExt<T> extends CheckBoxTreeItem<T>
{
    public SimpleBooleanProperty disabledProperty = new SimpleBooleanProperty(false);

    public CheckBoxTreeItemExt(T t)
    {
        super(t);
    }

    public boolean isDisabled()
    {
        return disabledProperty.get();
    }

    public void setDisabled(boolean disabled)
    {
        disabledProperty.set(disabled);
    }
}
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.TreeItem;
import javafx.scene.control.cell.CheckBoxTreeCell;


public class CheckBoxTreeCellExt<T> extends CheckBoxTreeCell<T> implements ChangeListener<Boolean>
{
    protected SimpleBooleanProperty linkedDisabledProperty;

    @Override
    public void updateItem(T item, boolean empty)
    {
        super.updateItem(item, empty);

        if(item != null)
        {
            TreeItem<T> treeItem = treeItemProperty().getValue();
            if(treeItem != null)
            {
                if(treeItem instanceof CheckBoxTreeItemExt<?>)
                {
                    CheckBoxTreeItemExt<T> checkItem = (CheckBoxTreeItemExt<T>)treeItem;
                    if(checkItem != null)
                    {                               
                        if(linkedDisabledProperty != null)
                        {
                            linkedDisabledProperty.removeListener(this);
                            linkedDisabledProperty = null;
                        }

                        linkedDisabledProperty = checkItem.disabledProperty;                        
                        linkedDisabledProperty.addListener(this);

                        setDisable(linkedDisabledProperty.get());
                    }
                }
            }           
        }
    }

    @Override
    public void changed(ObservableValue<? extends Boolean> arg0, Boolean oldVal, Boolean newVal)
    {       
        setDisable(newVal);
    }
}
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeView;
import javafx.util.Callback;

public class CheckBoxTreeCellFactoryExt<T> implements Callback<TreeView<T>, TreeCell<T>>
{
    @Override
    public TreeCell<T> call(TreeView<T> tv)
    {
        return new CheckBoxTreeCellExt<T>();
    }
}
   import javafx.beans.property.SimpleBooleanProperty;
   import javafx.scene.control.TreeItem;

    public class TreeItemDeactivatable<T> extends TreeItem<T> {
        private SimpleBooleanProperty disabledProperty = new SimpleBooleanProperty(false);

        public TreeItemDeactivatable() {
            super();
        }

        public TreeItemDeactivatable(T t) {
            super(t);
        }

        public SimpleBooleanProperty disabledProperty() {
            return disabledProperty;
        }

        public boolean isDisabled() {
            return disabledProperty.get();
        }

        public void setDisabled(boolean disabled) {
            disabledProperty.set(disabled);
        }
    }
    @Override
    public TreeCell<T> call(TreeView<T> treeView) {
    TreeCell<T> cell = (TreeCell<T>) new TextFieldTreeCellImpl();

        final PseudoClass clippedStylePseudoClass = PseudoClass.getPseudoClass("clipped");

        cell.treeItemProperty().addListener((ov, oldTreeItem, newTreeItem) -> {
            if (newTreeItem != null && newTreeItem instanceof TreeItemDeactivatable) {
                TreeItemDeactivatable<T> tid = (TreeItemDeactivatable<T>) newTreeItem;
                 tid.setDisabled(false);
                 cell.disableProperty().unbind();
                 cell.disableProperty().bind(tid.disabledProperty());

cell.pseudoClassStateChanged(clippedStylePseudoClass,cell.isDisabled());
            }
        });
}
.tree-view .tree-cell:clipped {
    -fx-background-color:   color-clipped;
}
.tree-view .tree-cell:disabled {}
@FXML
    private void handleCut() {
        Object selection = getFocusedSelectedItem();

        if (selection != null) {
            this.clipboard.add(selection);

             if (selection instanceof NodeDataModel) {
                NodeDataModel toPaste = (NodeDataModel) selection;
                TreeItemDeactivatable<NodeDataModel> tid = toPaste.getTreeItem();
                tid.setDisabled(true);
            }
        }
    }