-2

I have a JTable created using this code :

table = new JTable(new DefaultTableModel(
            new Object[][] {
            },
            en_entete
        )
                )

        {
            public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {

                URL fileURL = null;

                try {
                    Class.forName("com.mysql.jdbc.Driver");
                    Connection conn = DriverManager.getConnection(
                            "jdbc:mysql://localhost/test", "root", "root");
                    PreparedStatement ps = conn.prepareStatement("select name, img from table where id=1");
                    ResultSet rs = ps.executeQuery();

                    while (rs.next()) {
                        String name = rs.getString("name");
                        File temp = File.createTempFile(name, ".jpg");
                        Blob blob = rs.getBlob("img");
                        int blobLength = (int) blob.length();
                        byte[] bytes = blob.getBytes(1, blobLength);
                        blob.free();
                        BufferedImage img = ImageIO.read(new ByteArrayInputStream(bytes));
                        ImageIO.write(img, "jpg", temp);

                        fileURL = temp.toURI().toURL();
                    }

                } catch (Exception ex) {
                    ex.printStackTrace();
                }

                html
                = "<html><body>"
                + "<img src='"
                + fileURL + "'>";

                Component c = super.prepareRenderer(renderer, row, column);
                if (c instanceof JComponent) {
                    JComponent jc = (JComponent) c;
                    jc.setToolTipText(html);
                }
                return c;
            }

        };

So when the mouse hovers over a cell of my JTable, the image show up. But I want that image to be different for each cell (changing the SQL request) and to be shown only for the first column.

Thanks in advance

Simo03
  • 273
  • 3
  • 10
  • 21

1 Answers1

1

This is one possible approach...

I prefer to rely on the TableCellRenderer, but in this case, it's not going to be possible.

Instead, this uses the getToolTipText method of the JTable to try and load the image from the database based on the value of column 0, which is assumed to be the ID of the image we are looking for.

This uses a caching mechanism so that instead of having to hit the database each time the tooltip is requested, it can look up any previously cached values.

public class MyTable extends JTable {

    private Connection con;
    private Map<Long, File> imgCache;

    public MyTable(Connection con) {
        this.con = con;
        imgCache = new HashMap<>(25);
        // Register with the TooltipManager
        setToolTipText("No image available");
    }

    @Override
    public String getToolTipText(MouseEvent event) {
        String tip = super.getToolTipText(event);

        int col = columnAtPoint(event.getPoint());
        int row = rowAtPoint(event.getPoint());

        Object value = getValueAt(row, 0);
        if (value instanceof Number) {
            long id = ((Number) value).longValue();
            File source = imgCache.get(id);
            if (source == null) {
                try (PreparedStatement ps = con.prepareStatement("select name, img from table where id=?")) {
                    ps.setLong(1, id);
                    ResultSet rs = ps.executeQuery();
                    if (rs.next()) {
                        String name = rs.getString("name");
                        Blob blob = rs.getBlob("img");
                        int blobLength = (int) blob.length();
                        byte[] bytes = blob.getBytes(1, blobLength);
                        blob.free();
                        BufferedImage img = ImageIO.read(new ByteArrayInputStream(bytes));
                        source = File.createTempFile(name, ".jpg");
                        ImageIO.write(img, "jpg", source);
                        imgCache.put(id, source);
                    }
                } catch (SQLException | IOException exp) {
                    exp.printStackTrace();
                    tip = "Failed to load image: " + exp.getMessage();
                }
            }
            if (source != null) {
                try {
                    tip = "<html><body>"
                                    + "<img src='"
                                    + source.toURI().toURL() + "'>";
                } catch (MalformedURLException exp) {
                    tip = "Failed to load image: " + exp.getMessage();
                }
            } else {
                tip = "No image available";
            }
        }
        return tip;
    }

}

Beware, if the cell renderer has a tooltip, it will override this value.

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366