Как правильно использовать собственные средства визуализации для рисования конкретных ячеек в JTable?

У меня есть компонент JTable в моем графическом интерфейсе, который отображает psuedocode алгоритма. Я хочу выделить текущую строку выполнения, изменив фон конкретной ячейки, а затем изменив ячейку ниже и так далее.

Сейчас мой код меняет фоны на всех ячейках моего JTable, как показано на рисунке ниже:

JTable

Код, который я использую для архивирования текущего состояния, приведен ниже:

 class CustomRenderer extends DefaultTableCellRenderer { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JLabel d = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); if((row == 0) && (column == 0)) d.setBackground(new java.awt.Color(255, 72, 72)); return d; } } 

Затем я вызываю jTable2.setDefaultRenderer(String.class, new CustomRenderer()); в моем конструкторе.

Я предполагаю, что:

  • Этот метод вызывается в каждой ячейке таблицы типа String.
  • Что это только изменит цвет ячейки в позиции (0,0)

Как исправить мой код, чтобы покрасить только ячейку (0,0)?

Добавьте условие else в ваш if :

 if ((row == 0) && (column == 0)) { d.setBackground(new java.awt.Color(255, 72, 72)); } else { d.setBackground(Color.WHITE); } 

Помните, что один и тот же экземпляр визуализации используется для рисования всех ячеек.

Это не ответ (*), слишком длинный для комментария к обоим ответам: оба правильны в том, что блок else является важным, чтобы гарантировать, что цвет по умолчанию используется для ячейки, которая не должна быть подсвечена. Они немного ошибаются в том, как достичь этого, и с тем же общим эффектом: они пропускают любую специальную раскраску, например fi из-за выбора, фокусировки, редактируемого, dnd …

Они достигают этого «промаха» различными способами с немного разными эффектами

 setBackground(Color.WHITE); 

set – фиксированный цвет, который может быть или не быть стандартным «стандартным» табличным фоном

 setBackground(null); 

set не имеет цвета, что приводит к отображению «нормального» цвета фона – из-за внутренней трюки реализации DefaultTableCellRenderer isOpaque 🙂

Основной причиной проблемы (также известной печально известной цветной памятью, TM) является необычно плохая реализация рендеринга по умолчанию, которая оставляет его по существу нерасширяемым:

  /** * Overrides JComponent.setBackground to assign * the unselected-background color to the specified color. * * JW: The side-effect is documented and looks innocent enough :-) */ public void setBackground(Color c) { super.setBackground(c); unselectedBackground = c; } // using that side-effect when configuring the colors in getTableCellRendererComp // is what leads to the horrendeous problems // in the following lines of the else (not selected, that is normal background color) Color background = unselectedBackground != null ? unselectedBackground : table.getBackground(); super.setBackground(background); 

Увидев это, выход (кроме использования SwingX и его гибкой, чистой, мощной, последовательной поддержки: 🙂 – это @ Hovercraft, но обратный: сначала выполните пользовательскую раскраску (или null, если она не указана), а затем вызовите super:

  @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (myHighlightCondition) { setBackground(Color.RED); } else { setBackground(null); } super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); return this; } 

(*) В конце концов, этот комментарий привел к ответу, забыл, что он исправляется на пользовательском уровне визуализатора 🙂

BTW: Захват «первого» вызова рендеринга очень хрупкий, нет никакой гарантии, по которой произойдет эта ячейка, вполне может быть последней строкой последнего столбца.

Вы забыли свою другую часть вашего блока if, код, который рисует фон по умолчанию, если это не важная строка:

  if (row == 0 && column == 0) { d.setBackground(new java.awt.Color(255, 72, 72)); } else { d.setBackground(null); } 

Мой SSCCE

 import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; import javax.swing.table.DefaultTableCellRenderer; public class TestJTable { private static int highlightedRow = 0; private static void createAndShowGui() { String[] columnNames = {"Program"}; Object[][] rowData = {{"Row 1"}, {"Row 2"}, {"Row 3"}, {"Row 4"}, {"Row 1"}, {"Row 2"}, {"Row 3"}, {"Row 4"}, {"Row 1"}, {"Row 2"}, {"Row 3"}, {"Row 4"}}; final JTable myTable = new JTable(rowData , columnNames ); myTable.setDefaultRenderer(Object.class, new 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); if (row == highlightedRow && column == 0) { c.setBackground(new java.awt.Color(255, 72, 72)); } else { c.setBackground(null); } return c; } }); JFrame frame = new JFrame("TestJTable"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(new JScrollPane(myTable)); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); new Timer(1000, new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { highlightedRow++; int rowCount = myTable.getRowCount(); highlightedRow %= rowCount; myTable.repaint(); } }).start(); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } }); } } 
  • Загружать данные массива в JTable
  • Ограниченный выбор в JTextField / JTextComponent?
  • Растянуть текст JLabel
  • Как установить значок в JFrame
  • drag and drop jlabel вокруг экрана
  • Воспроизведение нескольких аудиоклипов с использованием объектов Clip
  • java swing background image
  • Как использовать собственный редактор ячеек JTable и средство отображения ячеек
  • Java делает направленную линию и заставляет ее двигаться
  • как обращаться с плохим выбором файла для отображения изображения в качелях
  • Поверните JLabel или ImageIcon на Java Swing
  • Давайте будем гением компьютера.