JavaFX-从后台任务为TextArea调用“ updateMessage”-找到两个问题

问题描述 投票:0回答:1

[在尝试在JavaFX任务中使用“ updateMessage”时遇到两个问题。

问题#1似乎是一种已知的行为,但我不确定该如何解决它,这对我来说还不是关键。问题在于,并非我在后台任务中执行的所有更新都显示在UI中(至少UI不再挂起/冻结,这是我最初的问题)。

UI部分的我的代码:

TextArea console = new TextArea();
        Button button01 = new Button("Start");
        button01.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {

                if (ms.getState() == State.READY) {
                    ms.messageProperty().addListener(new ChangeListener<String>() {
                        @Override
                        public void changed(ObservableValue<? extends String> observable,
                                String oldValue, String newValue) {

                            console.appendText(newValue+"\n");
                        }
                    });
                    ms.start();
                }
            }

        });

我的服务:

public class MyService extends Service<Object> {

    @Override
    protected Task createTask() {
        //here we use "MyTask" first to show problem #1
        MyTask ct = new MyTask();
        //here we use "MyTask2" first to show problem #2
//      MyTask2 ct = new MyTask2();
        try {
            ct.call();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("MyService end");
        return ct;
    }
}

我的任务(#1)

public class MyTask extends Task<Object> {

    @Override
    public EventHandler<WorkerStateEvent> call() {
        System.out.println("call() is called");
        if (Thread.currentThread().getName().equals("JavaFX Application Thread")){//yes, this might not be right, but if I do not do this, my stuff is executed twice because "call()" is called twice, but the textarea area is just updated in the second run (the non javafx application thread).
            return null;
            } else{
            //actually here I want to do some 'heavy' stuff in the background
            //and many things of this heavy stuff should be displayed / logged within the UI
            //but very likely (hopefully) new messages (updateMessage) will not be send as fast as in the following loop

            for (int i=0;i<10000000;i++){
                updateMessage("This is update number'"+i+"' from the background thread");
            }

            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    try{
                        //here is the chance to get back to the view

                    }finally{
                    }
                }
            });

            return null;
        }
    }

这基本上是有效的,但并不是每个循环都显示在UI中。如何(正确)确保显示每个循环?Screenshot: Messages are displayed but not for every loop

问题2目前阻止我尝试将基于文本的小游戏引入JavaFX应用程序。主要问题是我可以直接从Task调用“ updateMessage”(请参见上文),而不能从另一个(子)类调用,我需要从游戏中获取所有消息更新(每个消息都描述了进度)游戏的界面)。

我使用的任务(任务2):

public class MyTask2 extends Task<Object> {

    @Override
    public EventHandler<WorkerStateEvent> call() {
        // ...
        UITools myTools = new UITools();
        myTools.logToUITest("Just one simple message");
        // ...
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                try{
                    //here is the chance to get back to the view
                }finally{
                }
            }
        });

        return null;
    }

和我想用来执行updateMessage的(子)类(实际上,在我的小游戏中,在游戏过程中会调用更多的类,并且几乎所有这些类都会触发更新/消息)。

public class UITools  {
    public void logToUITest(String message){
        updateMessage(message);
        //how to allow 'updateMessage' from the Task to be executed from here?
    }

这已经导致“方法updateMessage(String)未定义...”。如何使在Task本身之外调用updateMessage成为可能?

javafx textarea subclass updates background-thread
1个回答
0
投票

updateMessage只能从Task的call()方法中调用,这是Task类设计的约束。错过的消息更新是由于存在太多的更新,并且并非所有更新都转发到事件队列。尝试减少更新次数或休眠一小会儿,以便及时将它们分开

© www.soinside.com 2019 - 2024. All rights reserved.