how to include a progress bar in a program of file transfer using sockets in java

你。 提交于 2019-11-28 14:49:44

Swing is a single threaded framework. That means that all interactions with the UI are expected to be made within the context of this thread (AKA The Event Dispatching Thread).

This also means that if you performing any kind of time consuming/long running or blocking process within the EDT, you will prevent it from responding to events or updating the UI.

This is what your code is currently doing.

There are a number of mechanism available to you to over come this, in your case, the simplest is probably to use a SwingWorker

import java.awt.EventQueue;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ProgressBar extends JFrame {

    JProgressBar current = new JProgressBar(0, 100);
    int num = 0;

    public ProgressBar() {
        //exit button
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //create the panel to add the details
        JPanel pane = new JPanel();
        current.setValue(0);
        current.setStringPainted(true);
        pane.add(current);
        setContentPane(pane);
    }

    //to iterate so that it looks like progress bar  
    public void iterate() {
        SwingWorker worker = new SwingWorker<Object, Object>() {
            @Override
            protected Object doInBackground() throws Exception {
                while (num < 2000) {
//                    current.setValue(num);
                    try {
                        Thread.sleep(125);
                    } catch (InterruptedException e) {
                    }
                    num += 95;
                    int p = Math.round(((float)Math.min(num, 2000) / 2000f) * 100f);
                    setProgress(p);
                }
                return null;
            }
        };
        worker.addPropertyChangeListener(new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                String name = evt.getPropertyName();
                if ("progress".equals(name)) {
                    SwingWorker worker = (SwingWorker) evt.getSource();
                    current.setValue(worker.getProgress());
                }
            }
        });
        worker.execute();
    }

    //for testing the app
    public static void main(String[] arguments) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                ProgressBar frame = new ProgressBar();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                frame.iterate();
            }
        });
    }
}

Check out http://docs.oracle.com/javase/tutorial/uiswing/concurrency/ for more details.

Updated with example of dual welding progress bars

If you need to display more then one progress bat, you can simply use the publish and process methods of SwingWorker to accomplish more complex results...

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

 */
public class ProgressBar extends JFrame {

    JProgressBar current = new JProgressBar(0, 100);
    JProgressBar overall = new JProgressBar(0, 100);
    int num = 0;

    public ProgressBar() {
        //exit button
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //create the panel to add the details
        JPanel pane = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        current.setValue(0);
        current.setStringPainted(true);
        overall.setStringPainted(true);
        pane.add(overall, gbc);
        pane.add(current, gbc);
        setContentPane(pane);
    }

    //to iterate so that it looks like progress bar  
    public void iterate() {
        SwingWorker worker = new SwingWorker<Object, float[]>() {

            @Override
            protected void process(List<float[]> chunks) {
                float[] progress = chunks.get(chunks.size() - 1); // only want the last one
                overall.setValue(Math.round(progress[0] * 100f));
                current.setValue(Math.round(progress[1] * 100f));
            }

            @Override
            protected Object doInBackground() throws Exception {
                int size = 2000;
                int overallSize = size * 10;
                int overallProgress = 0;
                for (int index = 0; index < 10; index++) {
                    for (int count = 0; count < size; count++) {
                        publish(new float[]{
                            getProgress(overallProgress, overallSize),
                            getProgress(count, size),
                        });
                        overallProgress++;
                        Thread.sleep(2);
                    }
                }
                return null;
            }

            public float getProgress(int value, int max) {

                return (float)value / (float)max;

            }
        };
        worker.execute();
    }

    //for testing the app
    public static void main(String[] arguments) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                ProgressBar frame = new ProgressBar();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                frame.iterate();
            }
        });
    }
}

Check out the ProgressMonitorInputStream from the Swing tutorial on Using Progress Bars.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!