How to Set Icon in a Column of Jtable

How to set icon in a column of JTable?

There is no need to create a custom render. JTable already supports an Icon renderer. YOu just need to tell the table to use this renderer. This is done by overriding the getColumnClass(...) method of the table model:

import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;

public class TableIcon extends JPanel
{
public TableIcon()
{
Icon aboutIcon = new ImageIcon("about16.gif");
Icon addIcon = new ImageIcon("add16.gif");
Icon copyIcon = new ImageIcon("copy16.gif");

String[] columnNames = {"Picture", "Description"};
Object[][] data =
{
{aboutIcon, "About"},
{addIcon, "Add"},
{copyIcon, "Copy"},
};

DefaultTableModel model = new DefaultTableModel(data, columnNames)
{
// Returning the Class of each column will allow different
// renderers to be used based on Class

public Class getColumnClass(int column)
{
switch (column)
{
case 0: return Icon.class;
default: return super.getColumnClass(column);
}
}
};
JTable table = new JTable( model );
table.setPreferredScrollableViewportSize(table.getPreferredSize());

JScrollPane scrollPane = new JScrollPane( table );
add( scrollPane );
}

private static void createAndShowGUI()
{
JFrame frame = new JFrame("Table Icon");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TableIcon());
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}

public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}

}

How to set icon in a jtable while filling the table?

but all get is the link of the image :

Then that means you are storing text in that column.

You have a couple of problems that I can see:

You code is attempting to read an Image, but you need to store an ImageIcon in the TableModel. So you need to change your addRow(...) statement to use:

addRow(..., new ImageIcon(image));

So you add each value in the order you want them displayed in the table.

When you fix the above statement it looks like the Icon will be the 6th parameter of the addRow(...) statement. However, according to your getColumnClass(...) method the Icon is in the 2 column. Doesn't this seem strange to you?

Adding icons to jTable in different rows

This is solved easily by simply making sure that the column for the icons returns Icon.class in the table model's getColumnClass(...) method. Fortunately JTables know how to display icons without any extra work if you do this. For example.

A modification of my code from there uses this table model:

  DefaultTableModel model = new DefaultTableModel(COL_NAMES, 0) {
@Override
public Class<?> getColumnClass(int column) {
if (getRowCount() > 0) {
Object value = getValueAt(0, column);
if (value != null) {
return getValueAt(0, column).getClass();
}
}

return super.getColumnClass(column);
}
};

The whole program:

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;

public class ImageColumnTest2 {
public static final String IMAGE_SHEET_PATH = "http://speckycdn.sdm.netdna-cdn.com/"
+ "wp-content/uploads/2010/08/flag_icons_04.jpg";
public static final String[] COUNTRIES = {
"Denmark", "China", "Chile", "Canada", "Belgium", "Austria",
"Argentina", "France", "Malaysina", "Lebanon", "Korea", "Japan",
"Italy", "Ireland", "India", "Hong Kong", "Greece", "Germany"
};
public static final int COLS = 6;
public static final int ROWS = 3;
private static final String[] COL_NAMES = {"Country", "Flag"};

private JTable table = new JTable();
private JScrollPane mainPane = new JScrollPane(table);

public ImageColumnTest2() throws IOException {
DefaultTableModel model = new DefaultTableModel(COL_NAMES, 0) {
@Override
public Class<?> getColumnClass(int column) {
if (getRowCount() > 0) {
Object value = getValueAt(0, column);
if (value != null) {
return getValueAt(0, column).getClass();
}
}

return super.getColumnClass(column);
}
};
URL url = new URL(IMAGE_SHEET_PATH);
BufferedImage img = ImageIO.read(url);
int x1 = 15; // sorry about the magic numbers
img = img.getSubimage(x1, 0, img.getWidth() - 2 * x1, img.getHeight());

int y1 = 20 ; // ditto!
int w = img.getWidth() / COLS;
int h = img.getHeight() / ROWS;
for (int row = 0; row < ROWS; row++) {
int y = (row * img.getHeight()) / ROWS;
for (int col = 0; col < COLS; col++) {
int x = (col * img.getWidth()) / COLS;
BufferedImage subImg = img.getSubimage(x, y, w, h);

subImg = subImg.getSubimage(x1, 0, subImg.getWidth() - 2 * x1, subImg.getHeight() - y1);

ImageIcon icon = new ImageIcon(subImg);
String country = COUNTRIES[col + row * COLS];
Object[] rowData = {country, icon};
model.addRow(rowData);
}
}

table.setModel(model);
table.setRowHeight(((ImageIcon)model.getValueAt(0, 1)).getIconHeight());
}

public JComponent getMainComponent() {
return mainPane;
}

private static void createAndShowGui() {
ImageColumnTest2 imgColumnTest = null;
try {
imgColumnTest = new ImageColumnTest2();
} catch (MalformedURLException e) {
e.printStackTrace();
System.exit(-1);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}

JFrame frame = new JFrame("ImageColumnTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(imgColumnTest.getMainComponent());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Which displays as:

Sample Image

JTable, how can I put icons in the header?

Your link is good code , but in fact when you load a picture using absolute path or relative path , this code is not portable .So it is better to load picture from a class. Levels :
1) Create a empty class with this name : ImageResources
2) Please copy your picture
3) Please find ImageResources class in package explorer (in eclipse) and do right click on it (ImageResources) and press "Paste" menuItem.
4) Finally you need a small change in your code like this

ImageIcon blueIcon = new ImageIcon(ImageResources.class.getResource(yourPictureName));

It is working :)

Displaying additional icon on the left side of a JTable column header (Nimbus)

Or simpler, you can use HTML tags to display the icon on the HeaderRenderer:

Sample Image

Sample Image

import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import java.util.Objects;
import javax.swing.*;
import javax.swing.table.*;

public class TableHeaderIconTest {
//private final URL url = getClass().getResource("a.png");
public JComponent makeUI() {
String[] columnNames = {"Column1", "Column2", "Column3"};
JTable table = new JTable(new DefaultTableModel(columnNames, 3));
TableColumnModel m = table.getColumnModel();
for (int i = 0; i < m.getColumnCount(); i++) {
TableColumn column = m.getColumn(i);
column.setHeaderRenderer(new FilterIconHeaderRenderer4());
//column.setHeaderValue(
// String.format("<html><table><td><img src='%s'/><td>%s", url, columnNames[i]));
}
table.setAutoCreateRowSorter(true);

JPanel p = new JPanel(new BorderLayout());
p.add(new JScrollPane(table));
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
try {
for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(laf.getName())) {
UIManager.setLookAndFeel(laf.getClassName());
}
}
} catch (Exception e) {
e.printStackTrace();
}
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new TableHeaderIconTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}

class FilterIconHeaderRenderer4 implements TableCellRenderer {
private final URL url = getClass().getResource("Ok2mc.png");
@Override public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
TableCellRenderer r = table.getTableHeader().getDefaultRenderer();
String str = Objects.toString(value, "");
String html = String.format("<html><table><td><img src='%s'/><td>%s", url, str);
return r.getTableCellRendererComponent(table, html, isSelected, hasFocus, row, column);
}
}

How to show icon instead of number in JTable?

I'm still not sure if I understand the question, but note that the renderer can choose an appropriate icon for each value. Here is what it might look like with the raw numbers on the left table, and icons for the same table model in the table on the right.

Sample Image

Note particularly the IconTableCellRenderer in the code below:

import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.net.URL;
import javax.swing.table.*;
import java.util.Random;

public class ImageForNumberTable {

private JComponent ui = null;
String prefix = "https://i.stack.imgur.com/";
String[] urlStrings = {
"wCF8S.png", "5v2TX.png", "F0JHK.png", "4EVv1.png", "xj49g.png"
};
ImageIcon[] imageIcons = new ImageIcon[5];

ImageForNumberTable() {
try {
initUI();
} catch (Exception ex) {
ex.printStackTrace();
}
}

public final void initUI() throws Exception{
if (ui!=null) return;

for (int ii=0; ii<urlStrings.length; ii++) {
URL url = new URL(prefix + urlStrings[ii]);
imageIcons[ii] = new ImageIcon(url);
}
Random random = new Random();
Integer[][] values = new Integer[5][5];
for (int xx=0; xx<values.length; xx++) {
for (int yy=0; yy<values[0].length; yy++) {
values[xx][yy] = new Integer(random.nextInt(5));
}
}
String[] colNames = {"Col 1", "Col 2", "Col 3", "Col 4", "Col 5"};
DefaultTableModel dtm = new DefaultTableModel(values, colNames);

ui = new JPanel(new GridLayout(0,2,0,0));
ui.setBorder(new EmptyBorder(4,4,4,4));

JTable table1 = new JTable(dtm);
table1.setRowHeight(36);
JTable table2 = new JTable(dtm);
table2.setDefaultRenderer(Object.class, new IconTableCellRenderer());
table2.setRowHeight(36);

ui.add(new JScrollPane(table1));
ui.add(new JScrollPane(table2));
}

public JComponent getUI() {
return ui;
}

class IconTableCellRenderer extends DefaultTableCellRenderer {

@Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
Component c = super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
JLabel l = (JLabel)c;
final Integer val = (Integer)value;
l.setIcon(imageIcons[val.intValue()]);
l.setText("");

return l;
}
}

public static void main(String[] args) {
Runnable r = () -> {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
ImageForNumberTable o = new ImageForNumberTable();

JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);

f.setContentPane(o.getUI());
f.pack();

f.setVisible(true);
};
SwingUtilities.invokeLater(r);
}
}

How to add text next to image in jtable?

I did find this but don't know what goes in ... or how to set the ImageIcon and string in the jtable with this:

You need to create custom Object (lets say you call it MyCustomObject) to hold the information you want to display. So your custom Object will have two properties: Icon and Text.

Then you create the Object and add to the TableModel like you do for any other Object in the table.

You need to override the getColumnClass() method to return MyCustomObject for the first two columns. Then you also need to set the custom renderer for the MyCustomObject.

So then in the rendering code you would do something like:

MyCustomObject data = (MyCustomObject)value;
setIcon(data.getIcon());
setText(data.getText());


Related Topics



Leave a reply



Submit