Jtable中的Java Jprogressbar无法正常工作

时间:2014-09-22 05:44:39

标签: java swing jtable jprogressbar tablecellrenderer

我的Jprogressbar工作很奇怪,我把jprogress放在Jtable列中,现在我面临的问题是,如果我们不接触进度条,它可以正常工作,但是如果我们点击任何一行,所有3个进度条都会改变当前正在运行的进度条的状态。

I am calling the following code
clsDownload(URLtoDownload,i,"file" + i ,JTable);

In clsDownload class, i am downloading file and also updating the progressbar, using 
 jTbl1.getModel().setValueAt(((int) dPercent)+"%", Loc, 1);

现在从这段代码中,如果我们点击任何Jtable行,它也会更新其他进度条。

以下是有问题的完整代码

public class ProgressCellRenderer extends JProgressBar
                        implements TableCellRenderer {

  /**
   * Creates a JProgressBar with the range 0,100.
   */
  public ProgressCellRenderer(){
    super(0, 100);
    setValue(0);
    setString("0%");
    setStringPainted(true);
  }

  public Component getTableCellRendererComponent(
                                    JTable table,
                                    Object value,
                                    boolean isSelected,
                                    boolean hasFocus,
                                    int row,
                                    int column) {

    //value is a percentage e.g. 95%
    final String sValue = value.toString();
    int index = sValue.indexOf('%');
    if (index != -1) {
      int p = 0;
      try{
        p = Integer.parseInt(sValue.substring(0, index));
      }
      catch(NumberFormatException e){
      }

      setValue(p);
      setString(sValue);
    }
    return this;
  }
}





public class clsDownload  implements Callable<String> {

    private String fileURL;
    private String localFileName;
    private JTable jTbl1;
    private int Loc;
    clsDownload(String UrlName, int Jobpos, String lFileName, JTable tbl1)
    {
        try
        {

           fileURL = UrlName;
          localFileName = lFileName;
          jTbl1 = tbl1;  
          Loc= Jobpos;
        }
        catch (Exception e)
        {

        }
    }

    @Override
   public String call() throws MalformedURLException, IOException 
    {
        try
        {               

                         OutputStream out = null;
                        URLConnection conn = null;
                        InputStream in = null;
                        URL url = new URL(fileURL);
                        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                        connection.connect();
                         BufferedOutputStream bout;
                        FileOutputStream fos;
                        Map<String,List<String>> hf  = connection.getHeaderFields();
                        long ReceivedFlength =0;
                         double dPercent = 0;
                        //Check receiving file length
                        String searchKey = "Content-Length";
                        long downloaded =0;  //initilze to 0 so that it dont take old value from above

                            in = new BufferedInputStream(connection.getInputStream());
                            fos=(downloaded==0)? new FileOutputStream(localFileName): new FileOutputStream(localFileName,true);
                            bout = new BufferedOutputStream(fos, 1024);
                            byte[] data = new byte[1024];
                            int x = 0;
                             if(hf.containsKey(searchKey))
                        ReceivedFlength = Long.parseLong(hf.get(searchKey).get(0));
                            //  progressBar = (JProgressBar)jTbl1.getComponent(8);
                            while ((x = in.read(data, 0, 1024)) >= 0 ) 
                            {
                               bout.write(data, 0, x);
                                downloaded += x;
                                //Display file download progress 
                                 dPercent =  (downloaded*100)/ReceivedFlength;
                                  if(dPercent > 1)
                                  {

                                   jTbl1.getModel().setValueAt(((int) dPercent)+"%", Loc, 1);
                                  }
                            }
        return "Completed";
        }
        catch(Exception e)
        {
        return "error";    
        }

     }
}



private void btnLoadActionPerformed(java.awt.event.ActionEvent evt) {                                        

        tblFilestoDownload.setModel(new DownloadTable());
         DownloadTable tblSelectedItem = (DownloadTable) tblFilestoDownload.getModel();
         final TableColumn myCol = tblFilestoDownload.getColumnModel().getColumn(1);

             myCol.setCellRenderer(new ProgressCellRenderer());
        tblSelectedItem.insertData(new Object[]{"http://releases.ubuntu.com/14.04.1/ubuntu-14.04.1-server-amd64.iso",new JProgressBar(0,100)});
        tblSelectedItem.insertData(new Object[]{"http://ports.ubuntu.com/ubuntu-ports/dists/precise-updates/main/installer-armhf/current/images/armadaxp/netboot/uImage",new JProgressBar(0,100)});
        tblSelectedItem.insertData(new Object[]{"http://releases.ubuntu.com/14.04.1/ubuntu-14.04.1-server-amd64.iso",new JProgressBar(0,100)});
        tblSelectedItem.insertData(new Object[]{"http://releases.ubuntu.com/14.04.1/ubuntu-14.04.1-server-amd64.iso",new JProgressBar(0,100)});


    }                                       

    private void btnStartActionPerformed(java.awt.event.ActionEvent evt) {                                         
       DoItWorker worker = new DoItWorker();
        worker.execute();
    }                                        


    class DoItWorker extends SwingWorker<Void, String> 
{
   public static final String INTERMEDIATE_RESULT = "intermediate result";
   private static final long TIME_OUT = 5;
   private  final TimeUnit UNIT = TimeUnit.MINUTES;

   private String intermediateResult;
   private ExecutorService executor;
   private CompletionService<String> completionService;

   public DoItWorker() {
      executor = Executors.newFixedThreadPool(1);
      completionService = new ExecutorCompletionService<>(executor);
   }

   @Override
   protected Void doInBackground() throws Exception {
      for (int i = 0; i < tblFilestoDownload.getModel().getRowCount()-1; i++) {


         Callable<String> callable = new clsDownload(tblFilestoDownload.getValueAt(0, i).toString(),i,"file" + i ,tblFilestoDownload);
         completionService.submit(callable);
      }
      executor.shutdown();
      for (int i = 0; i < tblFilestoDownload.getModel().getRowCount() -1 ; i++) {
         String result = completionService.take().get();
         publish(result);
         int progress = (100 * i) / tblFilestoDownload.getModel().getRowCount();
         setProgress(progress);
      }
      executor.awaitTermination(TIME_OUT, UNIT);
      setProgress(100);
      return null;
   }

你能帮助我,我做错了什么,为什么当我们点击jtable的任何一行时所有进度条都会更新。

由于

1 个答案:

答案 0 :(得分:1)

问题是TableCellRenderer旨在将其(单个)组件getTableCellRendererComponent重用为尽可能多的单元,作为资源优化。

因此组件不应该是有状态的,至少在getTableCellRendererComponent中设置其完整状态。 (因此提供了所有状态:isSelected,hasFocus。)

@Override
public Component getTableCellRendererComponent(JTable table, Object value,
                     boolean isSelected, boolean hasFocus, int row, int column) {
    // value is a percentage e.g. 95%
    final String sValue = value.toString();
    int p = 0;
    int index = sValue.indexOf('%');
    if (index != -1) {
        try {
            p = Integer.parseInt(sValue.substring(0, index));
        }
        catch(NumberFormatException e) {
        }
    }
    // Always set full state:
    setValue(p);
    setString(sValue);
    return this;
}