【问题标题】:Java FX How to style an item in a ListView if changedJava FX 如果更改,如何在 ListView 中设置项目的样式
【发布时间】:2018-03-15 17:11:07
【问题描述】:

我有一个 ListView 可以开启/关闭的用户。

我找到了一种根据某些条件设置每个单元格样式的方法:

friends.setCellFactory(lv -> new ListCell<String>() {
                @Override
                protected void updateItem(String friendname, boolean empty) {
                    super.updateItem(friendname, empty);
                    if (empty) {
                        setText(null);
                        setStyle("");
                    } else {
                        setText(friendname);
                        if (usersService.isOnline(friendname)) {
                            do stuf....
                        }
                    }
                }
});

是否有一种方法可以在每次用户打开或关闭时调用此方法?其他然后使用线程,因为我看到它每次调用它都会创建一个新的列表......

【问题讨论】:

    标签: java javafx javafx-8 javafx-2


    【解决方案1】:

    创造一些你可以观察的东西,然后观察它......

    例如如果您的usersService 有一个ObservableList&lt;String&gt; onlineUsers,其中包含所有在线用户的用户名列表,您可以这样做:

    friends.setCellFactory(lv -> {
    
        ListCell<String> cell = new ListCell<String>() {
    
            @Override
            protected void updateItem(String friendname, boolean empty) {
                super.updateItem(friendname, empty);
                if (empty) {
                    setText(null);
                    setStyle("");
                } else {
                    setText(friendname);
                }
            }
    
        };
    
        cell.styleProperty().bind(new StringBinding() {
            { bind(cell.itemProperty(), usersService.getOnlineUsers()); }
            @Override
            protected String computeValue() {
                if (cell.getItem() == null) {
                    return "" ;
                }
                if (usersService.getOnlineUsers().contains(cell.getItem())) {
                    return "/* online style here */";
                }
                return "/* offline style here*/" ;
            }
        });
    
        return cell ;
    
    });
    

    那么每当在线用户列表发生变化时,单元格就会相应更新。

    您可以通过使用外部 CSS 文件和自定义 PseudoClass 来简化此操作:

    PseudoClass online = PseudoClass.getPseudoClass("online");
    
    friends.setCellFactory(lv -> {
    
        ListCell<String> cell = new ListCell<String>() {
    
            @Override
            protected void updateItem(String friendname, boolean empty) {
                super.updateItem(friendname, empty);
                setText(friendname);
            }
    
        };
    
        InvalidationListener listener = obs -> 
            cell.pseudoClassStateChanged(online, 
                cell.getItem() != null
                && usersService.getOnlineUsers().contains(cell.getItem()));
        cell.itemProperty().addListener(listener);
        usersService.getOnlineUsers().addListener(listener);
    
        return cell ;
    
    });
    

    然后在你的 CSS 文件中做

    .list-cell {
        /* offline style rules here */
    }
    .list-cell:online {
        /* online style rules here */
    }
    

    【讨论】:

    • 非常优雅的解决方案!谢谢你,先生!像魅力一样工作!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-03
    • 1970-01-01
    • 2016-08-09
    • 2021-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多