2013-07-15 106 views
0

我正在寫一個小文件瀏覽器。我在下載文件時遇到了一個小問題。當我嘗試取消下載並從列表中刪除,我得到這個錯誤:JTable行刪除錯誤

Exception in thread "Timer-2" java.lang.ArrayIndexOutOfBoundsException: 2 >= 2 
    at java.util.Vector.elementAt(Unknown Source) 
    at javax.swing.table.DefaultTableModel.setValueAt(Unknown Source) 
    at pkg_main.CLS_Downloader$1.run(CLS_Downloader.java:151) 
    at java.util.TimerThread.mainLoop(Unknown Source) 
    at java.util.TimerThread.run(Unknown Source) 

而且這是我的代碼:

下載類:

public class CLS_Downloader extends Thread { 

    private final String sDOWNLOAD_FOLDER = "descargas/"; 

    private Socket tSock; 

    private ObjectInputStream tObjInStream; 
    private ObjectOutputStream tObjOutStream; 

    private JTable tTable; 
    private int iIndex; 

    private CLS_TransferTableModel tTransferModel; 

    private Boolean bDownloaded; 
    private Boolean bFailed; 

    private long iReadCount = 0; 
    private long iReadTotal = 0; 
    private long lTotalSize = 0; 
    private long lRemainSize = 0; 

    private String sFileName; 

    private JProgressBar tProgressBar; 

    public CLS_Downloader(Socket tSock, JTable tTable, int iIndex) { 
     this.tTable = tTable; 
     this.iIndex = iIndex; 
     this.tSock = tSock; 
     this.bDownloaded = false; 
     this.bFailed = false; 

     this.tTransferModel = (CLS_TransferTableModel) tTable.getModel(); 

     try { 
      this.tObjOutStream = new ObjectOutputStream(
        this.tSock.getOutputStream()); 
      this.tObjOutStream.flush(); 
      this.tObjInStream = new ObjectInputStream(
        this.tSock.getInputStream()); 

      this.start(); 
     } catch (IOException e) { 
      this.bFailed = true; 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

    public JTable getTable() { 
     return tTable; 
    } 

    public void setTable(JTable tTable) { 
     this.tTable = tTable; 
    } 

    public int getiIndex() { 
     return iIndex; 
    } 

    public void setiIndex(int iIndex) { 
     this.iIndex = iIndex; 
    } 

    public Socket getSock() { 
     return tSock; 
    } 

    public void setSock(Socket tSock) { 
     this.tSock = tSock; 
    } 

    public String getFileName() { 
     return sFileName; 
    } 

    public void setFileName(String sFileName) { 
     this.sFileName = sFileName; 
    } 

    public long getTotalSize() { 
     return lTotalSize; 
    } 

    public void setTotalSize(long lTotalSize) { 
     this.lTotalSize = lTotalSize; 
    } 

    public Boolean isDownloaded() { 
     return bDownloaded; 
    } 

    public void setDownloaded(Boolean bDownloaded) { 
     this.bDownloaded = bDownloaded; 
    } 

    public Boolean isFailed() { 
     return bFailed; 
    } 

    public void setFailed(Boolean bFailed) { 
     this.bFailed = bFailed; 
    } 

    private void setTableValues() { 
     this.tTransferModel.setValueAt(this.tSock.getInetAddress() 
       .getHostAddress(), iIndex, 0); 
     this.tTransferModel.setValueAt(this.sFileName, iIndex, 1); 
     this.tTransferModel.setValueAt("Descargando", iIndex, 2); 

     this.tProgressBar = (JProgressBar) tTable.getModel().getValueAt(
       this.iIndex, 3); 
     this.tProgressBar.setStringPainted(true); 

     this.tTransferModel.setValueAt(
       CLS_Functions.convertSize(this.lRemainSize), iIndex, 6); 
    } 

private void downloadComplete() { 
     this.tProgressBar.setValue(100); 
     this.tTable.repaint(); 
     this.tTransferModel.setValueAt("Completado", iIndex, 2); 
     this.tTransferModel.setValueAt(CLS_Functions.convertSize(iReadTotal), 
       iIndex, 4); 
     this.tTransferModel.setValueAt(CLS_Functions.convertSize(lRemainSize), 
       iIndex, 5); 

     this.bDownloaded = true; 
    } 

    TimerTask tUpdateTable = new TimerTask() { 
     public void run() { 
      tProgressBar.setValue((int) ((iReadTotal * 100)/lTotalSize)); 
      tTable.repaint(); 
      tTransferModel.setValueAt(CLS_Functions.convertSize(iReadTotal), 
        iIndex, 4); //ERROR LINE 
      tTransferModel.setValueAt(CLS_Functions.convertSize(lRemainSize), 
        iIndex, 5); 
     } 
    }; 

    public void run() { 
     String sData = null; 
     FileOutputStream tFileInStream = null; 

     byte[] bArrRet = new byte[2048]; 

     try { 
      sData = this.tObjInStream.readUTF(); 

      this.sFileName = new File(sData.split("#")[0]).getName(); 
      this.lTotalSize = Long.parseLong(sData.split("#")[1]); 
      this.lRemainSize = this.lTotalSize; 

      this.setTableValues(); 
      new Timer().scheduleAtFixedRate(tUpdateTable, 0, 1000); 

      tFileInStream = new FileOutputStream(sDOWNLOAD_FOLDER + this.sFileName); 

      while (this.lRemainSize > 0) { 
       this.iReadCount = tObjInStream.read(bArrRet); 
       tFileInStream.write(bArrRet, 0, (int) this.iReadCount); 
       tFileInStream.flush(); 
       this.lRemainSize -= this.iReadCount; 
       this.iReadTotal += this.iReadCount; 

       Thread.sleep(5); 
      } 

      this.tUpdateTable.cancel(); 
      this.downloadComplete(); 
      tFileInStream.close(); 
      this.close(); 

      System.out.println("listo"); 

     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      try { 
       tFileInStream.close(); 
      } catch (IOException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } 

      this.close(); 
      this.bFailed = true; 
      this.tTransferModel.setValueAt("Fallado", iIndex, 2); 
      this.tUpdateTable.cancel(); 
     } 
    } 

    public void close() { 
     try { 
      this.tUpdateTable.cancel(); 
      this.tObjOutStream.close(); 
      this.tObjInStream.close(); 
      this.tSock.close(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

下載管理器類:

public class CLS_DownloadManager { 

    private static CLS_DownloadManager tDownloadManager; 
    private ArrayList<CLS_Downloader> tDownloadList = new ArrayList<CLS_Downloader>(); 

    public static CLS_DownloadManager getInstance() { 
     if (tDownloadManager == null) 
      tDownloadManager = new CLS_DownloadManager(); 

     return tDownloadManager; 
    } 

    public ArrayList<CLS_Downloader> getDownloadList() { 
     return tDownloadList; 
    } 

    public void setDownloadList(ArrayList<CLS_Downloader> tDownloadList) { 
     this.tDownloadList = tDownloadList; 
    } 

    public void addDownload(CLS_Downloader tDownload) { 
     this.tDownloadList.add(tDownload); 
    } 

    public CLS_Downloader getDownload(int iIndex) { 
     return this.tDownloadList.get(iIndex); 
    } 

    public void deleteDownload(int iIndex) { 
     this.tDownloadList.remove(iIndex); 
    } 

    public void deleteDownload(CLS_Downloader tDownload) { 
     this.tDownloadList.remove(tDownload); 
    } 

    public void cancelDownload(int iIndex) { 
     this.tDownloadList.get(iIndex).close(); 
    } 

    public void cleanDownloads() { 
     for (int i = this.tDownloadList.size() - 1; i >= 0; i--) 
      if (this.tDownloadList.get(i).isDownloaded() 
        || this.tDownloadList.get(i).isFailed()) 
       this.tDownloadList.remove(i); 
    } 

    public int getListCount() { 
     return this.tDownloadList.size(); 
    } 
} 

下載取消功能:

if (TBL_Downloads.getSelectedRow() > -1) { 
    CLS_DownloadManager.getInstance().cancelDownload(TBL_Downloads.getSelectedRow()); 
} 

在此先感謝!

+0

您是否聽說過Event Dispatch Thread, – mKorbel

+0

是的。你想說這個問題在那?感謝您的迴應。 –

+0

java7中沒有人知道幾乎是最上面的,那麼Swing GUI的代碼還有另一個問題,爲了更快地發佈[SSCCE](http://sscce.org/),更好的幫助,簡短,可運行,可編譯,只是爲了避免任何猜測 – mKorbel

回答

2

您的設計將業務對象(CLS_Downloader)與視圖(JTable及其表模型)混合在一起。

我在這裏看到的問題是,你的CLS_Downloader有一個表模型的引用,更重要的是它的索引。最重要的是,您還可以在CLS_DownloadManager中的列表中跟蹤您的下載情況。

更新數據(通過取消下載)使保持所有內容同步(表模型,CLS_DownloadManager,所有CLS_Downloader中的索引)變得非常複雜。

查找model view controller體系結構以更好地組織代碼。在這種情況下,模型應該是CLS_Downloader,視圖應該是JTable,控制器應該是CLS_DownloadManager

+0

謝謝,我會盡力重新實現它 –