2014-11-25 2 views
1

저는 JavaFX를 처음 사용하며 체크 박스 트리보기에 문제가 있습니다.
루트 값 ** 일련 번호 중 하나의 항목을 비활성화하고 싶지만 JavaFX 설명서에 따르면 불가능합니다.
javafx checkboxTreeItem에서 하나의 항목을 비활성화하는 방법?

나는 장애인 클릭 효과 cbTreeViewdisable (treeItems, 3)
어느 한 값 (또는 세트 ID)를 회색으로 어떤 방법이 있나요 그래서 사용자가 사용하지 알고 있습니다.

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

한 가지 방법은 나무의 단일 항목 런타임에서 수정할 수있는 외부 속성에 자신의 휴대 비활성화 속성을 구속력을 해제 할 수 있습니다. 이를 위해 셀 팩토리를 설정할 때이 바인딩을 셀 구현에 추가 할 수 있습니다. 그러나 참조가 필요하므로 간단하게하기 위해 항목의 값을 사용합니다 (고유 값이 필요함).

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

그래서 우리는 트리 뷰에있는 모든 항목에 대해 하나의 콜렉션을 가질 수 있습니다 :

의이 POJO를 사용하자

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

루트가 독립적으로 설정되지 않은 경우 루트를 클릭하면 사용할 수없는 자식도 올바르지 않은 진드기를받습니다. 이 경우 솔루션은 무엇입니까? –

+0

쉬운 해결책은 없습니다. 이 타입의'TreeItem'은 기본적으로이 동작을합니다. 나는 뿌리를 독립적으로 세울 것이다. 하지만 다른 방법이 필요하다면,'CheckBox'를 사용하여 자신 만의'TreeItem'을 구현해야 할 것입니다. –

0

덕분에 많은 @Pereda. 루트가 독립적으로 설정되면 잘 작동합니다. 나는 자바 7 일하고 있기 때문에, 나는이

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

와 코드

Wrap wrap=disableList.stream() 
        .filter(w->w.getName().equals(s1)) 
        .findFirst().orElse(null); 
      if(wrap!=null){ 
       cell.disableProperty().bind(wrap.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); 
    } 
} 
다음

내가 그 새로운 disabledProperty에 수신 대기 CheckBoxTreeCell 만들었습니다

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