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);
}
}