2

I have a JTable created with a DefaultTableModel, and I want to show an image when the mouse hovers over a particular cell of that JTable, and I need the image to be different for each cell.

Thanks in advance

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Simo03
  • 273
  • 3
  • 10
  • 21

2 Answers2

8

You can override prepareRenderer of the JTable and setToolTip for the cell/column/row component, and use some HTML for the tooltop, as see here and here

enter image description here

For each different image you will need to get a different URL as the src of the img tag. You'll need to know some basic HTML for this. You can obtain an URL by using getClass().getResource() for images in the class path. Or you can use File.getUri().getUrl() to get image files on the file system. One of the links above also shows how you can get images from a relational database.

Whatever way you obtain the URL, you will use it for the URL in the <img src tag. Something like (from linked answer):

URL url = getClass().getResource("/path/to/image");
String html = "<html><body>"
        + "<img src='"
        + url
        + "' width=150 height=150> ";

jc.setToolTipText(html + "<br/>"
        + getValueAt(row, column).toString()
        + ":  row, col (" + row + ", " + column + ")"
        + "</body></html>");

You will need to organize your images in some way where you can the data from the model corresponds some way to a path that can used to obtain the URL. Say you have a name as a piece of data in the table, then you want to be able to use that name as an identifier in obtaining the URL


UPDATE with complete example

Given this is my following project structure

ProjectRoot
          src
             resources
                    mario
                         Mario.png
                         Luigi.png

the following works

import java.awt.Component;
import java.net.URL;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

public class TableTooltipDemo {

    public TableTooltipDemo() {
        JTable table = getTable(getModel());
        JFrame frame = new JFrame("Table ToolTip");
        frame.add(new JScrollPane(table));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private JTable getTable(DefaultTableModel model) {
        JTable table = new JTable(model) {
            @Override
            public Component prepareRenderer(TableCellRenderer renderer,
                    int row, int col) {

                Component c = super.prepareRenderer(renderer, row, col);
                if (c instanceof JComponent) {
                    JComponent jc = (JComponent)c;
                    String name = getValueAt(row, 0).toString();
                    String html = getHtml(name);
                    jc.setToolTipText(html);
                }   
                return c;
            }
        };
        return table;
    }

    private String getHtml(String name) {
        URL url = getClass().getResource("/resources/mario/" + name + ".png");
        String html
        = "<html><body>"
        + "<img src='"
        + url
        + "' width=150 height=150></body></html>";
        return html;
    }

    private DefaultTableModel getModel() {
        String[] cols = { "Name", "Age", "Message" };
        Object[][] data = { { "Mario", 32, "I am Mario!" },
                { "Luigi", 32, "I am Luigi!" },
                { "Bowser", 32, "I am Bowser!" },
                { "Princess", 32, "I am Princess!" },
                { "Koopa", 32, "I am Koopa!" } };
        DefaultTableModel model = new DefaultTableModel(data, cols);
        return model;
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new TableTooltipDemo();
            }
        });
    }
}
Community
  • 1
  • 1
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • I inderstand how to get an image URL, but I don't know how to use this code, or where to insert it? what is jc ? – Simo03 May 12 '14 at 08:18
  • It's a JComponent. You cant set a tooltip on a Component, so first you check if the renderer component is an instance of `JComponent`, then cast it. `jc` is the casted Component to a `JComponent` so that you can call `JComponent`'s `setToolTip` on the renderer component – Paul Samsotha May 12 '14 at 08:21
  • Look at the links I posted. They have complete working examples – Paul Samsotha May 12 '14 at 08:22
  • 1
    See my **UPDATE** for a more intuitive working example. The linked answers may be a little off for what you are trying to do – Paul Samsotha May 12 '14 at 09:21
1

You need to use a custom TableCellRenderer.

If you subclass from DefaultTableCellRenderer, which extends JLabel, you can very easily introduce the images by using the renderer's setIcon method, and providing it with one of your images wrapped inside an ImageIcon.

If this is your first attempt with renderers, I suggest reading the following tutorial: Custom table renderers

ethanfar
  • 3,733
  • 24
  • 43
  • Ok, but I don't want to change what is in the cell, I just want the image to be shown when the cursor of the mouse is on the cell – Simo03 May 12 '14 at 06:26
  • Do I have to add a listener and apply the renderer inside it ? and how to do so ? – Simo03 May 12 '14 at 06:33
  • What do you mean by "I don't want to change what is in the cell" ? Do you want the image to appear in a tooltip ? – ethanfar May 12 '14 at 07:47