java 如何从自定义类中更新进度

ckocjqey  于 2023-06-20  发布在  Java
关注(0)|答案(2)|浏览(105)

我需要从worker/task线程中的自定义类更新进度。我该怎么做?

public Task createWorker() {
    Task task = new Task() {

        @Override
        protected Object call() throws Exception {
            DocumentProcessor dp = new DocumentProcessor();
            dp.proces(this);
        }

        public void notifyTask(String _msg, long _stepNumber, long _totalSteps ){
            updateMessage(_msg);
            updateProgress(_stepNumber, _totalSteps);
        }
    };
}

分类:

public class DocumentProcessor {
    public void proces(Task _task){
         // Step 1
         _task.notifyTask("Step 1 done", 1 ,2); // ERROR: no function with that name

         // Step 2
         _task.notifyTask("Step 2 done", 2 ,2);

    }
}

调用

Task worker = createWorker();
    new Thread(worker).start();

notifyTask函数不可用。

hl0ma9xz

hl0ma9xz1#

notifyTask方法不可用,因为它没有包含在Task类中,而是在您的(匿名)子类中定义的。
例如,您可以创建一个命名的子类并将其传递给DocumentProcessor

public class NotifiableTask extends Task {
    @Override
    protected Object call() throws Exception {
        DocumentProcessor dp = new DocumentProcessor();
        dp.proces(this);
    }

    public void notifyTask(String _msg, long _stepNumber, long _totalSteps ){
       updateMessage(_msg);
       updateProgress(_stepNumber, _totalSteps);
   }
}
public Task createWorker() {
   return new NotifiableTask();
}

public class DocumentProcessor {
    public void proces(NotifiableTask _task){
       // Step 1
       _task.notifyTask("Step 1 done", 1 ,2); // function is now available because it's defined in NotifiableTask
       // Step 2
       _task.notifyTask("Step 2 done", 2 ,2);

    }
}

Task worker = createWorker();
new Thread(worker).start();

你也可以定义一个接口,并让你的类实现它,以实现更松散的耦合。

public interface Notifiable {
    void notifyTask(String _msg, long _stepNumber, long _totalSteps);
}

public class NotifiableTask extends Task implements Notifiable {
    // implement Task's call()
    @Override
    protected Object call() throws Exception {
        DocumentProcessor dp = new DocumentProcessor();
        dp.proces(this);
    }

    // implement Notifiable's notifyTask
    public void notifyTask(String _msg, long _stepNumber, long _totalSteps ){
       updateMessage(_msg);
       updateProgress(_stepNumber, _totalSteps);
   }
}
public Task createWorker() {
   return new NotifiableTask();
}

public class DocumentProcessor {
    // we don't need Task's call() method here, so pass the Notifiable only
    public void proces(Notifiable _task){
       // Step 1
       _task.notifyTask("Step 1 done", 1 ,2); // function is now available because it's declared in Notifiable
       // Step 2
       _task.notifyTask("Step 2 done", 2 ,2);

    }
}

Task worker = createWorker();
new Thread(worker).start();

您可能需要将NotifiableTask声明为当前定义createTask方法的内部类,因为它需要在notifyTask()期间调用其他方法(updateMessage()updateProgress())。实际上,由于任务本身只委托这个调用,您还不如在外部类中声明接口并在那里执行更新;但这取决于上下文,并且很难说清楚,因为您显然只提供了一个最小化的示例。

5gfr0r5j

5gfr0r5j2#

您遇到的问题是**Task类中没有定义notifyTask方法。要解决这个问题,可以创建一个Task的自定义子类,其中包含notifyTask**方法,然后使用该子类。这可能是一个更简单和更直接的方法。你可以试试这个:

public class CustomTask extends Task<Void> {

    @Override
    protected Void call() throws Exception {
        DocumentProcessor dp = new DocumentProcessor();
        dp.process(this);
        return null;
    }

    public void notifyTask(String _msg, long _stepNumber, long _totalSteps) {
        updateMessage(_msg);
        updateProgress(_stepNumber, _totalSteps);
    }
}

public class DocumentProcessor {
    public void process(CustomTask _task) {
        // Step 1
        _task.notifyTask("Step 1 done", 1, 2);

        // Step 2
        _task.notifyTask("Step 2 done", 2, 2);
    }
}

// Usage
CustomTask worker = new CustomTask();
new Thread(worker).start();

这样就可以创建一个名为**CustomTask的子类,它扩展了Task<Void>。包含notifyTask方法,可从DocumentProcessor类调用。创建worker时,示例化CustomTask,而不是Task。这样,您就可以访问DocumentProcessor类中的notifyTask方法。
或者,如果您想在不修改
Task class的情况下,从DocumentProcessor类内部更新进度和消息,可以通过回调接口或函数接口给DocumentProcessor**构造函数。你可以试试这个:

import javafx.application.Platform;

public class DocumentProcessor {
    private ProgressCallback progressCallback;

    public DocumentProcessor(ProgressCallback callback) {
        this.progressCallback = callback;
    }

    public void process() {
        // Step 1
        progressCallback.notifyTask("Step 1 done", 1, 2);

        // Step 2
        progressCallback.notifyTask("Step 2 done", 2, 2);
    }

    public interface ProgressCallback {
        void notifyTask(String message, long stepNumber, long totalSteps);
    }
}

public class Main {
    public static void main(String[] args) {
        DocumentProcessor.ProgressCallback callback = new DocumentProcessor.ProgressCallback() {
            @Override
            public void notifyTask(String message, long stepNumber, long totalSteps) {
                // Update the progress and message in the UI thread
                Platform.runLater(() -> {
                    // Update your UI elements with the progress and message
                    System.out.println(message);
                });
            }
        };

        DocumentProcessor processor = new DocumentProcessor(callback);

        Task<Void> task = new Task<Void>() {
            @Override
            protected Void call() throws Exception {
                processor.process();
                return null;
            }
        };

        Thread worker = new Thread(task);
        worker.start();
    }
}

其中**DocumentProcessor类在其构造函数中有一个ProgressCallback接口,该接口定义了notifyTask方法。回调中的notifyTask方法负责更新UI中的进度和消息,或者其他任何需要的方式。
Main类中,匿名实现ProgressCallback接口,并传递给DocumentProcessor构造函数。在回调实现中,我们使用Platform.runLater()更新UI元素,以确保在UI线程上执行更新。
这里我使用
System.out.println()**来演示进度更新。您应该用适当的代码来替换它,以便用进度和消息更新UI元素。

相关问题