Java - Как обновить JProgressBar из Socket? - PullRequest
0 голосов
/ 15 декабря 2011

Я пытался решить следующую проблему в течение нескольких недель :(. В моем Java-апплете (MyApplet) у меня есть метод для кнопки, называемый btnSendToPC, который должен отправлять выбранное содержимое файла с сервера на локальный ПК через Открытое гнездо. Проблема возникает, когда я пытаюсь реализовать JProgressBar, который покажет пользователю, какая часть этого файла была загружена на локальный ПК. Я прочитал много примеров JProgressBar на этом сайте, но, честно говоря, до сих пор не могу понять это. очень признателен, если вы мне помогли. Ниже приведена очень короткая версия моего кода, включающая все основные части.

//My Network class that opens a socket and reads bytes from the socket
public class TcpIp {

    protected Socket s = null;
    public DataInputStream dis = null;

    public TcpIp(InetAddress ipa, int port) {

        try { 
            s = new Socket(ipa.getHostAddress(), port);
        } catch (IOException ex) {
            System.out.println("Error opening socket!");
            return;
        }

        try { //Create an input stream.
            dis = new DataInputStream(new BufferedInputStream(s.getInputStream()));
        } catch (Exception ex) {
            System.out.println("Error creating input stream!");
        }

    }

    public synchronized byte[] readBytes() throws IOException {

        ByteArrayOutputStream getBytes = new ByteArrayOutputStream();

        int oneByte;

        while ((oneByte = dis.read()) != 124) {//Reads 1 byte from the InputStream and breaks on | character
            getBytes.write(oneByte);
        }

        return (getBytes.toByteArray());

    }
}

//My main Applet class that has the method for Send to PC button
public class MyApplet extends javax.swing.JApplet implements Runnable {

    public TcpIp gtp = null;
    private static String inGet;

    @Override
    public void run() {

        int i;

        byte[] in = new byte[10000024];

        try {
            Thread.sleep(1000);
            //pause gtp.readBytes so that server has enough time to receive name of the file to read,
            //to read its contents and send its contents back through socket
        } catch (InterruptedException ex) {
        }

        if ((gtp != null)) {

            try {
                in = gtp.readBytes();
            } catch (IOException ex) {
            }

            //Remove non-printing bytes.
            for (i = 0; i < in.length; i++) {
                if (in[i] < 0x20) {
                    in[i] = 0x20;
                }
            }

            inGet = new String(in);
        }
    }

    public void btnSendToPC() {

        //In here are commands that send name of the file to read. 
        //Server reads that file and sends its contents back through socket.

        try {

            FileOutputStream fout = new FileOutputStream(fn);
            BufferedWriter myOutput = new BufferedWriter(new OutputStreamWriter(fout));

            timer = new Thread(this);
            timer.start();

            try {
                timer.join();
            } catch (InterruptedException ex) {
            }

            myOutput.write(inGet)

            myOutput.close();
            fout.close();
        }

    }
}

Ответы [ 3 ]

3 голосов
/ 16 декабря 2011

Просто используйте javax.swing.ProgressMonitorInputStream.Делает всю тяжелую работу за вас.

3 голосов
/ 15 декабря 2011

Ваш класс TcpIp должен работать в своем собственном потоке. Тогда вы звоните

SwingUtilities.invokeLater(new Runnable(){
  public void run(){
    progressBar.setValue(progressBar.getValue()+1);
  }
}

после getBytes.write(oneByte);

Но прежде чем сделать это, вам нужно установить максимум. Для этого вам нужно знать, сколько байтов вы хотите прочитать. Если вы не знаете, сколько байтов будет получено, индикатор выполнения не имеет смысла.

Я бы также предложил не вызывать обновление индикатора выполнения для каждого полученного байта.

1 голос
/ 15 декабря 2011

Вы можете изменить индикатор выполнения, используя oberver или eventlistener.

Попробуйте наблюдаемый наблюдателем, чтобы изменить индикатор выполнения от других классов.

...