簡體   English   中英

如何強制程序等待任務並向用戶顯示進度欄?

[英]How force the program wait a Task and show Progress Bar to user?

我在程序中使用了Swing應用程序框架。 而且我有一些長期的工作。 我使用org.jdesktop.application.Task 在我接受這個項目之前,另一個程序員編寫了兩個任務(我不能向他詢問編程問題)。 當執行任務時,用戶會看到進度條,但未顯示完成百分比,但是顯示“等待”消息的用戶無法在任務未結束時單擊主窗口。 沒事! 但是我找不到創建ProgressBars的地方。 可能是在某些xml文件或屬性文件中描述的嗎?

我還寫了另一個任務,當它們運行時,我創建的進度條沒有顯示或顯示不正確。 我閱讀了有關ProgressBar和ProgressMonitor的信息,但這對我沒有幫助。 程序在someTask.execute()之后繼續運行,但是我希望它顯示ProgressBar,ProgressMonitor或其他內容,並且用戶無法單擊主窗口,並且窗口將正確顯示。 現在,當用戶對其進行更改時,窗口具有黑色的“塊”。

可能是我需要使用org.jdesktop.application.TaskMonitor 我嘗試在這里使用它https://kenai.com/projects/bsaf/sources/main/content/other/bsaf_nb/src/examples/StatusBar.java?rev=235 ,但是我的主窗口顯示不正確,我的不顯示ProgressBar。

我需要在Task正在運行時程序等待它,但是用戶可以看到ProgressBar,可以取消操作並且不能單擊到主窗口。 我該怎么做?

這是我的代碼:

public class A{
@Action(name = "ActionName", block = Task.BlockingScope.APPLICATION)
public RequestInfoTask requestInfo() {
        RequestInfoTask task = new RequestInfoTask(Application.getInstance());
        isSuccessedGetInfo=false;

        task.addTaskListener(new TaskListener.Adapter<List<InfoDTO>, Void>() {
            @Override
            public void succeeded(TaskEvent<List<InfoDTO>> listTaskEvent) {
                isSuccessedGetResources=true;
            }
        });

        //Here I want to the program shows ProgressMonitor and user can not click to the main window.
        //But small window with message "Progress..." is displayed for several seconds and disappear.
        ProgressMonitor monitor = new ProgressMonitor(getMainView(), "Wait! Wait!", "I am working!", 0, 100);
        int progress = 0;
        monitor.setProgress(progress);
        while(!task.isDone()){
            monitor.setProgress(progress+=5);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
        }
        monitor.setProgress(100);

        //This code must run after "task" finishes.
        if(isSuccessedGetInfo){
            MyTask2 task2 = new MyTask2(Application.getInstance());
            isSuccessedTask2=false;
            task2.addTaskListener(new TaskListener.Adapter<Map<?,?>, Void>(){

                @Override
                public void succeeded(TaskEvent<Map<String, ICredential>> arg0) {
                    isSuccessedTask2=true;
                }
            });
            //Do something with results of task2.
        }

        return task;
    }
}

public class RequestInfoTask extends Task<List<InfoDTO>, Void> {

    public RequestInfoTask(Application application) {
        super(application);
    }

    @Override
    protected List<InfoDTO> doInBackground() throws Exception {
        List<InfoDTO> result = someLongerLastingMethod();
        return result;
    }

}

您的部分問題聽起來像是由於未正確使用EDT而引起的 任何長時間運行的任務都需要在其自己的線程中啟動,以保持GUI響應和重新繪制。

理想情況下,您將遵循MVC模式 在這種情況下,將進度條放置在視圖中,將標記(指示任務是否應該仍在運行)放置在控件中,將長期運行的任務放置在模型中。

從那時起,如果您的模型定期檢查是否應該停止(可能在良好的停止點),則可以重置所有內容。

這是MVC的示例:

import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;


public class ProgressBarDemo{

    public static class View extends JPanel{
        Controller control;
        public JProgressBar progressBar = new JProgressBar(0, 100);
        JButton button = new JButton("Start Long Running Task");

        public View(Controller controlIn){
            super();
            this.control = controlIn;
            setLayout(new BorderLayout());

            button.addActionListener(new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent e) {
                    //Toggle between running or not
                    if(control.isRunning){
                        control.isRunning = false;
                        button.setText("Canceling...");
                        button.setEnabled(false);
                    } else{
                        control.isRunning = true;
                        button.setText("Cancel Long Running Task");
                        control.startTask();
                    }
                }});

            progressBar.setStringPainted(true);
            add(progressBar);
            add(button, BorderLayout.SOUTH);
        }   
    }

    //Communications gateway
    public static class Controller{ 
        View view = new View(this);
        boolean isRunning = false;

        public void updateProgress(final int progress){
            SwingUtilities.invokeLater(new Runnable(){
                @Override
                public void run() {
                    view.progressBar.setValue(progress);
                }});
        }

        public void reset(){
            SwingUtilities.invokeLater(new Runnable(){
                @Override
                public void run() {
                    isRunning = false;
                    view.button.setText("Start Long Running Task");
                    view.progressBar.setValue(0);
                    view.button.setEnabled(true);
                }});
        }

        public void startTask(){
            LongRunningClass task = new LongRunningClass(this);
            new Thread(task).start();
        }
    }

    public static class LongRunningClass implements Runnable{

        Controller control;
        public LongRunningClass(Controller reference){
            this.control = reference;
        }

        @Override
        public void run() {
            try {
                for(int i = 0; i < 11; i++){
                    //Monitor the is running flag to see if it should still run
                    if(control.isRunning == false){
                        control.reset();
                        break;
                    }
                    control.updateProgress(i * 10);
                    Thread.sleep(3000);
                }
                control.reset();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

    public static void main(String[] args) throws InterruptedException {
        // Create and set up the window.
        JFrame frame = new JFrame("LabelDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // Add content to the window.
        frame.add(new Controller().view);
        // Display the window.
        frame.pack();
        frame.setVisible(true);

    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM