Java JTable Image render在应用程序中占用了太多的负载

Java JTable Image render在应用程序中占用了太多的负载,java,swing,jtable,image-rendering,Java,Swing,Jtable,Image Rendering,我正在研究Swing的Java应用程序,我正在获取数据,并在其中使用Swing Jtable Render for Render Image,但当数据更多时,它会一直挂起,那么我该怎么做才能防止这种情况 我正在使用的示例渲染 public class DefaultTableCellRenderer extends javax.swing.table.DefaultTableCellRenderer { JLabel jLabel; public DefaultTableCe

我正在研究Swing的Java应用程序,我正在获取数据,并在其中使用Swing Jtable Render for Render Image,但当数据更多时,它会一直挂起,那么我该怎么做才能防止这种情况

我正在使用的示例渲染

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;
    }
}

给你的一些建议:

  • 您可以在应用程序启动时使用多线程加载图像。使用类来完成它。重要的是:在显示UI之前,必须加载所有图像
  • 另一种可能是异步加载图像。用于加载图像。加载必须在方法
    doInBackground()
    中实现。加载某些图像后,可以使用方法
    publish()
    /
    process()
    使用新图像更新表格模型
  • 您可以将两者结合使用,并在
    doInBackground()
    方法中使用
    Executors

  • 我认为,你的问题不是CPU负载。你的问题是木卫一。从硬盘读取的速度非常慢,如果可能,应该在后台执行。

    给您一些建议:

  • 您可以在应用程序启动时使用多线程加载图像。使用类来完成它。重要的是:在显示UI之前,必须加载所有图像
  • 另一种可能是异步加载图像。用于加载图像。加载必须在方法
    doInBackground()
    中实现。加载某些图像后,可以使用方法
    publish()
    /
    process()
    使用新图像更新表格模型
  • 您可以将两者结合使用,并在
    doInBackground()
    方法中使用
    Executors
  • 我认为,你的问题不是CPU负载。你的问题是木卫一。从硬盘读取的速度非常慢,如果可能,应该在后台执行。

    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;
        }
    }
    
    这个

    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;
        }
    }
    

    考虑提供一个说明你的问题的方法。这将减少混乱,提高效率responses@MadProgrammer是的,它的工作文件,但采取这么多的负荷,我的意思是它需要太多的cpu。虽然数据更重要,但不要从渲染器中加载图像。将它们放在某种可以单独查找的缓存中。所有单元格是否总是有相同的图像?那么,程序员在他的回答中提出的(简单的)解决方案就足够了。否则(如果每个行都有不同的图像),则需要更复杂的加载机制。这将减少混乱,提高效率responses@MadProgrammer是的,它的工作文件,但采取这么多的负荷,我的意思是它需要太多的cpu。虽然数据更重要,但不要从渲染器中加载图像。将它们放在某种可以单独查找的缓存中。所有单元格是否总是有相同的图像?那么,程序员在他的回答中提出的(简单的)解决方案就足够了。否则(如果每行有不同的图像),您将需要一些更复杂的加载机制。一直以来,新图像都不相同。好的,所以我需要将此Swingworker线程添加到我正在使用的渲染中,不是吗?@KishanBhimajiyani如果您想在渲染器中提供它,您还需要一个图像缓存。渲染器调用太频繁,无法每次加载图像。将图像保存在表模型中。好的,那么最好在应用程序中调用其设置的位置,不是吗?:)只需实现您自己的表模型,它扩展了AbstracTableModel并可以异步加载图像。创建包含文件和加载图像的对象。Image在开始时为null,并且必须在第一次为特定单元格调用TableModel的getValueAt()方法时加载。渲染器使用图像在表格单元格中显示它。加载映像后,不要忘记在Swing thread(EDT)中调用fireTableDataChanged()。因此,在加载映像后,我需要使用它,然后等待,我正在上载一些示例类型的内容。:)好的,那么我需要将这个Swingworker线程添加到我正在使用的渲染器中,不是吗?@KishanBhimajiyani如果你想在渲染器中提供它,你还需要一个图像缓存。渲染器调用太频繁,无法每次加载图像。将图像保存在表模型中。好的,那么最好在应用程序中调用其设置的位置,不是吗?:)只需实现您自己的表模型,它扩展了AbstracTableModel并可以异步加载图像。创建包含文件和加载图像的对象。Image在开始时为null,并且必须在第一次为特定单元格调用TableModel的getValueAt()方法时加载。渲染器使用图像在表格单元格中显示它。加载映像后,不要忘记在Swing线程(EDT)中调用fireTableDataChanged()。因此,在加载映像后,我需要使用