我面临潜在的追逐错误。我使用javafx TableView来显示我的数据,并且我定期在外部接收一个调用我的更新功能的更新请求。我也有一些听众会做一些事情,比如处理mousedrag事件等等。我想做的是做这样的事情:
private void handleEvent(){
TableView.setRowFactory(new Callback<TableView<MyModel>, TableRow<MyModel>>(){
public TableRow<MyModel> call(TableView<MyModel> p) {
final TableRow row = new TableRow();
row.setOnDragDetected(new EventHandler<MouseEvent>(){
public void handle(){
//implement some kind of lock to prevent receiving data update
}
}
row.setOnMouseDragExited(new EventHandler<MouseDragEvent>(){
//release lock to accept update
}
}
}
//this method is being called externally periodically
public void updateModel(MyModel model){
//this won't work because it will skip entirely if it's locked,
//I want it to instead run later when lock is released
if (!locked){
this.model = model;
}
}
我做了一个快速的解决方法,使用布尔来锁定和解锁,如updateModel方法所示,问题是它会丢失一些更新的数据,因为它被完全跳过..相反,我希望它在以后锁定释放时运行..如何实现这种锁机制并运行以后的功能?
编辑:为什么我怀疑这是因为我的听众正在操纵并获取表数据..虽然数据不断更新,但我不确定这是否会导致我的表中断。
答案 0 :(得分:2)
只需编写一些逻辑,收集您在锁定状态下尝试执行的所有操作,并在解锁时执行。
以下代码假定您使用{
read: true,
create: true,
delete: false,
update: false
}
或类似的代码,使更新在应用程序线程上运行。
Platform.runLater
如果上次更新总是覆盖以前更新的所有数据,只需保留一个public class UpdateSynchronizer {
private final List<Runnable> pendingUpdates = new ArrayList<>();
private boolean locked = false;
public void lock() {
if (locked) {
throw new IllegalStateException("double lock");
} else {
locked = true;
}
}
public void runUpdate(Runnable updater) {
if (updater == null) {
throw new IllegalArgumentException();
}
if (locked) {
pendingUpdates.add(updater);
} else {
updater.run();
}
}
public void unlock() {
for (Runnable r : pendingUpdates) {
try {
r.run();
} catch(Exception ex) {
ex.printStackTrace(); // print but ignore
}
}
pendingUpdates.clear();
locked = false;
}
}
而不是列表,就会更有效。
Runnable