4

Hovercraft Full of Eels helped me already by pointing me too a TableCellRenderer but now: I can draw a circle with no problems. I'm just confused as how the original ImageIcons(inside all cells) get overriden with empty cells and a black circle.

SSCEE:

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

State atm

Anything obvious I'm missing out? (first time fiddling with tablecellrenderers).

Cœur
  • 37,241
  • 25
  • 195
  • 267
ManyQuestions
  • 1,069
  • 1
  • 16
  • 34

4 Answers4

1

I'm not 100% clear on what your actual problem is, but believe that your problem can be solved by creating a custom table cell renderer for your JTable, so that each cell can draw whatever circle desired.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
1

Answer is: Somehow overriding the TabelCellRenderer also overrides to getColumnClass of the DefaultTabelModel that I have overriden. Solution is to make the renderer:

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

            }
    );
ManyQuestions
  • 1,069
  • 1
  • 16
  • 34
1

Just to provide a little more explanation as to the "SOMEHOW" in your answer:

"Somehow overriding the TabelCellRenderer also overrides to getColumnClass of the DefaultTabelModel that I have overriden."

As stated in Concepts: Editors and Renderers from How to Use Tables

To choose the renderer that displays the cells in a column, a table first determines whether you specified a renderer for that particular column. If you did not, then the table invokes the table model's getColumnClass method, which gets the data type of the column's cells. Next, the table compares the column's data type with a list of data types for which cell renderers are registered. This list is initialized by the table, but you can add to it or change it. Currently, tables put the following types of data in the list:

  • Boolean — rendered with a check box.
  • Number — rendered by a right-aligned label.
  • Double, Float — same as Number, but the object-to-text translation is performed by a NumberFormat instance (using the default number format for the current locale).
  • Date — rendered by a label, with the object-to-text translation performed by a DateFormat instance (using a short style for the date and time).
  • ImageIcon, Icon — rendered by a centered label.
  • Object — rendered by a label that displays the object's string value.

Things to note. If you didn't override the getColumnClass(), the renderer will default to Object and will therefore render the object's toString() value, hence the javax.swing.ImageIcon.... As the first couple of lines from the text above state, the table will first look for a custom renderer. If you specify a renderer, that's the renderer it will use. In this context, getColumnClass() is only used to get the renderer from the list above. But because you already specify the renderer, your getColumnClass() is useless.

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
0

I'm just confused as how the original ImageIcons(inside all cells) get overriden with empty cells and a black circle.

The cells in the first column are rendered with black circles because you explicitly assigned a renderer that draws that to the ("Title 1") column. The other cells are all "empty" because you specified null for their values and the default renderer winds up being used, which is a JLabel.

Gimpy
  • 61
  • 5