ProgressMonitor и SwingWorker не работают

У меня проблема с SwingWorker. Приложение отправляет файл между клиентом и сервером, но монитор прогресса не будет показывать мне прогресс во время передачи. Не могли бы вы сказать мне, что я делаю неправильно и что мне делать?

Основной класс одинаков для обоих приложений:

package main;

import java.awt.EventQueue;

public class Main {

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {

                Test2 test2=new Test2();

            }
        });

    }

}

Клиент:

package main;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class Test2 {

    public Test2() {

        hostName="localhost";

        try {
            clientSocket = new Socket(hostName, 1234);
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        File file=new File("E:/test/123.mp4");

        try {
            fileInputStream=new FileInputStream(file);
            bis=new BufferedInputStream(fileInputStream);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try {
            bos=new BufferedOutputStream(clientSocket.getOutputStream());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 

        bit=new byte[512];
        int len;

        System.out.println("Send..."); //test

        try {
            while ((len = bis.read(bit,0,511)) != -1) {
                bos.write(bit, 0, len);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }       

        try {
            bis.close();
            bos.close();
            fileInputStream.close();
            //fileOutputStream.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   

        System.out.println("Finish"); //test

    }

    private String hostName;
    private Socket clientSocket;

    private BufferedInputStream bis;
    private BufferedOutputStream bos;
    private FileInputStream fileInputStream;
    private byte bit[];
}

Сервер:

package main;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;

import javax.swing.ProgressMonitor;
import javax.swing.SwingWorker;

public class Test2 {

    public Test2() {

        pm=new ProgressMonitor(null, "Download...", null, 0, 1850297);
        pm.setMillisToDecideToPopup(1);

        test4=new Test4();
        test4.execute();                            

    }

    private class Test4 extends SwingWorker<Boolean, Void> {

        public Test4() {

            try {
                welcomeSocket = new ServerSocket(1234);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            System.out.println("Server works");

            try {
                connectionSocket = welcomeSocket.accept();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

        @Override
        protected Boolean doInBackground() throws Exception {

            try {

                bis=new BufferedInputStream(connectionSocket.getInputStream());

            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            try {
                fileOutputStream=new FileOutputStream("E:/test2/123.mp4");
                bos=new BufferedOutputStream(fileOutputStream);
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }                                           

            bit=new byte[512];
            int len;

            System.out.println("Download..."); //test

            try {
                while ((len = bis.read(bit,0,511)) != -1) {

                    bos.write(bit, 0, len);

                    publish();

                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            try {
                bis.close();
                bos.close();
                fileOutputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }           

        return true;

        }

        @Override
        protected void process(List<Void> chunks) {

            number++;
            pm.setProgress(number);

        }

        @Override
        protected void done() {
            System.out.println("DONE");
        }

    }

    private ServerSocket welcomeSocket; 
    private Socket connectionSocket;

    private FileOutputStream fileOutputStream;
    private BufferedInputStream bis;
    private BufferedOutputStream bos;
    private byte bit[];

    private ProgressMonitor pm;
    private Test4 test4;
    private int number;

}

Помимо SwingWorker, у меня есть проблема с кодом ниже. Это вторая версия приложения моего сервера без SwingWorker. Здесь, монитор прогресса показывает мне прогресс во время передачи, но не когда-либо. Я использовал invokeLater в методе run(), но иногда монитор прогресса не работает. Не могли бы вы сказать мне, что я делаю не так?

Сервер:

package main;

import java.awt.EventQueue;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;

import javax.swing.ProgressMonitor;
import javax.swing.SwingWorker;

public class Test2 {

    public Test2() {

        pm=new ProgressMonitor(null, "Download...", null, 0, 1850297);
        pm.setMillisToDecideToPopup(1);

        test3=new Test3();
        new Thread(test3).start();                          

    }

    private class Test3 implements Runnable {

        public Test3() {        

        }

        @Override
        public void run() {

            try {
                welcomeSocket = new ServerSocket(1234);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            System.out.println("Server works"); //test

            while(true){

                try {
                    connectionSocket = welcomeSocket.accept();

                    try {

                        bis=new BufferedInputStream(connectionSocket.getInputStream());

                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                    try {
                        fileOutputStream=new FileOutputStream("E:/test2/123.mp4");
                        bos=new BufferedOutputStream(fileOutputStream);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }                                   

                    bit=new byte[512];
                    int len;

                    System.out.println("Download..."); //test

                    try {
                        while ((len = bis.read(bit,0,511)) != -1) {

                            bos.write(bit, 0, len);

                            EventQueue.invokeLater(new Runnable() {

                                @Override
                                public void run() {
                                    number++;
                                    pm.setProgress(number);

                                }
                            });

                        }
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }                           

                    try {
                        bis.close();
                        bos.close();
                        fileOutputStream.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                    System.out.println("DONE"); //test

                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }

        }

    }

    private ServerSocket welcomeSocket; 
    private Socket connectionSocket;

    private FileOutputStream fileOutputStream;
    private BufferedInputStream bis;
    private BufferedOutputStream bos;
    private byte bit[];

    private ProgressMonitor pm;
    private Test3 test3;
    private int number;

}

1 ответ

Вы ожидаете подключения к сокету и принимаете его в конструкторе Test4, который будет вызываться в потоке событий Swing. Можно создать сокет там, но не ждите соединения там, так как это блокирует. Вместо этого дождитесь подключения его в методе doInBackground.

Также рассмотрите возможность изменения вашего SwingWorker, чтобы он передавал прочитанные байты:

// change generic parameter to Integer
private class Test4 extends SwingWorker<Boolean, Integer> {


    @Override
    protected Boolean doInBackground() throws Exception {

        // .....                                          

        bit=new byte[512];
        int len;

        try {
            while ((len = bis.read(bit,0,511)) != -1) {

                bos.write(bit, 0, len);

                publish(len);

            }

и в других местах:

    @Override
    protected void process(List<Integer> chunks) {
        // number++;
        for (Integer chunk : chunks) {
           pm.setProgress(chunk);
        }
    }
Другие вопросы по тегам