2014-12-04 84 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