JavaFX:在onEditCommit函数中使用ListView.edit(int itemIndex)和
我试图在javaFX中创建一个可编辑的列表视图,该视图对用户来说很容易使用。为此,我使用了on edit commit函数。它通常非常擅长做我想让它做的事情,但我遇到了一个问题。每次用户编辑最后一个项目时,我希望它生成另一个项目并开始编辑该项目。这看起来似乎很琐碎,但是我在JavaFX:在onEditCommit函数中使用ListView.edit(int itemIndex)和,java,listview,javafx,Java,Listview,Javafx,我试图在javaFX中创建一个可编辑的列表视图,该视图对用户来说很容易使用。为此,我使用了on edit commit函数。它通常非常擅长做我想让它做的事情,但我遇到了一个问题。每次用户编辑最后一个项目时,我希望它生成另一个项目并开始编辑该项目。这看起来似乎很琐碎,但是我在setOnEditCommit函数中从中运行dit函数时遇到了问题。这是我的密码: personList.setOnEditCommit(new EventHandler<ListView.EditEvent<S
setOnEditCommit
函数中从中运行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.setOnEditCommit(新的EventHandler(){
@凌驾
公共无效句柄(ListView.EditEvent t){
personList.getItems().set(t.getIndex(),t.getNewValue());
if(personList.getSelectionModel().getSelectedDices().contains(personList.getItems().size()-1)){
int personNumber=personList.getItems().size()+1;
personList.getItems().add(“person”+personNumber);
personList.edit(personList.getItems().size()-1);//不起作用的行。
}
}
});
注意:personlist是一个ListView
在
setOnEditCommit
上的集合中,是否仍然可以从中运行编辑功能。谢谢。基本问题是提交人的重新编辑被取消。有许多(复杂的)路径可以触发取消,其中一个似乎是“修复”,它相当粗鲁地取消对数据更改的任何编辑
但这不可能是全部原因,因为重新编辑后收到的取消是在单元配置期间触发的,大致如下:
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
我能想到的唯一解决办法是非常脆弱的:像你一样启动重新编辑,然后启动一个计时器“等待”,直到所有内部配置完成,然后再次编辑。显然,我们不想在生产代码中执行任何操作;)
导入javafx.animation.KeyFrame;
导入javafx.animation.Timeline;
导入javafx.application.application;
导入javafx.collections.FXCollections;
导入javafx.scene.scene;
导入javafx.scene.control.ListView;
导入javafx.scene.control.cell.TextFieldListCell;
导入javafx.scene.layout.BorderPane;
导入javafx.stage.stage;
导入javafx.util.Duration;
/**
*正在尝试在commitHandler中添加项目/开始编辑新项目:
* https://stackoverflow.com/q/46047134/203657
*
*最后一次尝试:使用计时器稍后开始编辑。。
*/
公共类ListViewAutoEditInHandler扩展了应用程序{
私有ListView单纯形列表;
private int expectedEditIndex=-1;
专用定时器;
/**
*editTimer的回调。实现为滚动到并强制
*在expectedEditIndex处编辑单元格。
*/
私有void checkEdit(){
如果(expectedEditIndex<0)返回;
如果(expectedEditIndex==simpleList.getEditingIndex()){
expectedEditIndex=-1;
返回;
}
int index=expectedEditIndex;
expectedEditIndex=-1;
simpleList.scrollTo(索引);
编辑(索引);
}
@凌驾
公共无效开始(阶段primaryStage){
editTimer=新的时间线(新的关键帧(Duration.millis(100),ae->checkEdit());
simpleList=newListView(FXCollections.observableArrayList(“Item1”);
simpleList.setEditable(true);
simpleList.setCellFactory(TextFieldListCell.forListView());
simpleList.setOnEditStart(t->p(“编辑开始:+t.getIndex()));
simpleList.setOnEditCancel(t->p(“编辑取消:+t.getIndex()));
simpleList.setOnEditCommit(t->{
p(“编辑提交:+t.getIndex());
//对项目的任何修改都将触发取消
simpleList.getItems().set(t.getIndex(),t.getNewValue());
//p(“编辑?”+simpleList.getEditingIndex());
如果(t.getIndex()==simpleList.getItems().size()-1){
expectedEditIndex=t.getIndex()+1;
simpleList.getItems().add(“newItem”);
simpleList.getSelectionModel().select(expectedEditIndex);
simpleList.edit(expectedEditIndex);
//…所以我们启动计时器强制
//取消脆性解决方案的注释;)
//editTimer.playFromStart();
}否则{
//重置..这里有点偏执;)
expectedEditIndex=-1;
editTimer.stop();
}
});
BorderPane根=新的BorderPane(simpleList);
场景=新场景(根,300,250);
setTitle(“你好,世界!”);
初级阶段。场景(场景);
primaryStage.show();
}
私有静态无效p(字符串t){
系统输出打印ln(t);
}
公共静态void main(字符串[]args){
发射(args);
}
}
在我看来似乎是个bug:事件序列很奇怪-当你修改数据时(通过设置新项,f.i.),会出现一个中间事件。。。编辑虚拟控件是真的,真的是坏了…原因可能是“修复”-对基础数据的任何更改都会取消编辑谢谢,我在生产中这样做,但是,所以。。。这是应该发生的错误还是可以报告的错误?这就是问题所在;)在提交后接收cancel显然是一个bug,我认为(在默认处理程序中也会发生,报告为)就像在commitHandler中启动另一个编辑一样。。我不太确定:在能够可靠地开始另一个周期之前,系统可能需要完成从编辑到不编辑的状态转换。另一方面,需求非常简单,我不知道如何/在哪里实现它。
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);
}
}