【问题标题】:ListView Colors in JavaJava中的ListView颜色
【发布时间】:2019-05-03 09:40:47
【问题描述】:

我正在尝试通过 ListCell 在我的 Listview 中添加背景颜色。

我的 ListView 工作正常,但 ListCell 出现问题。它以某种方式覆盖每个 ListView 项目之后的颜色。我目前的结果是,只有我的 ListView 的最后一项获得背景颜色灰色(因为它的优先级是“中性”)。我的建议是,每个 ListCell 都覆盖之前的一个,以便之前设置的颜色更新为“null”,因为当前项目的优先级不同。 请问有人有什么想法吗?

编辑: 我尝试了费边的建议。我可以创建笔记,但不知何故,笔记的名称仍然是记事本 ID(即“Notepad@”HexCode“”)。此外,颜色不起作用。这是我正在实施的完整方法:

    public void initialize() throws SQLException {
    //initializing listView
    notesListView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
    //initializing listView items depending on instance + depending on User
    if (this.objectType instanceof Student) {
        ObservableList<Notepad> list = FXCollections.observableArrayList();
        for(StudentNotepad s : db.getStudentNotepadDao()) {
            if(db.getLoggedInUser() == s.getNotepad().getUser()) {
                list.add(s.getNotepad());
            }
        }
        notesListView.setItems(list);
            notesListView.getItems().clear(); // this is not necessary, if the list is guaranteed to be empty
            db.getStudentNotepadDao().queryForAll().stream()
                    .map(StudentNotepad::getNotepad)
                    .filter(n -> n.getUser().equals(db.getLoggedInUser()))
                    .forEach(notesListView.getItems()::add);
            notesListView.setCellFactory(new Callback<ListView<Notepad>, ListCell<Notepad>>() {
                public ListCell<Notepad> call(ListView<Notepad> param) {
                    return new ListCell<Notepad>() {
                        @Override
                        protected void updateItem(Notepad item, boolean empty) {
                            super.updateItem(item, empty);

                            String style = "";
                            if (!empty && item != null) {
                                setText(item.getNotepadName());

                                // this switch could be rewritten using a Map<String, String>
                                switch (item.getNotepadPriority()) {
                                    case "Hoch":
                                        style = "-fx-background-color: red";
                                        break;
                                    case "Mittel":
                                        style = "-fx-background-color: yellow";
                                        break;
                                    case "Niedrig":
                                        style = "-fx-background-color: green";
                                        break;
                                    case "Neutral":
                                        style = "-fx-background-color: grey";
                                        break;
                                }
                            } else {
                                setText("");
                            }
                            setStyle(style);
                        }

                    };
                }
            });
        }

}

【问题讨论】:

    标签: listview javafx background-color


    【解决方案1】:

    ListCells 都是由同一个工厂创建的。多次替换工厂导致最后一个工厂创建单元格,而不是在与项目对应的迭代期间由工厂集创建的单元格。

    n.getNotepad().getNotepadName().equals(item)
    

    因此,仅对单个项目产生 true。

    在这里使用ListView&lt;Notepad&gt;(我假设StudentNotepad.getNotepad 返回一个Nodepad 类型的对象)。

    以下代码还假设db.getStudentNotepadDao().queryForAll() 返回Collection。如果它返回一个数组,请使用Stream.of 并将数组作为参数,而不是使用stream() 方法。

    notesListView.getItems().clear(); // this is not necessary, if the list is guaranteed to be empty
    db.getStudentNotepadDao().queryForAll().stream()
                                           .map(StudentNotepad::getNotepad)
                                           .filter(n -> n.getUser().equals(db.getLoggedInUser()))
                                           .forEach(notesListView.getItems()::add);
    
    notesListView.setCellFactory(new Callback<ListView<Notepad>, ListCell<Notepad>>() {
        public ListCell<Notepad> call(ListView<Notepad> param) {
            return new ListCell<Notepad>() {
                @Override
                protected void updateItem(Notepad item, boolean empty) {
                    super.updateItem(item, empty);
    
                    String style = "";
                    if (!empty && item != null) {
                         setText(item.getNotepadName());
    
                         // this switch could be rewritten using a Map<String, String>
                         switch (item.getNotepadPriority()) {
                             case "Hoch":
                                 style = "-fx-background-color: red";
                                 break;
                             case "Mittel":
                                 style = "-fx-background-color: yellow";
                                 break;
                             case "Niedrig":
                                 style = "-fx-background-color: green";
                                 break;
                             case "Neutral":
                                 style = "-fx-background-color: grey";
                                 break;
                         }
                    } else {
                        setText("");
                    }
                    setStyle(style);
                }
    
            };
        }
    });
    

    【讨论】:

    • 您好 Fabian,非常感谢您的回复! ListView 的问题是,这样做之后,ListView 显示的记事本地址 ID 看起来像 "Notepad@"some hex address" " 这就是我使用 ListView 的原因,即记事本的名称.
    • @KaanErdogan 我的答案中的方法的结果应该在循环结束时显示studentNotes 列表的内容:Stream&lt;StudentNotepad&gt; 使用.map(StudentNotepad::getNotepad) 映射到Stream&lt;Notepad&gt;。其余操作不会更改类型。这会导致单元格接收将在您的代码中使用getNotepadName() 转换为字符串的对象,因此执行相同操作以获取ListCell.text 属性(setText(item.getNotepadName());) 的新值应该会导致显示相同的文本。
    • 是的,我刚刚在您的示例中意识到这一点。非常感谢,我浪费了好几个小时试图弄清楚如何处理这个问题。
    • 您好 Fabian,我刚刚尝试了您的建议,但我认为无法实施。我编辑了我之前的问题,你能给我反馈吗?
    • 使用== 而不是equals() 比较用户可能是个坏主意。此外,我建议只添加一次项目。您应该能够删除循环或流+清除调用,因为它们都有效地做同样的事情。重要的部分是添加 Notepad 类的结构并检查值是否按照您认为的方式初始化,例如通过使用调试器或添加一些打印语句。
    【解决方案2】:

    你的代码有很多问题。

    1. 您可以将studentNotes 声明为ObservableList 并直接使用它而无需多余的临时list(除非您出于某种原因真的想使用ArrayList,我不认为你这样做)。

    2. 您应该在循环之后调用notesListView.setItemsnotesListView.setCellFactory,而不是在循环内部。然后在您的updateItem 方法中,您需要进行搜索以获取与传递给它的item 对应的StudentNotepad 对象。

    3. 如果您将notesListView 声明为ListView&lt;Notepad&gt;(我假设这是您用于记事本对象的类),这将简化很多事情,以便updateItem 为您提供@987654334直接@对象,然后您可以使用调用setText并传递您要显示的属性。如果您不确定如何操作,可以查看This SO thread

    【讨论】:

      猜你喜欢
      • 2021-05-28
      • 2018-06-14
      • 1970-01-01
      • 2015-06-04
      • 2019-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多