双击 jtable 中的图像图标会使图像图标消失

double clicking on an imageicon in jtable makes the imageIcon dissapear

我有一个 JTable 从数据库中获取数据并显示的地方。其中一列是 blob 对象类型,它包含一个图像(如果存在,否则为 null)。 我还有一个用于 JTable 的双击事件处理程序,因此当用户仅双击图像时,将打开一个新的 JFrame 以全屏显示图像。 我面临的问题是,当用户双击图像时,图像按预期显示在新 window 中,但是之前在 JTable 中可见的 imageIcon 消失了,而是显示了一个具有值的字符串作为 javax.swing.ImageIcon@1ce5bc4d。那么如何在完成双击事件后取回 imageIcon 呢? 这是我的代码(payment_receipt 列是 blob):

String query = "Select payment_date,payment_amt,payment_receipt from fooTable";
    conn = dbTest.connect();
    try {
        PreparedStatement ps = conn.prepareStatement(query);
        ResultSet rs = ps.executeQuery();
        ResultSetMetaData rsMetaData = (ResultSetMetaData) rs.getMetaData();
        int columns = rsMetaData.getColumnCount();

        //names of columns
        Vector<String>columnNames = new Vector<String>();

        for(int i=1;i<=columns;i++)
        {
            columnNames.add(rsMetaData.getColumnName(i));
        }

        //data of table
         Vector<Vector<Object>> data = new Vector<Vector<Object>>();
         while (rs.next()) {
                Vector<Object> vector = new Vector<Object>();
                for (int columnIndex = 1; columnIndex <= columns; columnIndex++) 
                {
                    if (columnIndex ==3 ) //starting index is 1
                    {  // image column
                        Blob blob = rs.getBlob("payment_receipt");
                        if(blob!=null)
                        {

                            int blobLength = (int) blob.length();  

                            byte[] bytes = blob.getBytes(1, blobLength);
                            blob.free();
                            BufferedImage img=null;
                            try {
                                img = ImageIO.read(new ByteArrayInputStream(bytes));
                                icon = new ImageIcon(img);

                                vector.addElement(icon);
                            } 
                            catch (Exception e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }

                        }
                    } 
                    else 
                    {
                        vector.addElement(rs.getObject(columnIndex));
                    }

            }
           data.add(vector);
         }
         table = new JTable(new DefaultTableModel(data,columnNames))
                 {
                    @Override
                    public Class<?> getColumnClass(int column) {
                        if(column==2)
                        {
                                return ImageIcon.class;
                        }
                        else
                            return Object.class;
                    }
                };

        table.setRowHeight(200);//to display the receipt
        table.setPreferredScrollableViewportSize(this.getPreferredSize());
        table.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent mouseEvent)
            {
                JTable table = (JTable)mouseEvent.getSource();
                Point point = mouseEvent.getPoint();
                int row = table.rowAtPoint(point);//the index of row where the double click event too place
                int column = table.columnAtPoint(point);
                if(mouseEvent.getClickCount()==2 && table.getSelectedRow() !=-1)
                {
                    if(column==2)//image column,so open image in full screen
                    {
                        Object obj = table.getValueAt(row, column);
                        if(obj!=null)
                        {
                            if(obj.getClass().equals(ImageIcon.class))
                            {
                                ImageIcon icon = (ImageIcon)obj;
                                jf = new JFrame();
                                jf.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
                                jf.setBounds(GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds());
                                jf.add(new JLabel(icon));
                                jf.setVisible(true);
                                loadPaymentsTable();
                            }
                            else
                            {
                                JOptionPane.showMessageDialog(null, "No image available");
                                loadPaymentsTable();
                            }
                        }
                        else
                        {
                                JOptionPane.showMessageDialog(null, "No image available");
                                loadPaymentsTable();
                        }
                    }
                }
            }

        });
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

在两个 JFrame 中使用相同的 ImageIcon 可能会导致问题;为新 window.

复制图像

java 组件使用的本机资源,尤其是图像和 BufferedImages 对重用和处置很敏感。

我通过将 ImageIcon.class 更改为 Icon.class 获得了解决方案:

@Override
                public Class<?> getColumnClass(int column) {
                    if(column==2)
                    {
                            return Icon.class;
                    }
                    else
                        return Object.class;
                }