2014-09-04 21 views
1

我正在研究Swing的應用程序和哪些我正在獲取數據和我正在使用擺動Jtable渲染渲染圖像中,但是當數據更是它所有時間掛起我能做些什麼來阻止呢?JTable圖像渲染是花費太多的負載在應用程序

示例渲染,我正在使用。

public class DefaultTableCellRenderer extends javax.swing.table.DefaultTableCellRenderer { 

    JLabel jLabel; 

    public DefaultTableCellRenderer() { 
     jLabel = new JLabel(); 

    } 

    public Component getTableCellRendererComponent(
      JTable table, Object value, boolean selected, boolean focus, int row, int col) { 

     try { 
      if (row == 1) { 
       jLabel.setIcon(new ImageIcon(ImageIO.read(getClass().getResource("blank.png")))); 
       jLabel.setText("Image Data"); 
       jLabel.setBackground(Color.LIGHT_GRAY); 
      } else { 
       jLabel.setIcon(new ImageIcon(ImageIO.read(getClass().getResource("blank.png")))); 
       jLabel.setText("Final"); 
      } 

      //jLabel.setIcon(new ImageIcon(ImageIO.read(new File("blank")))); 

      return jLabel; 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return jLabel; 
    } 

    @Override 
    public boolean mouseEnter(Event evt, int x, int y) { 
     System.out.println(jLabel.getText()); 
     return true; 
    } 
} 
+3

考慮提供一個[可運行示例]( https://stackoverflow.com/help/mcve)這表明你的問題。這將導致更少的混淆和更好的響應 – MadProgrammer 2014-09-04 07:08:41

+0

@MadProgrammer是它的工作文件,但承受如此多的負載,我的意思是它需要太多的CPU。而數據更多。 – 2014-09-04 07:10:13

+0

請勿從渲染器中加載圖像。將它們放入可以單獨查看的某種類型的緩存中。 – MadProgrammer 2014-09-04 08:07:35

回答

2

你一些建議:

  1. 您可以在應用程序的使用多線程開始加載圖像。使用類Executors來做到這一點。重要的是:您必須在顯示用戶界面之前加載所有圖像。
  2. 另一種可能性是異步加載圖像。使用SwingWorker加載圖像。加載必須在方法doInBackground()中執行。當加載一些圖像時,您可以使用方法publish()/process()用新圖像更新您的表格模型。
  3. 您可以將兩者組合並使用Executors中的doInBackground()方法。

我想,你的問題不是CPU負載。你的問題是IO。從硬盤讀取數據非常緩慢,應儘可能在後臺執行。

+0

okey所以我需要添加這個Swingworker線程到渲染,我使用的不是嗎? – 2014-09-04 07:34:18

+0

@KishanBhimajiyani如果你想在你的渲染器中提供它,你還需要一個圖片緩存。 Renderer過於頻繁地被調用來每次加載圖像。將圖像保存在您的表格模型中。 – 2014-09-04 07:37:14

+0

okey然後它更好地調用它的設置到應用程序中是不是它? :) – 2014-09-04 07:39:07

3

這...

jLabel.setIcon(new ImageIcon(ImageIO.read(getClass().getResource("blank.png")))); 

是一項昂貴的電話,每次它被稱爲一個新的ImageIcon類創建時間是繞BufferedImage數據包被讀取。與ImageIcon不同,ImageIO不會緩衝圖像並重新使用它們,而是會讀取新的資源。

這意味着,每次渲染單元格時,圖像都會被完全重新加載。

因爲,你的加載相同的圖像,每次,簡單的負載,當你構建類和利用它在需要的時候,例如圖像...

public class DefaultTableCellRenderer extends javax.swing.table.DefaultTableCellRenderer { 

    private Icon icon; 

    public DefaultTableCellRenderer() throws IOException { 
     icon = new ImageIcon(ImageIO.read(getClass().getResource("blank.png"); 
    } 

    public Component getTableCellRendererComponent(
      JTable table, Object value, boolean selected, boolean focus, int row, int col) { 
     super.getTableCellRendererComponent(table, value, selected, focus, row, col); 
     setIcon(icon); 
     if (row == 1) { 
      setText("Image Data"); 
      setBackground(Color.LIGHT_GRAY); // You may need to set the opaque state for this to work... 
     } else { 
      setText("Final"); 
     } 
     return this; 
    } 
} 
+0

啊,這是做這件事的好方法。我通常使用SwingWorker,但通常用於在GUI實例化之前加載一組圖像。 – Gorbles 2014-09-04 08:16:43

+1

@Gorb這一切都取決於,因爲OP是隻加載一個圖像,這會更容易,以爲可能需要圖像緩存,但它變得更簡單,然後我認爲 – MadProgrammer 2014-09-04 08:17:52

+0

但如果我需要上傳所有時間其他圖像? – 2014-09-04 08:39:07