2014-09-04 75 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