如何从ListView中完全编辑/删除元素?

时间:2015-08-17 14:38:42

标签: java listview javafx

与问题相关的信息:

我有一个类( Shell ),它包含一个任务图,声明为:

private Map<String, Task> _tabs = new HashMap<String,Task>();
private List<Task> _tsks; //this is the result of the function below:

public List<Task> MapToArray() {

    this._tsks = new ArrayList<Task>();
    for(String key : _tabs.keySet()) {
        this._tsks.add(_tabs.get(key));
    }
    return this._tsks;
}

我的应用程序允许用户创建,编辑或删除任务

创建:

shl.createTab(taskName.getText(), taskDescription.getText(), taskAssignee.getText()); //shl is the *Shell* class. 

版:

public void editTask(String name, String description, String assignee) {
        this.deleteTask(loadTask(name));
        _currentTab.setAssignee(findUser(assignee));
        _currentTab.setDescription(description);
        _currentTab.setName(name);
        this.setEmployees(this.getEmployees());
        this.setManagers(this.getManagers());
        this.setTabs(this.getTabs());
        this.setUsers(this.getUsers());

    }

删除:

public void deleteTask(Task currentTab) {
        String exName = this.getCurrentTab().getName();
        this._tabs.remove(loadTask(exName));
        this._tabs.entrySet().remove(exName);
        this._tsks.remove(loadTask(exName));

        System.out.println("Task '"+ exName + "' deleted");

    }

上面,我使用loadTask(name)方法,它执行以下操作:

public Task loadTask(String tabName) {
        return this._tabs.get(tabName);
    }

最后,我的ListView javafx对象声明为:

private ListView<Task> lstView;

填充它的方法是:

    public void refreshList() {

        lstView.setItems(FXCollections.observableArrayList(shl.MapToArray())); //once again, shl is the *Shell* class
        lstView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        lstView.setOnMouseClicked(new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent event) {
                System.out.println("clicked on " + lstView.getSelectionModel().getSelectedItem());
                shl.setCurrentTab((Task) lstView.getSelectionModel().getSelectedItem());
                taskName.setText(shl.getCurrentTab().getName());
                description.setText(shl.getCurrentTaskDescription());
                name.setText(shl.getCurrentTab().getAssignee());
                comment.setText(shl.getCurrentTab().getComment());                
            }
        });
    }

问题本身:

当我创建一个Task时,我的ListView会自动更新并添加到列表中。 - 很棒

然而,我无法理解为什么,当我编辑一项任务时,我发现它已成功更改了我的ListView对象并没有这样做。 t刷新/更新列表。一旦我重新启动程序,我的ListView就会更新。 - 为什么会这样?

另外,我无法删除任何任务。当我调用deleteTask方法时,系统打印&#34;任务已删除&#34;但是我仍然可以在listView上选择并编辑它,并将其与对象一起保存,这样当我加载它时,&#34;删除&#34;任务依旧。

2 个答案:

答案 0 :(得分:1)

使用ObservableList而不是List

来自JavaFX Doc

  

此处显示了如何创建和填充名称ListView(字符串)的简单示例:

     

ObservableList names = FXCollections.observableArrayList(             &#34; Julia&#34;,&#34; Ian&#34;,&#34; Sue&#34;,&#34; Matthew&#34;,&#34; Hannah&#34;,&#34; Stephan& #34;,&#34; Denise&#34;);    ListView listView = new ListView(名称);   ListView的元素包含在ObservableList项中。 ListView会自动观察此ObservableList,因此ObservableList中发生的任何更改都将自动显示在ListView本身中。如果将ObservableList传递给ListView构造函数是不可行的,那么设置项目的推荐方法是简单地调用:

     

ObservableList content = ...    listView.setItems(内容);   如上所述,最终结果是ListView将自动刷新视图以表示列表中的项目。   另一种方法虽然被ListView接受,但不是推荐的方法:

     

列出内容= ...    getItems()SETALL(内容)。   上面显示的方法的问题是内容列表被复制到项目列表中 - 这意味着不会观察到对内容列表的后续更改,并且不会在ListView中以可视方式反映。

答案 1 :(得分:0)

我没有完全理解你的问题,但试试看看是否有帮助:

在您创建&#34; lstview&#34;:

的位置添加
lstview.setCellFactory(new Callback<ListView<Task>, ListCell<Task>>() {
        @Override
        public ListCell<Task> call(ListView<Task> param) {
            return new ListCell<Task>(){
                @Override
                protected void updateItem(Task item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item != null && !empty) {
                        setText(item.toString());
                    } else {
                        setText(null);
                    }
                }
            };
        }
    });

我没有运行此代码,但它可能有错误,但想法是当你有一个包含String以外的对象的listview时;你应该设置单元格工厂,以便列表视图知道如何显示该对象以及当项目为空或空时显示的内容。