【问题标题】:JavaFX: use ListView.edit(int itemIndex) with in the onEditCommit functionJavaFX:在 onEditCommit 函数中使用 ListView.edit(int itemIndex)
【发布时间】:2017-09-05 04:42:32
【问题描述】:

我正在尝试在 javaFX 中创建一个易于用户使用的可编辑列表视图。为此,我使用了 on edit commit 功能。它通常非常擅长做我想做的事情,但是我遇到了一个问题。每次用户编辑最后一个项目时,我希望它制作另一个项目并开始编辑它。这似乎是微不足道的,但是我在setOnEditCommitfunction 中运行 dit 函数时遇到了问题。这是我的代码:

 personList.setOnEditCommit(new EventHandler<ListView.EditEvent<String>>() {
        @Override
        public void handle(ListView.EditEvent<String> t) {
            personList.getItems().set(t.getIndex(), t.getNewValue());

            if(personList.getSelectionModel().getSelectedIndices().contains(personList.getItems().size()-1)) {
                int personNumber = personList.getItems().size() + 1;
                personList.getItems().add("person " + personNumber);
                personList.edit(personList.getItems().size()-1); //the line that is not working.
            }
        }

    });

注意:personlist 是一个 ListView

无论如何可以从setOnEditCommit 的集合中运行编辑功能。谢谢。

【问题讨论】:

  • 对我来说看起来像一个错误:事件序列很奇怪 - 在您修改数据的那一刻(通过设置新项目),有一个中间的 cancelEvent ...编辑虚拟控件真的是真的坏了……
  • 原因可能是“修复”bugs.openjdk.java.net/browse/JDK-8094887 - 对基础数据的任何更改都会取消编辑

标签: java listview javafx


【解决方案1】:

基本问题是commitHandler的重新编辑被取消了。有许多(且复杂的)路径可以触发取消,其中一个似乎是对JDK-8094887 的“修复”,它相当粗鲁地取消了对数据更改的任何编辑。

但这不可能是全部,因为在单元格配置期间触发了重新编辑后收到的取消,大致:

indexedCell.updateIndex(index)
-> listCell.indexChanged(oldIndex, newIndex)
-> listCell.updateFocus()
-> node.setFocused(xx)  //for some reason xx is false
-> cell.focusedListener 
-> cancelEdit()

运行下面的示例,编辑单个项目,按 ENTER 产生输出:

edit start: 0   // start edit on last row
edit commit: 0  // commit the edit by items.set(...)
edit cancel: -1 // cancel triggered by modification
edit start: 1   // re-edit the added item
edit cancel: -1 // cancel triggered by cell config

我能想到的唯一出路是非常脆弱的:像你一样开始重新编辑,然后还启动一个计时器,“等待”直到所有内部配置完成并再次编辑。显然,我们不想在生产代码中做任何事情;)

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.control.cell.TextFieldListCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Duration;

/**
 * Trying to add item/start edit on new item in commitHandler:
 * https://stackoverflow.com/q/46047134/203657
 * 
 * one last try: use timer to start editing some time later ..
 */
public class ListViewAutoEditInHandler extends Application {

    private ListView<String> simpleList;
    private int expectedEditIndex = -1;
    private Timeline editTimer;

    /**
     * Callback for editTimer. Implemented to scroll to and force
     * edit of cell at expectedEditIndex.
     */
    private void checkEdit() {
        if (expectedEditIndex < 0) return;
        if (expectedEditIndex == simpleList.getEditingIndex()) {
            expectedEditIndex = -1;
            return;
        }
        int index = expectedEditIndex;
        expectedEditIndex = -1;
        simpleList.scrollTo(index);
        simpleList.edit(index);
    }

    @Override
    public void start(Stage primaryStage) {
        editTimer = new Timeline(new KeyFrame(Duration.millis(100), ae -> checkEdit() ));
        simpleList = new ListView<>(FXCollections.observableArrayList("Item1"));
        simpleList.setEditable(true);

        simpleList.setCellFactory(TextFieldListCell.forListView());

        simpleList.setOnEditStart(t -> p("edit start: " + t.getIndex()));
        simpleList.setOnEditCancel(t -> p("edit cancel: " + t.getIndex()));
        simpleList.setOnEditCommit(t -> {
            p("edit commit: " + t.getIndex());
            // any modification of the items will trigger a cancel
            simpleList.getItems().set(t.getIndex(), t.getNewValue());
            //  p("editing? " + simpleList.getEditingIndex());
            if (t.getIndex() == simpleList.getItems().size() - 1) {
                expectedEditIndex = t.getIndex() + 1;
                simpleList.getItems().add("newItem");
                simpleList.getSelectionModel().select(expectedEditIndex);
                simpleList.edit(expectedEditIndex);
                // ... so we start a timer to force
                // uncomment for a brittle solution ;)
                // editTimer.playFromStart();
            } else {
                // reset .. a bit paranoid here ;)
                expectedEditIndex = -1;
                editTimer.stop();
            }

        });


        BorderPane root = new BorderPane(simpleList);
        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private static void p(String t) {
        System.out.println(t);
    }
    public static void main(String[] args) {
        launch(args);
    }
}

【讨论】:

  • 谢谢,但是我正在生产中这样做,所以...这是应该发生的错误还是可以报告的错误?
  • 这就是问题 ;) 我认为在提交后接收取消显然是一个错误(默认处理程序也会发生,报告为bugs.openjdk.java.net/browse/JDK-8187307)至于在 commitHandler 中开始另一个编辑..我不太确定:系统可能需要完成从编辑到非编辑的状态转换,然后才能可靠地开始另一个循环。另一方面:需求很简单,我看不出如何/在哪里实现它。
猜你喜欢
  • 2015-08-28
  • 1970-01-01
  • 2013-04-24
  • 1970-01-01
  • 2016-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多