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

前端 未结 2 978
鱼传尺愫
鱼传尺愫 2020-12-12 06:20

i am working on a project in java that transfers files from a client to a server. now i need to show the progress bar for each file transfer i.e the progress bar should auto

相关标签:
2条回答
  • 2020-12-12 06:42

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

    0 讨论(0)
  • 2020-12-12 07:02

    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...

    enter image description here

    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();
                }
            });
        }
    }
    
    0 讨论(0)
提交回复
热议问题