java textvaluechanged 全选删除不触发_JavaFX ChangeListener并不总是有效

message属性被设计为保存任务的“当前消息”的属性:即,目标用例类似于状态消息.在这个用例中,是否永远不会截获存储在属性中的消息只是非常短暂的时间并不重要.的确,documentation for updateMessage()表示:

Calls to updateMessage are coalesced and run later on the FX

application thread,so calls to updateMessage,even from the FX

Application thread,may not necessarily result in immediate updates to

this property,and intermediate message values may be coalesced to

save on event notifications.

(我的重点).因此,简而言之,传递给updateMessage(…)的某些值可能永远不会被设置为messageProperty的值,如果它们被另一个值快速取代的话.通常,每次将帧渲染到屏幕时(每秒60次或更少),您只能观察到一个值.如果你有一个重要的用例,你想要观察每个值,那么你需要使用另一种机制.

一个非常天真的实现只会使用Platform.runLater(…)并直接更新文本区域.我不推荐这种实现方式,因为您可能会因为调用过多而导致FX应用程序线程泛滥(updateMessage(…)合并调用的确切原因),导致UI无响应.但是,此实现看起来像:

for (int i = 1 ; i <= 300; i++) {

String value = "\n" + i ;

Platform.runLater(() -> ta_Statusbereich.appendText(value));

}

另一种选择是使每个操作成为一个单独的任务,并在一些执行器中并行执行它们.附加到每个任务的onSucceeded处理程序的文本区域.在此实现中,结果的顺序不是预先确定的,因此如果顺序很重要,则这不是一个合适的机制:

final int numThreads = 8 ;

Executor exec = Executors.newFixedThreadPool(numThreads,runnable -> {

Thread t = Executors.defaultThreadFactory().newThread(runnable);

t.setDaemon(true);

return t ;

});

// ...

for (int i = 1; i <= 300; i++) {

int value = i ;

Task task = new Task() {

@Override

public String call() {

// in real life,do real work here...

return "\n" + value ; // value to be processed in onSucceeded

}

};

task.setOnSucceeded(e -> ta_Statusbereich.appendText(task.getValue()));

exec.execute(task);

}

如果您想从单个任务完成所有这些操作并控制顺序,那么您可以将所有消息放入BlockingQueue,从阻塞队列中获取消息并将它们放在FX Application线程的文本区域中.为了确保不会使用过多的调用来泛洪FX应用程序线程,您应该每帧渲染一次消息来自队列的消息不超过一次呈现给屏幕.您可以使用AnimationTimer来实现此目的:保证每帧渲染时调用一次handle方法.这看起来像:

BlockingQueue messageQueue = new LinkedBlockingQueue<>();

Task task = new Task() {

@Override

public Void call() throws Exception {

final int numMessages = 300 ;

Platform.runLater(() -> new MessageConsumer(messageQueue,ta_Statusbereich,numMessages).start());

for (int i = 1; i <= numMessages; i++) {

// do real work...

messageQueue.put(Integer.toString(i));

}

return null ;

}

};

new Thread(task).start(); // or submit to an executor...

// ...

public class MessageConsumer extends AnimationTimer {

private final BlockingQueue messageQueue ;

private final TextArea textArea ;

private final numMessages ;

private int messagesReceived = 0 ;

public MessageConsumer(BlockingQueue messageQueue,TextArea textArea,int numMessages) {

this.messageQueue = messageQueue ;

this.textArea = textArea ;

this.numMessages = numMessages ;

}

@Override

public void handle(long now) {

List messages = new ArrayList<>();

messagesReceived += messageQueue.drainTo(messages);

messages.forEach(msg -> textArea.appendText("\n"+msg));

if (messagesReceived >= numMessages) {

stop();

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值