Судно на воздушной подушке Full of Eels уже помогло мне, указав мне тоже TableCellRenderer, но теперь: я могу без проблем нарисовать круг. Я просто смущен тем, как исходные ImageIcons (внутри всех ячеек) переопределяются пустыми ячейками и черным кружком.

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

Что-нибудь очевидное, что я упускаю? (впервые возился с tablecellrenderers).

4
ManyQuestions 16 Май 2014 в 20:58

4 ответа

Лучший ответ

Ответ: Каким-то образом переопределение TabelCellRenderer также переопределяет getColumnClass из DefaultTabelModel, который я переопределил. Решение - сделать рендерер:

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

            }
    );
1
ManyQuestions 19 Май 2014 в 15:46

Я не на 100% понимаю, в чем заключается ваша реальная проблема, но считаю, что ваша проблема может быть решена путем создания настраиваемого средства визуализации ячеек таблицы для вашего JTable, чтобы каждая ячейка могла рисовать любой желаемый круг.

1
Hovercraft Full Of Eels 18 Май 2014 в 02:29

Просто чтобы дать немного больше пояснений по поводу "КАК-ТО" в вашем ответе:

«Каким-то образом переопределение TabelCellRenderer также переопределяет getColumnClass из DefaultTabelModel, которое я переопределил».

Как указано в Concepts: Editors and Renderers от Как использовать таблицы

Чтобы выбрать средство визуализации, которое отображает ячейки в столбце, таблица сначала определяет, указали ли вы средство визуализации для этого конкретного столбца. Если вы этого не сделали, таблица вызывает метод модели таблицы getColumnClass, который получает тип данных ячеек столбца. Затем таблица сравнивает тип данных столбца со списком типов данных, для которых зарегистрированы средства визуализации ячеек. Этот список инициализируется таблицей, но вы можете добавить к нему или изменить его. В настоящее время таблицы помещают в список следующие типы данных:

  • Boolean - отображается с флажком.
  • Число - отображается меткой с выравниванием по правому краю.
  • Double, Float - то же, что и Number, но преобразование объекта в текст выполняется экземпляром NumberFormat (с использованием числового формата по умолчанию для текущей локали).
  • Дата - отображается меткой, с преобразованием объекта в текст, выполняемым экземпляром DateFormat (с использованием короткого стиля для даты и времени).
  • ImageIcon, Icon - отображается центрированной меткой.
  • Объект - отображается меткой, отображающей строковое значение объекта.

На заметку. Если вы не переопределили getColumnClass(), средство визуализации по умолчанию будет использовать Object и, следовательно, отобразит значение объекта toString(), следовательно, javax.swing.ImageIcon.... Как указано в первых двух строках приведенного выше текста, таблица сначала будет искать настраиваемое средство визуализации. Если вы укажете средство визуализации, это средство визуализации, которое оно будет использовать. В этом контексте getColumnClass() используется только для получения средства визуализации из списка выше. Но поскольку вы уже указали рендерер, ваш getColumnClass() бесполезен.

1
Paul Samsotha 19 Май 2014 в 16:07

Я просто смущен тем, как исходные ImageIcons (внутри всех ячеек) переопределяются пустыми ячейками и черным кружком.

Ячейки в первом столбце отображаются с черными кружками, потому что вы явно назначили средство визуализации, которое отображает их в столбце («Заголовок 1»). Все остальные ячейки являются «пустыми», потому что вы указали null для их значений, и в итоге используется средство визуализации по умолчанию, которым является JLabel.

0
Gimpy 22 Май 2014 в 13:58