Rendering BufferedImage in JTable cell

前端 未结 2 550
半阙折子戏
半阙折子戏 2020-12-07 06:57

I need to display a BufferedImage in one JTable column. I overwrote JTable method

@Override
public Class getColumnClass(int column) {
    if (colum         


        
2条回答
  •  春和景丽
    2020-12-07 06:58

    There is no default TableCellRenderer for BufferedImage, you're going to have to supply one

    Create yourself a new class that extends from DefaultTableCellRenderer. Override the getTableCellRendererComponent method

    In this method, check the value been passed in is a BufferedImage, if it is, create a instance of ImageIcon, passing the BufferedImage into it.

    Use the cell renderes setIcon method, passing the new instance of ImageIcon to it

    With your table instance, use the setDefaultRenderer method to associate the cell renderer with the BufferedImage class

    table.setDefaultRenderer(BufferedImage.class, myInstanceOfBufferedImageCellRenderer)
    

    Check out Using Custom Renderers for more info

    Added example

    So a threw a quick example together using both ideas from myself and Hovercraft.

    enter image description here

    My personally feeling is that Hovercraft's idea will use less resources and be quicker then using a cell renenderer, so long as you create a ImageIcon once for each BufferedImage and maintain that reference.

    You could get the custom cell renderer to do the same, but you would need to dabble with WeakHashMaps to maintain a reference between the BufferedImage and Icon and there is still the risk that the BufferedImage in question will never be collected, leaving the Icon reference hanging around.

    If you weren't doing anything special with the BufferedImage in the way of rendering, I would use Hovercraft's suggest, purly from a ease of use and resource management perspective.

    public class BufferedImageTableCellRenderer {
    
        public static void main(String[] args) {
            new BufferedImageTableCellRenderer();
        }
    
        public BufferedImageTableCellRenderer() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    File[] files = new File("some folder some where").listFiles(new FileFilter() {
                        @Override
                        public boolean accept(File pathname) {
                            String name = pathname.getName().toLowerCase();
                            return name.endsWith(".gif") || name.endsWith(".jpg") || name.endsWith(".png");
                        }
                    });
    
                    ImageTableModel model = new ImageTableModel();
                    for (File file : files) {
                        try {
                            model.add(ImageIO.read(file));
                        } catch (IOException ex) {
                            ex.printStackTrace();
                        }
                    }
    
                    JTable table = new JTable(model);
                    table.setRowHeight(100);
                    table.setDefaultRenderer(BufferedImage.class, new BufferedImageCellRenderer());
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new JScrollPane(table));
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class BufferedImageCellRenderer extends DefaultTableCellRenderer {
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                if (value instanceof BufferedImage) {
                    setIcon(new ImageIcon((BufferedImage)value));
                    setText(null);
                } else {
                    setText("Bad image");
                }
                return this;
            }
        }
    
        public class ImageTableModel extends AbstractTableModel {
    
            private List images = new ArrayList<>(25);
            private List icons = new ArrayList<>(25);
    
            @Override
            public int getRowCount() {
                return images.size();
            }
    
            public void add(BufferedImage image) {
                images.add(image);
                icons.add(new ImageIcon(image));
                fireTableRowsInserted(images.size() - 1, images.size() - 1);
            }
    
            @Override
            public int getColumnCount() {
                return 2;
            }
    
            @Override
            public Object getValueAt(int rowIndex, int columnIndex) {
                Object value = null;
                switch (columnIndex) {
                    case 0:
                        value = images.get(rowIndex);
                        break;
                    case 1:
                        value = icons.get(rowIndex);
                        break;
                }
                return value;
            }
    
            @Override
            public Class getColumnClass(int columnIndex) {
                Class clazz = String.class;
                switch (columnIndex) {
                    case 0:
                        clazz = BufferedImage.class;
                        break;
                    case 1:
                        clazz = Icon.class;
                        break;
                }
                return clazz;
            }
    
            @Override
            public String getColumnName(int column) {
                String name = null;
                switch (column) {
                    case 0:
                        name = "BufferedImage";
                        break;
                    case 1:
                        name = "Icon";
                        break;
                }
                return name;
            }
        }
    }
    

提交回复
热议问题