JavaFx TreeView css [英] JavaFx TreeView css

查看:157
本文介绍了JavaFx TreeView css的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建元素外观和行为,如下所示。





有深色背景和4个元素的顶部列表:biblioteki,Analiza等。当我们点击其中一个列表时,列表会被展开,这个项目及其子项会变得很暗。来自子列表的Additionaly选择项目获得不同的字体(粗体和白色)。此外,当时只有一个项目可以扩展。



所以我发现这是应用了适当样式的TreeView行为。
我使用以下代码:

  TreeView< TabMenuElement> treeView = new TreeView<>(treeRoot); 
treeView.setCellFactory(tv - > new TreeCell< TabMenuElement>(){
@Override
public void updateItem(TabMenuElement item,boolean empty){
super.updateItem(item ,空);
setDisclosureNode(null);

if(empty){
setText();
setGraphic(null);
} else {
setText(item.getName()); //项目
的适当文本if(item.getIv()!= null){
setGraphic(item.getIv());
}
}
}
});
treeView.setShowRoot(false);

TabMenuElement有方法getIV获取ImageView(icon)如果为此elemnt定义并获取getName要显示的文本。现在它看起来像这样





所以我遇到以下问题:


  1. 如何仅更改字体TreeView中的所选项目?

  2. 如何在所选子树上设置背景?

  3. 如何强制最多可以扩展一个子树
  4. li>
  5. 如何设置更大的尺寸到顶级项目?


解决方案

< blockquote>

如何仅更改TreeView中所选项目的字体?


在你的css文件中,只需定义字体.tree-cell:selected

  .tree- cell:selected {
-fx-font-weight:bold;
}




如何在所选子树上设置背景?


这个有点棘手。您希望任何扩展节点的背景以及父节点不是根节点的任何节点都不同(这不是您的措辞,但我认为它在逻辑上是等效的)。扩展节点已经有一个CSS伪类。对于父不是根,您需要定义自己的伪类:

  PseudoClass subElementPseudoClass = PseudoClass.getPseudoClass(子树项目); 

现在观察单元格的 treeItem 属性,并在更改时更新伪类状态:

  treeView.setCellFactory(tv  - > {
TreeCell< TabMenuElement> ; cell = new TreeCell< TabMenuElement>(){
@Override
public void updateItem(TabMenuElement item,boolean empty){
super.updateItem(item,empty);
setDisclosureNode (null);

if(empty){
setText();
setGraphic(null);
} else {
setText(item) .getName()); //项目
的适当文本if(item.getIv()!= null){
setGraphic(item.getIv());
}
}
}
};

cell.treeItemProperty()。addListener((obs,oldTreeItem,newTreeItem) - > {
cell.pseudoClassStateChanged(subElemen) tPseudoClass,
newTreeItem!= null&& newTreeItem.getParent()!= cell.getTreeView()。getRoot());
}

返回单元格;
});

现在在CSS文件中你可以做到

  .tree-cell:expanded,.tree-cell:sub-tree-item {
-fx-background-color:...;
}




如何强制最多一个子树可以扩展


为每个<$ c $添加以下 ChangeListener c> TreeItem 的扩展属性:

  ChangeListener< Boolean> expandedListener =(obs,wasExpanded,isNowExpanded) - > {
if(isNowExpanded){
ReadOnlyProperty<?> expandedProperty =(ReadOnlyProperty<?>)obs;
Object itemThatWasJustExpanded = expandedProperty.getBean();
for(TreeItem< TabMenuElement> item:treeView.getRoot()。getChildren()){
if(item!= itemThatWasJustExpanded){
item.setExpanded(false);
}
}
}
};

TreeItem< TabMenuElement> biblioteka = new TreeItem<>(...);
biblioteka.expandedProperty()。addListener(expandedListener);
TreeItem< TabMenuElement> analiza = new TreeItem<>(...);
analiza.expandedProperty()。addListener(expandedListener);
//等,适用于所有顶级商品。




如何设置更大的尺寸到顶级商品?




  .tree-cell {
-fx-padding:0.75em 0em 0.75em 0em;
}
.tree-cell:sub-tree-item {
-fx-padding:0.25em;
}

(或更改字体大小或类似内容。)



这是一个完整的例子:

  import javafx.application.Application; 
import javafx.beans.property.ReadOnlyProperty;
import javafx.beans.value.ChangeListener;
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;

公共类StyledUniqueExpandingTree扩展Application {

@Override
public void start(Stage primaryStage){
TreeView< String> tree = new TreeView<>();
tree.setShowRoot(false);
TreeItem< String> root = new TreeItem<>();
tree.setRoot(root);

ChangeListener< Boolean> expandedListener =(obs,wasExpanded,isNowExpanded) - > {
if(isNowExpanded){
ReadOnlyProperty<?> expandedProperty =(ReadOnlyProperty<?>)obs;
Object itemThatWasJustExpanded = expandedProperty.getBean();
for(TreeItem< String> item:tree.getRoot()。getChildren()){
if(item!= itemThatWasJustExpanded){
item.setExpanded(false);
}
}
}
};

for(int i = 1; i< = 4; i ++){
TreeItem< String> item = new TreeItem<>(顶级+ i);
item.expandedProperty()。addListener(expandedListener);
root.getChildren()。add(item);
for(int j = 1; j< = 4; j ++){
TreeItem< String> subItem = new TreeItem<>(Sub item+ i +:+ j);
item.getChildren()。add(subItem);
}
}

PseudoClass subElementPseudoClass = PseudoClass.getPseudoClass(sub-tree-item);

tree.setCellFactory(tv - > {
TreeCell< String> cell = new TreeCell< String>(){
@Override
public void updateItem(String item,boolean empty){
super.updateItem(item,empty);
setDisclosureNode(null);

if(empty){
setText() ;
setGraphic(null);
} else {
setText(item); //项目
的适当文本}
}

};
cell.treeItemProperty()。addListener((obs,oldTreeItem,newTreeItem) - > {
cell.pseudoClassStateChanged(subElementPseudoClass,
newTreeItem!= null&& newTreeItem.getParent ()!= cell.getTreeView()。getRoot());
});
返回单元格;
});

BorderPane uiRoot = new BorderPane(tree);
场景场景=新场景(uiRoot,250,400);
scene.getStylesheets()。add(styled-unique-expanded-tree.css);
primaryStage.setScene(scene);
primaryStage.show();
}

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

with styled-unique-expanded-tree.css:

  .tree-view,.tree-cell {
-fx-background-color:black;
-fx-text-fill:white;
}
.tree-cell:expanded,.tree-cell:sub-tree-item {
-fx-background-color:#404040;
}
.tree-cell:selected {
-fx-font-weight:bold;
}
.tree-cell {
-fx-padding:0.75em 0em 0.75em 0em;
}
.tree-cell:sub-tree-item {
-fx-padding:0.25em;
}


I am would like to create element looking and behaving as the one shown below.

There is dark background and top list of 4 elements: "biblioteki", "Analiza" and so on. hen we click on one of them list is expanded and this item and its children gets light dark backgorund. Additionaly selected item from child list gets different font (bold and white). Also there could be only one item expanded at the time.

So I figure out that this is TreeView behaviour with proper styles applied. I get it working with following code:

    TreeView<TabMenuElement> treeView = new TreeView<>(treeRoot);
    treeView.setCellFactory(tv -> new TreeCell<TabMenuElement>() {
        @Override
        public void updateItem(TabMenuElement item, boolean empty) {
            super.updateItem(item, empty);
            setDisclosureNode(null);

            if (empty) {
                setText("");
                setGraphic(null);
            } else {
                setText(item.getName()); // appropriate text for item
                if (item.getIv() != null) {
                    setGraphic(item.getIv());
                }
            }
        }
    });
    treeView.setShowRoot(false);

TabMenuElement have method getIV to obtain ImageView (icon) if it is define for this elemnt and getName to obtain text to be displayed. For now it looks like this

So I have following problems:

  1. how to change font only on selected item in TreeView?
  2. how to setup background on selected sub-tree?
  3. how to force that at most one subtree could be expanded
  4. how to set bigger size to top level items?

解决方案

how to change font only on selected item in TreeView?

In your css file, just define the font for .tree-cell:selected:

.tree-cell:selected {
    -fx-font-weight: bold ;
}

how to setup background on selected sub-tree?

This one's a little tricky. You want the background of any expanded node, and any node whose parent is not the root, to be different (that's not how you phrased it but I think it is logically equivalent). An expanded node has a CSS pseudoclass already. For the "parent is not the root", you need to define your own pseudoclass:

PseudoClass subElementPseudoClass = PseudoClass.getPseudoClass("sub-tree-item");

Now observe the treeItem property of the cell, and update the pseudoclass state when it changes:

treeView.setCellFactory(tv -> {
    TreeCell<TabMenuElement> cell = new TreeCell<TabMenuElement>() {
        @Override
        public void updateItem(TabMenuElement item, boolean empty) {
            super.updateItem(item, empty);
            setDisclosureNode(null);

            if (empty) {
                setText("");
                setGraphic(null);
            } else {
                setText(item.getName()); // appropriate text for item
                if (item.getIv() != null) {
                    setGraphic(item.getIv());
                }
            }
        }
    };

    cell.treeItemProperty().addListener((obs, oldTreeItem, newTreeItem) -> {
        cell.pseudoClassStateChanged(subElementPseudoClass,
            newTreeItem != null && newTreeItem.getParent() != cell.getTreeView().getRoot());
    }

    return cell ;
});

Now in your CSS file you can do

.tree-cell:expanded, .tree-cell:sub-tree-item {
    -fx-background-color: ... ;
}

how to force that at most one subtree could be expanded

Add the following ChangeListener to each of your TreeItem's expanded properties:

ChangeListener<Boolean> expandedListener = (obs, wasExpanded, isNowExpanded) -> {
    if (isNowExpanded) {
        ReadOnlyProperty<?> expandedProperty = (ReadOnlyProperty<?>) obs ;
        Object itemThatWasJustExpanded = expandedProperty.getBean();
        for (TreeItem<TabMenuElement> item : treeView.getRoot().getChildren()) {
            if (item != itemThatWasJustExpanded) {
                item.setExpanded(false);
            }
        }
    }
};

TreeItem<TabMenuElement> biblioteka = new TreeItem<>(...);
biblioteka.expandedProperty().addListener(expandedListener);
TreeItem<TabMenuElement> analiza = new TreeItem<>(...);
analiza.expandedProperty().addListener(expandedListener);
// etc, for all "top-level" items.

how to set bigger size to top level items?

.tree-cell {
    -fx-padding: 0.75em 0em 0.75em 0em ;
}
.tree-cell:sub-tree-item {
    -fx-padding: 0.25em ;
}

(Or change the font size, or similar.)

Here is a complete example:

import javafx.application.Application;
import javafx.beans.property.ReadOnlyProperty;
import javafx.beans.value.ChangeListener;
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 StyledUniqueExpandingTree extends Application {

    @Override
    public void start(Stage primaryStage) {
        TreeView<String> tree = new TreeView<>();
        tree.setShowRoot(false);
        TreeItem<String> root = new TreeItem<>("");
        tree.setRoot(root);

        ChangeListener<Boolean> expandedListener = (obs, wasExpanded, isNowExpanded) -> {
            if (isNowExpanded) {
                ReadOnlyProperty<?> expandedProperty = (ReadOnlyProperty<?>) obs ;
                Object itemThatWasJustExpanded = expandedProperty.getBean();
                for (TreeItem<String> item : tree.getRoot().getChildren()) {
                    if (item != itemThatWasJustExpanded) {
                        item.setExpanded(false);
                    }
                }
            }
        };

        for (int i=1; i<=4; i++) {
            TreeItem<String> item = new TreeItem<>("Top level "+i);
            item.expandedProperty().addListener(expandedListener);
            root.getChildren().add(item);
            for (int j=1; j<=4; j++) {
                TreeItem<String> subItem = new TreeItem<>("Sub item "+i+":"+j);
                item.getChildren().add(subItem);
            }
        }

        PseudoClass subElementPseudoClass = PseudoClass.getPseudoClass("sub-tree-item");

        tree.setCellFactory(tv -> {
            TreeCell<String> cell = new TreeCell<String>() {
                @Override
                public void updateItem(String item, boolean empty) {
                    super.updateItem(item, empty);
                    setDisclosureNode(null);

                    if (empty) {
                        setText("");
                        setGraphic(null);
                    } else {
                        setText(item); // appropriate text for item
                    }
                }

            };
            cell.treeItemProperty().addListener((obs, oldTreeItem, newTreeItem) -> {
                cell.pseudoClassStateChanged(subElementPseudoClass,
                        newTreeItem != null && newTreeItem.getParent() != cell.getTreeView().getRoot());
            });
            return cell ;
        });

        BorderPane uiRoot = new BorderPane(tree);
        Scene scene = new Scene(uiRoot, 250, 400);
        scene.getStylesheets().add("styled-unique-expanded-tree.css");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

with styled-unique-expanded-tree.css:

.tree-view, .tree-cell {
    -fx-background-color: black ;
    -fx-text-fill: white ;
}
.tree-cell:expanded, .tree-cell:sub-tree-item {
    -fx-background-color: #404040 ;
}
.tree-cell:selected {
    -fx-font-weight: bold ;
}
.tree-cell {
    -fx-padding: 0.75em 0em 0.75em 0em ;
}
.tree-cell:sub-tree-item {
    -fx-padding: 0.25em ;
}

这篇关于JavaFx TreeView css的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆