如何在 JTable 中显示图标而不是数字?

How to show icon instead of number in JTable?

为了保存数据库 space,我将数字而不是图标保存到数据库中。例如数据库中的数字 9 表示 B.png。我想要的是首先将数据加载到JTable

然后循环把数字改成相应的图标,比如9应该改成B.png icon:

但是我把数据加载到table后就不行了,9号单元格应该显示图标,但显示的是图标的文件路径:

  public void load() {
    try {
        conn = (Connection) DriverManager.getConnection("jdbc:mysql://192.168.30.6/game?autoReconnect=true", "lee", "");
        pstmt = (PreparedStatement) conn.prepareStatement("Select c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17 From test_socre order by sn");
        rs = pstmt.executeQuery();
        score.setModel(DbUtils.resultSetToTableModel(rs));
        while (rs.next()) {
        }
        DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
        centerRenderer.setHorizontalAlignment(JLabel.CENTER);
        score.getColumnModel().getColumn(0).setCellRenderer(centerRenderer);
        for (int x = 0; x < score.getColumnCount(); x++) {
            score.getColumnModel().getColumn(x).setCellRenderer(centerRenderer);//how to center alignment in jtable
        }
        for (int ix = 0; ix < score.getRowCount(); ix++) {
            for (int jy = 0; jy < score.getColumnCount(); jy++) {
                if (score.getValueAt(ix, jy) != null && "9".equals(score.getValueAt(ix, jy).toString())) {

                    ImageIcon icon = new ImageIcon(getClass().getResource("/slip/B.png"));

                    score.setValueAt(icon, ix, jy);
                }
            }
        }

        rs.close();
        pstmt.close();
        conn.close();
    } catch (SQLException ex) {
        Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex);
    }
}

尝试设置默认渲染器:

myTable.getColumnModel().getColumn(1)
.setCellRenderer(myTable.getDefaultRenderer(ImageIcon.class));

对每个输入 ImageIcon.

的单元格执行此操作

but it shows the icon's file path:

您需要告诉 table 使用什么渲染器;

如果 table 中的所有数据都是 Icon 那么您可以告诉 table 使用默认的图标渲染器。

第一次尝试:

table.setDefaultRenderer(Object.class, table.getDefaultRenderer(Icon.class));

如果这不起作用,那么您可以使用:

JTable table = new JTable(data, columnNames)
{
    @Override
    public Class getColumnClass(int column)
    {
        return Icon.class;
    }
};

如果您有文本和图标的组合,那么您可以使用类似的东西:

JTable table = new JTable(...)
{
    @Override
    public TableCellRenderer getCellRenderer(int row, int column)
    {
        Object value = getValueAt(row, column);

        return getDefaultRenderer(value.getClass();
    }

};

我仍然不确定我是否理解这个问题,但请注意渲染器可以为每个值选择一个合适的图标。这是左侧 table 中的原始数字和右侧 table 中相同 table 模型的图标的样子。

特别注意下面代码中的IconTableCellRenderer

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);
    }
}