2014-12-04 79 views
2

我想實現OnMouseEnter在和一個JavaFX的ListView onMouseExit事件兄弟節點變化的背景CSS。我想要做的是,如果鼠標移動到列表視圖的節點上,我想更改當前視圖中當前可見子節點的背景顏色。JavaFX的TreeView控件 - 上的MouseEvent

這篇文章有很大的代碼示例,但並不完全是我所期待的。 Apply style to TreeView children nodes in javaFX

使用代碼作爲參考,我所尋找的是一個給定的樹:

根 - >項目:1 - >項目:100 - >項目1000,項目1001,項目1002項1003

當我鼠標移到「項目:100」我想它和項目1000 *有一個背景顏色變化。

這對我來說很難,因爲getNextSibling和getPreviousSibling接口位於TreeItem上,雖然您可以從MouseEvent上的TreeCell獲取TreeItem,但您不能(我知道)更新TreeItem上的CSS並且擁有它在TreeCell中生效 - 因爲setStyle方法在TreeCell上。

關於如何做到這一點的建議?

回答

2

[更新注:我本來使用的TreeItem子類中的解決方案。此處顯示的解決方案比原始的要乾淨得多。]

創建一個ObservableSet<TreeItem<?>>,其中包含應該突出顯示的TreeItem。然後在單元工廠中觀察該單元格和單元格treeItemProperty(),並設置樣式類別(我在下面的示例中使用了PseudoClass),以便單元格在屬於該單元格的樹項目位於集合中時突出顯示。

最後,註冊mouseEnteredmouseExited處理與細胞。當鼠標進入單元格時,您可以獲取樹項目,使用它導航到您需要的任何其他樹項目,並將相應的項目添加到您定義的集合中。在mouseExited處理程序中,清除集合(或根據需要執行其他邏輯)。

import java.util.HashSet; 

import javafx.application.Application; 
import javafx.beans.binding.Bindings; 
import javafx.beans.binding.BooleanBinding; 
import javafx.beans.value.ChangeListener; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableSet; 
import javafx.css.PseudoClass; 
import javafx.scene.Scene; 
import javafx.scene.control.TreeCell; 
import javafx.scene.control.TreeItem; 
import javafx.scene.control.TreeView; 
import javafx.scene.layout.BorderPane; 
import javafx.stage.Stage; 

public class HighlightingTree extends Application { 

    private final PseudoClass highlighted = PseudoClass.getPseudoClass("highlighted"); 

    @Override 
    public void start(Stage primaryStage) { 
     TreeView<Integer> tree = new TreeView<>(); 
     tree.setRoot(buildTreeRoot()); 

     ObservableSet<TreeItem<Integer>> highlightedItems = FXCollections.observableSet(new HashSet<>()); 


     tree.setCellFactory(tv -> { 

      // the cell: 
      TreeCell<Integer> cell = new TreeCell<Integer>() { 

       // indicates whether the cell should be highlighted: 

       private BooleanBinding highlightCell = Bindings.createBooleanBinding(() -> 
        getTreeItem() != null && highlightedItems.contains(getTreeItem()), 
        treeItemProperty(), highlightedItems); 

       // listener for the binding above 
       // note this has to be scoped to persist alongside the cell, as the binding 
       // will use weak listeners, and we need to avoid the listener getting gc'd: 
       private ChangeListener<Boolean> listener = (obs, wasHighlighted, isHighlighted) -> 
        pseudoClassStateChanged(highlighted, isHighlighted); 

       // anonymous constructor: register listener with binding  
       { 
        highlightCell.addListener(listener); 
       } 
      }; 

      // display correct text: 
      cell.itemProperty().addListener((obs, oldItem, newItem) -> { 
       if (newItem == null) { 
        cell.setText(null); 
       } else { 
        cell.setText(newItem.toString()); 
       } 
      }); 

      // mouse listeners: 
      cell.setOnMouseEntered(e -> { 
       if (cell.getTreeItem() != null) { 
        highlightedItems.add(cell.getTreeItem()); 
        highlightedItems.addAll(cell.getTreeItem().getChildren()); 
       } 
      }); 

      cell.setOnMouseExited(e -> highlightedItems.clear()); 

      return cell ; 
     }); 

     BorderPane uiRoot = new BorderPane(tree); 
     Scene scene = new Scene(uiRoot, 600, 600); 
     scene.getStylesheets().add("highlight-tree-children.css"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    private TreeItem<Integer> buildTreeRoot() { 
     return buildTreeItem(1); 
    } 

    private TreeItem<Integer> buildTreeItem(int n) { 
     TreeItem<Integer> item = new TreeItem<>(n); 
     if (n < 10_000) { 
      for (int i = 0; i<10; i++) { 
       item.getChildren().add(buildTreeItem(n * 10 + i)); 
      } 
     } 
     return item ; 
    } 


    public static void main(String[] args) { 
     launch(args); 
    } 
} 

亮點,樹children.css:

.tree-cell:highlighted { 
    -fx-background: yellow ; 
} 
+0

James_D:首先感謝您對顯而易見的思想和考慮,你把這個問題。讓我精神上審查你的迴應並回復你。 – funkyjive 2014-12-04 20:04:54

+0

我強烈建議只跳轉到第二個(更新)版本。爲了完整起見,我將原件留在那裏,但也許我應該刪除它。 – 2014-12-04 20:16:51

+0

詹姆斯,我做到了。我剛剛嘗試過,而且這真的是我以後的事情。非常好!謝謝。 – funkyjive 2014-12-04 21:09:31