1

我在 JTable 中有一个列,它应该显示两种类型:字符串或 ImageIcon,而不是两者。该列中的每个单元格都有自己的线程来计算数据。一开始我给每个单元格放置一个图像(如等待徽标),然后用一串计算数据替换(不附加)图像。我试图扩展默认的 TableCell 渲染器,但它显示像对象地址(javax.swing.ImageIcon@342...)这样的图像,然后用字符串替换。另一种变体,它正确显示图像,但用空字符串替换它(或者它不可见?)。

如何设置它以便表格根据类型正确显示单元格内容?

这是我目前所拥有的:

class IconAndStringRenderer extends DefaultTableCellRenderer {

private static final long serialVersionUID = 3606788739290618405L;

public Component getTableCellRendererComponent(JTable table, Object value,
                          boolean isSelected, boolean hasFocus, int row, int column) {
    super.getTableCellRendererComponent(table, value,
                          isSelected, hasFocus, row, column);
    if (value instanceof Icon) {

      setIcon((Icon) value);
      setText("");
    } 
    return this;
  }
}

这是JTable:

表 = 新 JTable(模型){

        private static final long serialVersionUID = 8058795799817761161L;

        public Class<?> getColumnClass(int column) {
            if (column == TARGET_COLUMN)
                return ImageIcon.class;
            else
                return super.getColumnClass(column);
        }
    };

还有几个问题:

  1. 如何设置它以使文本替换图像,而不是在图像之后写入文本(即使它不可见);

  2. 如何设置文本颜色,我将使用 setForebackground(Color c),但如果我使用它,图像不会显示。

  3. 是否可以使其与 Jlabel 一起使用?在修改单元格的线程中设置所需的 Jlabel(带有图像或文本),只需 setValueAt(label, row, column);

4

3 回答 3

2

默认渲染器知道如何显示字符串和图标。您所要做的就是确保您分别从、和中TableModel返回正确的类。可以在此处找到示例。getColumnClass()String.classIcon.class

附录:这是一个基于默认实现的最小示例来说明原理。

附录:不确定在需要为同一列返回不同类时是否有效

如果您确实需要在每个单元格的基础上选择渲染器,请覆盖,如此prepareRenderer()所示。

图片

import java.awt.EventQueue;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;

/** @see https://stackoverflow.com/a/14672312/230513 */
public class Test {

    private static final Icon YES = UIManager.getIcon("InternalFrame.maximizeIcon");
    private static final Icon NO = UIManager.getIcon("InternalFrame.closeIcon");

    private void display() {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        DefaultTableModel model = new DefaultTableModel(
            new Object[]{"Name", "Icon"}, 0) {

            @Override
            public Class<?> getColumnClass(int col) {
                if (col == 1) {
                    return Icon.class;
                } else {
                    return super.getColumnClass(col);
                }
            }
        };
        model.addRow(new Object[]{"One", YES});
        model.addRow(new Object[]{"Two", NO});
        final JTable table = new JTable(model);
        table.setRowHeight(YES.getIconHeight() +2);
        f.add(table);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

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

            @Override
            public void run() {
                new Test().display();
            }
        });
    }
}
于 2013-02-03T12:10:41.333 回答
2

要利用默认渲染器,您可以覆盖 JTable 的 getCellRenderer(...) 方法以返回适当的渲染器。就像是:

public TableCellRenderer getCellRenderer(int row, int column)
{
    int modelColumn = convertColumnIndexToModel(column);

    if (modelColumn == ???)
    {
        Class rowClass = getModel().getValueAt(row, modelColumn).getClass();
        return getDefaultRenderer( rowClass );
    }
    else
        return super.getCellRenderer(row, column);
}
于 2013-02-03T18:42:16.613 回答
2

您需要一个可以理解您使用的两种类型的自定义渲染器。

例如

public class IconAndStringRenderer extends DefaultTableCellRenderer {
  public Component getTableCellRendererComponent(JTable table, Object value,
                          boolean isSelected, boolean hasFocus, int row, int column) {
    super.getTableCellRendererComponent(table, value,
                          isSelected, hasFocus, row, column);
    if (value instanceof Icon) {
      setText("");
      setIcon((Icon) value);
    }
    return this;
  }
}

尝试将此类设置为您的列渲染器

于 2013-02-03T10:52:18.247 回答