【问题标题】:Bold text in ObservableList breaks ChangeListenerObservableList 中的粗体文本会破坏 ChangeListener
【发布时间】:2016-06-02 04:11:46
【问题描述】:

我希望 ObservableList 中有一个粗体的标题。我把它加粗了,但是当它被选中时它会碰到异常块,因为它不是一个字符串。我可以将其他项目设为 Text,但 ChangeListener 需要一个字符串。我只是希望异常消失。

有没有办法让它不能选择或粗体和字符串类型?

   ListView<String> list = new ListView<>();
   ObservableList items = FXCollections.observableArrayList();
   Task curr = tasklist.head;

   items.add(TextBuilder.create().text("Done Tasks").style("-fx-font-weight:bold;").build());
   items.add(curr.name + " - " + curr.description);
   //items.add(new Text(curr.name + " - " + curr.description));

   try {
        list.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
            public void changed(ObservableValue<? extends String> ov,
                                final String oldvalue, final String newvalue) {
                if(newvalue != "Done Tasks")
                    selectedValue[0] = newvalue.split(" - ")[0];
                else
                    selectedValue[0] = "done";
            }
        });
    } catch(Exception e)
    {
        actiontarget.setFill(Color.FIREBRICK);
        actiontarget.setText("You must select a task.");
    }

【问题讨论】:

    标签: java listview javafx observablelist


    【解决方案1】:

    快速而肮脏的答案

    要直接回答您的愿望“我可以将其他项目设为 Text,但 ChangeListener 需要一个字符串。我只是希望异常消失。”,您可以将 ChangeListener 的类型更改为接受 Object 而不是 String:

    new ChangeListener<Object>() {
        @Override
        public void changed(ObservableValue<? extends Object> observable, Object oldValue, Object newValue) {
            if(!(newvalue instanceof Text)) {
                String string = ((String) newvalue).split(" - ")[0];
                System.out.println(string);
            }
        }
    }
    

    但是,我不推荐上述方法,因为您会失去 Java 环境提供的一些固有类型安全优势。

    编码建议

    一些基于你的代码 sn-p 的建议。

    1. 使用 cell factories 从 ListView 的底层项模型数据生成 ListView 单元节点。
    2. 不要将Text等节点直接放入ListView项列表中。 ListView 项目列表用于表示不是节点的模型对象。我知道ListView javadoc 没有明确说明这一点,但是,这仍然是我最好的建议。每当您认为某个节点非常适合 ListView 时,通常最好的选择是使用单元工厂。
    3. 当您将items 放入 ListView 时,它们应该与 ListView 的项目类型相匹配(ListView 的 javadoc 确实说明了这一点)。
    4. 对于像这里这样的非平凡用例,使用更复杂的数据结构来表示列表中的项目,以便您可以将语义数据(例如项目是否为标题)直接编码到项目而不是硬编码字符串,例如“完成的任务”。
    5. 不要使用 Builder 类,例如 TextBuilder,它们已被弃用,并将从未来的 JavaFX 运行时发行版中删除。
    6. 使用外部样式表并通过设置和取消设置样式类来操作样式,而不是在代码中内联样式定义。

    样本合并建议

    根据建议,您可以将您的问题编码为类似于下面的应用程序(请注意,它仍然没有将样式信息提取到外部样式表,我将把这部分作为练习):

    import javafx.application.Application;
    import javafx.beans.property.SimpleBooleanProperty;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.collections.FXCollections;
    import javafx.scene.Scene;
    import javafx.scene.control.*;
    import javafx.stage.Stage;
    
    public class ListDisplay extends Application {
        @Override
        public void start(Stage stage) {
            ListView<TaskItem> listView = new ListView<>(
                    FXCollections.observableArrayList(
                            new TaskItem("Todo Tasks", null, true, true),
                            new TaskItem("Senility", "The Autumn Years", false, false),
                            new TaskItem("Death", "But I didn't eat the salmon mousse", false, false),
                            new TaskItem("Done Tasks", null, true, true),
                            new TaskItem("Birth", "The Miracle of Life", true, false),
                            new TaskItem("School", "Growth and Learning", true, false),
                            new TaskItem("Middle Age", "Stagnation", true, false),
                            new TaskItem("Live Organ Transplants", "The Machine that goes 'Ping'", true, false)
                    )
            );
    
            listView.setCellFactory(param -> new ListCell<TaskItem>() {
                @Override
                protected void updateItem(TaskItem item, boolean empty) {
                    super.updateItem(item, empty);
    
                    if (!empty && item != null) {
                        if (item.isHeader()) {
                            setText(item.getName());
                            setStyle("-fx-font-weight: bold;");
                        } else {
                            setText(item.getName() + " - " + item.getDescription());
                            setStyle(null);
                        }
                    } else {
                        setText(null);
                    }
                }
            });
    
            listView.setPrefHeight(200);
    
            listView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
                if (!newValue.isHeader()) {
                    System.out.println("Selected: " + newValue.getName());
                }
            });
    
            stage.setTitle("Monty Python's Meaning of Life");
            stage.setScene(new Scene(listView));
            stage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    
        private static class TaskItem {
            private final String name;
            private final String description;
            private final SimpleBooleanProperty completed;
            private final boolean header;
    
            public TaskItem(String name, String description, boolean completed, boolean header) {
                this.name = name;
                this.description = description;
                this.completed = new SimpleBooleanProperty(completed);
                this.header = header;
            }
    
            public boolean isHeader() {
                return header;
            }
    
            public boolean isCompleted() {
                return completed.get();
            }
    
            public SimpleBooleanProperty completedProperty() {
                return completed;
            }
    
            public String getName() {
                return name;
            }
    
            public String getDescription() {
                return description;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-10-02
      • 2019-05-31
      • 1970-01-01
      • 2014-09-04
      • 1970-01-01
      • 1970-01-01
      • 2016-08-04
      • 2015-04-21
      • 1970-01-01
      相关资源
      最近更新 更多