java进度条显示下载进度,我在每写一次数据时都setValue(setValue);但进度条到下载完后一次完成显示,而不是每次显示进度,请高手帮我看一下问题出在哪里?
代码如下:
FileLoad.java:
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;
public class FileLoad extends JFrame implements ActionListener
{
 JPanel norJp=new JPanel();
 JPanel souJp=new JPanel();
  
     JLabel addLabel=new JLabel("下载地址:");
     JTextField jtf=new JTextField(20);
     JButton jb=new JButton("下载");
     
     JProgressBar jpb=new JProgressBar(0,0,500);
     
     
 
    public static void main(String[] args) 
    {
         new FileLoad();
         
    }
    public FileLoad()
    {
     this.setTitle("FileLoad");
     this.setSize(500,200);
     Container con=super.getContentPane();
     BorderLayout border=new BorderLayout();
        con.setLayout(border);
        jb.addActionListener(this);
        
        norJp.setLayout(new FlowLayout());
        norJp.add(addLabel);
        norJp.add(jtf);
        norJp.add(jb);
        
        souJp.setLayout(new FlowLayout());
        jpb.setValue(50);
        souJp.add(jpb);
        
        
        con.add(norJp,BorderLayout.NORTH);
        con.add(souJp,BorderLayout.CENTER);
        
          
       
      
        
     this.show();
    }
    
    public void actionPerformed(ActionEvent e)
    {
      //System.out.println("++++++++");
      int i=0;
      int value=10;
      if(e.getSource()==jb)
      {
        //String jtfStr=jtf.getText();
          new URLFileLoad(jpb,this,souJp,jtf);
  //System.out.println("jtfStr");
   }

  }
    
}URLFileLoad.java:
import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
public class URLFileLoad   
{
    JProgressBar jpb;
     
     public URLFileLoad(JProgressBar jpb,JFrame frame,JPanel jpl,JTextField jtf) 
     {
      try
      {
                this.jpb=jpb;
     FileOutputStream  out=new FileOutputStream("e:\\UUCall3.exe");
          String urlStr=jtf.getText();
          System.out.println("urlStr="+urlStr);
          //URL url=new URL("http://127.0.0.1:8585/manager/UUCall3.exe");
          URL url=new URL(urlStr);
          
          URLConnection urlCon=url.openConnection();
         
          Map m=urlCon.getHeaderFields();
          Set set=m.entrySet();
          Iterator it=set.iterator();
          while(it.hasNext())
          {
            Map.Entry me=(Map.Entry)it.next();
            System.out.println(me.getKey()+": "+me.getValue());
          } 
          String fileStr=(String)m.get("Content-Length").toString();
           fileStr=fileStr.replace('[',' ');
           fileStr=fileStr.replace(']',' ');
           fileStr=fileStr.trim();
          System.out.println(fileStr);
          int fileLen=Integer.valueOf(fileStr);
     
          //System.out.println("k="+k);
          InputStream in=urlCon.getInputStream();
          BufferedInputStream buffIn=new BufferedInputStream(in);
         
          byte[] buf=new byte[1024*10];
          int size=0;
          int fileNum=0;
          int setValue=0;
          
          while((size=buffIn.read(buf))!=-1)
          {    //System.out.println("fileNum"+fileNum);
                 out.write(buf,0,size);
                
              if(fileNum>1024)
              {
                 System.out.println("已经下载了"+fileNum/1024+"k");
              }
              fileNum+=size;
              setValue+=5;
               jpb.setValue(setValue);
              frame.setVisible(true);
              Thread.sleep(500);
          }
          
   }
 catch(Exception e)
 {
    System.out.println(e);
 }   
      
     }}

解决方案 »

  1.   

    一般来说,可能的原因是你没有使用多线程。一下是一个示例程序:JRE 1.6环境下通过编译。
    //package components;import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.beans.*;
    import java.util.Random;public class ProgressBarDemo extends JPanel
                                 implements ActionListener,
                                            PropertyChangeListener {    private JProgressBar progressBar;
        private JButton startButton;
        private JTextArea taskOutput;
        private Task task;    class Task extends SwingWorker<Void, Void> {
            /*
             * Main task. Executed in background thread.
             */
            @Override
            public Void doInBackground() {
                Random random = new Random();
                int progress = 0;
                //Initialize progress property.
                setProgress(0);
                while (progress < 100) {
                    //Sleep for up to one second.
                    try {
                        Thread.sleep(random.nextInt(1000));
                    } catch (InterruptedException ignore) {}
                    //Make random progress.
                    progress += random.nextInt(10);
                    setProgress(Math.min(progress, 100));
                }
                return null;
            }        /*
             * Executed in event dispatching thread
             */
            @Override
            public void done() {
                Toolkit.getDefaultToolkit().beep();
                startButton.setEnabled(true);
                setCursor(null); //turn off the wait cursor
                taskOutput.append("Done!\n");
            }
        }    public ProgressBarDemo() {
            super(new BorderLayout());        //Create the demo's UI.
            startButton = new JButton("Start");
            startButton.setActionCommand("start");
            startButton.addActionListener(this);        progressBar = new JProgressBar(0, 100);
            progressBar.setValue(0);
            progressBar.setStringPainted(true);        taskOutput = new JTextArea(5, 20);
            taskOutput.setMargin(new Insets(5,5,5,5));
            taskOutput.setEditable(false);        JPanel panel = new JPanel();
            panel.add(startButton);
            panel.add(progressBar);        add(panel, BorderLayout.PAGE_START);
            add(new JScrollPane(taskOutput), BorderLayout.CENTER);
            setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));    }    /**
         * Invoked when the user presses the start button.
         */
        public void actionPerformed(ActionEvent evt) {
            startButton.setEnabled(false);
            setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            //Instances of javax.swing.SwingWorker are not reusuable, so
            //we create new instances as needed.
            task = new Task();
            task.addPropertyChangeListener(this);
            task.execute();
        }    /**
         * Invoked when task's progress property changes.
         */
        public void propertyChange(PropertyChangeEvent evt) {
            if ("progress" == evt.getPropertyName()) {
                int progress = (Integer) evt.getNewValue();
                progressBar.setValue(progress);
                taskOutput.append(String.format(
                        "Completed %d%% of task.\n", task.getProgress()));
            }
        }
        /**
         * Create the GUI and show it. As with all GUI code, this must run
         * on the event-dispatching thread.
         */
        private static void createAndShowGUI() {
            //Create and set up the window.
            JFrame frame = new JFrame("ProgressBarDemo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        //Create and set up the content pane.
            JComponent newContentPane = new ProgressBarDemo();
            newContentPane.setOpaque(true); //content panes must be opaque
            frame.setContentPane(newContentPane);        //Display the window.
            frame.pack();
            frame.setVisible(true);
        }    public static void main(String[] args) {
            //Schedule a job for the event-dispatching thread:
            //creating and showing this application's GUI.
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGUI();
                }
            });
        }
    }
      

  2.   

    因为事件处理线程 和UI更新线程都在同一个线程里面,叫Event Dispatch Thread(EDT),
    所以,当你在处理事件的时候,是很会影响效率的
    还有,你的组件应该一开始就让它显示出来,然后再起个线程 去读取文件,然后边读文件边更新进度条