基本的な問題は、commitHandlerによる再編集がキャンセルされることです。キャンセルを引き起こすことができる多くの(そして複雑な)パスがありますが、そのうちの1つは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);
}
}
は私にはバグのように見えません:イベントシーケンス奇妙です - あなたがデータを変更するとき、新しいアイテムを設定することで(FI)、中間cancelEventがあります...仮想コントロールの編集は実際には本当に壊れています... – kleopatra
理由は「https://bugs.openjdk.java.net/browse/JDK-8094887」の「修正」になる可能性があります。基礎データ – kleopatra