2014-11-25 1 views
1

Я новичок в JavaFX, и у меня возникла проблема с флажком Tree View.
Я хочу отключить один элемент внутри корневого значения ** Последовательный номер, но, согласно документации JavaFX, кажется, что это невозможно.
javafx как отключить один элемент в checkboxTreeItem?

Я отключил щелчок эффект cbTreeViewdisable (3, элементы дерева)
Есть ли способ, чтобы серый любое одно значение (или установить идентификатор), так что пользователь знает, что это будет отключено.

private TreeView<String> cbTreeView;  
@Override 
public void start(Stage primaryStage) { 
StackPane root = new StackPane(); 
cbTreeView = new TreeView(); 
CheckboxTreeItem<String> rootItem = new CheckboxTreeItem("Serial No."); 
final CheckboxTreeItem[] treeItems = new CheckboxTreeItem[6]; 
for (int i = 0; i < 6; i++) { 
    treeItems[i] = new CheckboxTreeItem(""+i+""); 
    rootItem.getChildren().addAll(treeItems[i]); 
} 

root.setExpanded(true); 
CheckboxTreeItem rootItem2 = new CheckboxTreeItem("child1"); 
final CheckboxTreeItem[] treeItems2 = new CheckboxTreeItem[6]; 

for (int i = 0; i < 6; i++) { 
    treeItems2[i] = new CheckboxTreeItem(""+i+""); 
    rootItem2.getChildren().addAll(treeItems2[i]); 
} 

cbTreeView.setRoot(rootItem); 
cbTreeView.setCellFactory(CheckboxTreeCell.<String>forTreeView()); 
rootItem.getChildren().set(2,rootItem2); 
cbTreeViewdisable(treeItems, 3); 
//rest of code imports css and draws stage which is not relevant to my question 
} 

private void cbTreeViewdisable(final CheckboxTreeItem[] treeItems, final int id) { 
    treeItems[id].setIndependent(Boolean.TRUE); 
    treeItems[id].setValue(treeItems[id].getValue().toString()+" Note: you can't select this!)"); 
    treeItems[id].selectedProperty().addListener(new ChangeListener<Boolean>() { 

    @Override 
    public void changed(ObservableValue<? extends Boolean> observable, 
     Boolean oldvalue, Boolean newvalue) { 
     Platform.runLater(new Runnable() { 
     @Override 
     public void run() { 
      treeItems[id].setSelected(Boolean.FALSE);  
    } 
+0

Этот код никогда не видел компилятора, который я предполагаю ... как насчет расширения ChackBoxTreeCell, чтобы сохранить состояние «отключено» и изменить его внешний вид? –

ответ

0

Один из способов разрешить отключение отдельных элементов дерева являются обязательными их клетки отключить свойство внешнего свойства, которое можно изменять во время выполнения. Для этого, когда мы устанавливаем фабрику ячеек, мы можем добавить эту привязку к реализации ячейки. Но нам нужна ссылка, поэтому мы будем использовать значение элемента для простоты (для этого требуются уникальные значения).

Давайте использовать этот 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); 

Теперь мы создаем мобильный завод, а также обеспечить связывание , когда значение предмета установлено:

cbTreeView.setCellFactory((TreeView<String> item) -> { 

     final CheckBoxTreeCell<String> cell = new CheckBoxTreeCell<>(); 

     cell.itemProperty().addListener((obs,s,s1)->{ 
      cell.disableProperty().unbind(); 
      if(s1!=null && !s1.isEmpty()){ 
       Wrap wrap=disableList.stream() 
         .filter(w->w.getName().equals(s1)) 
         .findFirst().orElse(null); 
       if(wrap!=null){ 
        cell.disableProperty().bind(wrap.disabledProperty()); 
       } 
      } 
     }); 
     return cell; 
    }); 

И, наконец, мы показываем сцену и отключим некоторые случайные элементы:

Scene scene=new Scene(cbTreeView); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 

    // disable by name 
    disableList.stream() 
      .filter(w->w.getName().equals("03")) 
      .findFirst().ifPresent(w->w.setDisabled(true)); 
    // disable by order 
    disableList.get(7).setDisabled(true); 

}

TreeView with disabled items

+0

, если root не установлен как независимый, я нажимаю на корень, а отключенный ребенок также получает галочку, которая неверна. Итак, каково решение в этом случае? –

+0

Для этого нет простого решения. По умолчанию этот тип 'TreeItem' имеет такое поведение. Я установлю корень как независимый. Но если вам это нужно по-другому, вам нужно будет реализовать собственный 'TreeItem' с помощью' CheckBox'. –

0

спасибо @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()); 
    } 
} 

Но если корень не установить в качестве независимой, я нажимаю на корню, и ребенок-инвалид также получить галочка, которая неверна. Итак, каково решение в этом случае?

1

У меня возникла идея расширить класс CheckBoxTreeItem. Там я добавил недостающий отключил свойство:

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); 
    } 
} 

Затем я создал 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); 
    } 
} 

И, наконец, мы в CheckBoxTreeCellFactory:

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>(); 
    } 
} 
Смежные вопросы