【问题标题】:Overriding CellRenderer, ImageIcon disappears覆盖 CellRenderer,ImageIcon 消失
【发布时间】:2014-07-05 05:31:03
【问题描述】:

Hovercraft Full of Eels 已经通过向我指出 TableCellRenderer 帮助了我,但现在: 我可以毫无问题地画一个圆圈。我只是对原始 ImageIcons(在所有单元格内)如何被空单元格和黑色圆圈覆盖感到困惑。

SSCE:

package sccee;

import java.awt.Graphics;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.SwingWorker;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

public class SCCEE extends JFrame {

    private JTable spelbordTabel;
    URL url = this.getClass().getResource("/resources/leeg.png");
    ImageIcon leeg = new ImageIcon(new ImageIcon(url).getImage().getScaledInstance(100, 100, java.awt.Image.SCALE_SMOOTH));

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(() -> {
            SCCEE testFrame = new SCCEE();
            testFrame.setBounds(0, 0, 700, 700);
            testFrame.setVisible(true);
        });

    }

    public SCCEE() {
        initComponents();
        updateTableImages();
    }

    private void initComponents() {
        spelbordTabel = new javax.swing.JTable();
        spelbordTabel.setModel(new DefaultTableModel(new Object[][]{
            {null, null, null, null, null, null, null},
            {null, null, null, null, null, null, null},
            {null, null, null, null, null, null, null},
            {null, null, null, null, null, null, null},
            {null, null, null, null, null, null, null},
            {null, null, null, null, null, null, null},
            {null, null, null, null, null, null, null},},
                new String[]{
                    "Title 1", "Title 2", "Title 3", "Title 4", "Title 5", "Title 6", "Title 7"
                }) {

                    @Override
                    public Class
                    getColumnClass(int columnIndex) {
                        return ImageIcon.class;
                    }
                    boolean[] canEdit = new boolean[]{false, false, false, false, false, false, false};

                    @Override
                    public boolean isCellEditable(int rowIndex, int columnIndex) {
                        return canEdit[columnIndex];
                    }

                });
        spelbordTabel.setAutoscrolls(false);
        spelbordTabel.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
        spelbordTabel.setOpaque(false);
        spelbordTabel.setRequestFocusEnabled(false);
        spelbordTabel.setRowHeight(100);
        spelbordTabel.setRowSelectionAllowed(false);
        spelbordTabel.setTableHeader(null);
        spelbordTabel.setUpdateSelectionOnSort(false);
        spelbordTabel.setVerifyInputWhenFocusTarget(false);
        spelbordTabel.setBounds(0, 0, 700, 700);
        spelbordTabel.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0), 4, true));
        spelbordTabel.setDragEnabled(true);
        spelbordTabel.setVisible(true);
        spelbordTabel.getColumn("Title 1").setCellRenderer(
                new DefaultTableCellRenderer() {
                    @Override
                    public void paintComponent(Graphics g) {
                        super.paintComponent(g);
                        g.fillOval(30, 30, 20, 20);
                    }

                }
        );
        add(spelbordTabel);
    }

    public void updateTableImages() {
        SwingWorker<Void, Void> worker2 = new SwingWorker<Void, Void>() {
            @Override
            protected Void doInBackground() throws InterruptedException {
                Thread.sleep(50);
                for (int i = 0; i < 7; i++) {
                    for (int j = 0; j < 7; j++) {
                        spelbordTabel.setValueAt(leeg, i, j);
                    }
                }
                return null;
            }

        };
        worker2.execute();
    }
}

我遗漏了什么明显的东西吗? (第一次摆弄 tablecellrenderers)。

【问题讨论】:

  • 我们可以得到一个可编译的例子吗?
  • SCEE?我可以很快做出一个是的。
  • @JavierDiaz 添加了 SCCEE,您将添加一张选择的图片并更改其路径。

标签: java swing jtable paint tablecellrenderer


【解决方案1】:

我不是 100% 清楚您的实际问题是什么,但相信您的问题可以通过为您的 JTable 创建自定义表格单元格渲染器来解决,这样每​​个单元格都可以绘制所需的任何圆圈。

【讨论】:

  • 我可以这样在一个单元格中绘制多个形状吗?我想是的。
  • @crashystar:是的,绝对的。
【解决方案2】:

答案是:以某种方式覆盖 TabelCellRenderer 也会覆盖到我已覆盖的 DefaultTabelModel 的 getColumnClass。解决方法是制作渲染器:

        spelbordTabel.getColumn("Title 1").setCellRenderer(
            new DefaultTableCellRenderer() {
                @Override
                public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                        boolean hasFocus, int row, int column) {
                    Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row,
                            column);
                    ((JLabel) cell).setIcon((Icon) value);
                    ((JLabel) cell).setText("");
                    ((JLabel) cell).setHorizontalAlignment(JLabel.CENTER);
                    return cell;
                }
                @Override
                public void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    g.fillOval(30, 30, 20, 20);
                }

            }
    );

【讨论】:

    【解决方案3】:

    只是为了对您的回答中的 “SOMEHOW” 提供更多解释:

    “不知何故,覆盖TabelCellRenderer 也覆盖了我已覆盖的DefaultTabelModel 中的getColumnClass。”

    Concepts: Editors and Renderers 中所述,来自How to Use Tables

    要选择在列中显示单元格的渲染器,表格首先会确定您是否为该特定列指定了渲染器。如果您不这样做,则该表调用表模型的getColumnClass 方法,该方法获取列单元格的数据类型。接下来,该表将列的数据类型与注册了单元格渲染器的数据类型列表进行比较。此列表由表初始化,但您可以添加或更改它。目前,表格将以下类型的数据放入列表中:

    • 布尔值 - 使用复选框呈现。
    • 数字 - 由右对齐标签呈现。
    • Double、Float — 与 Number 相同,但对象到文本的转换由 NumberFormat 实例执行(使用当前语言环境的默认数字格式)。
    • 日期 - 由标签呈现,对象到文本的转换由 DateFormat 实例执行(使用日期和时间的短样式)。
    • ImageIcon, Icon — 由居中的标签呈现。
    • 对象 — 由显示对象字符串值的标签呈现。

    注意事项。如果您没有覆盖getColumnClass(),渲染器将默认为Object,因此将渲染对象的toString() 值,即javax.swing.ImageIcon...。作为上述文本的前几行,表格将首先查找自定义渲染器。如果您指定一个渲染器,那就是它将使用的渲染器。在这种情况下,getColumnClass() 仅用于从上面的列表中获取渲染器。但是因为你已经指定了渲染器,所以你的getColumnClass()是没用的。

    【讨论】:

    • 如果我不知道,我无法解释:/ 我有 3/4 年的 Java 经验。
    【解决方案4】:

    我只是对原始 ImageIcons(在所有单元格内)的获取方式感到困惑 用空单元格和黑色圆圈覆盖。

    第一列中的单元格以黑色圆圈呈现,因为您明确分配了一个渲染器,将其绘制到(“标题 1”)列。其他单元格都是“空的”,因为您为它们的值指定了 null 并且最终使用了默认渲染器,即 JLabel。

    【讨论】:

      猜你喜欢
      • 2020-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多