JTable Cell Renderer

我正在按照我发现的一些代码,(是的我理解它是如何工作的)它来自这里: Code Link

如果单元格值设置为“黄色”,我正在尝试设置单元格前景色

这是我的代码:

public class Board extends JPanel{ private static final long serialVersionUID = 1L; int boardHeight = 20; int boardWidth = 10; JTable table; public Board() { table = new JTable(this.boardHeight, this.boardWidth); table.setDefaultRenderer(String.class, new BoardTableCellRenderer()); table.setFocusable(false); table.setShowGrid(false); table.setRowMargin(0); table.setIntercellSpacing(new Dimension(0,0)); table.setRowSelectionAllowed(false); table.setVisible(true); this.add(table); this.setPreferredSize(new Dimension(table.getPreferredSize().width, (table.getPreferredSize().height + 85))); } public void paint(Graphics g) { table.setRowHeight(20); for (int x = 0; x < this.table.getColumnCount(); ++x) { TableColumn col = this.table.getColumnModel().getColumn(x); col.setPreferredWidth(20); } } } 

还有Cell Renderer

 public class BoardTableCellRenderer extends DefaultTableCellRenderer { private static final long serialVersionUID = 1L; public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,int row,int col) { Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); String s = table.getModel().getValueAt(row, col).toString(); if (s.equalsIgnoreCase("yellow")) { c.setForeground(Color.YELLOW); } else { c.setForeground(Color.WHITE); } return c; } } 

问题是它没有改变,如果我将任何单元格值设置为“黄色”

提前致谢!

您的渲染器是否曾被使用过? 你使它成为包含String的单元格的默认渲染器,但是你是否重载了模型的getColumnClass方法,以便它知道某些单元格包含字符串?

所以首先我使用println语句来查看渲染器是否被调用,如果没有,我会覆盖我的模型的方法,如上所述。

编辑1
你的if结果也一定很奇怪。 在if部分中你改变了forground而在else中你改变了背景 – 没有意义。 您可能应该在if与else块中进行状态的互补更改,而不是正交更改。

编辑2
例如:

 import java.awt.*; import java.util.Random; import javax.swing.*; import javax.swing.table.*; public class Board extends JPanel { private static final long serialVersionUID = 1L; int boardHeight = 20; int boardWidth = 10; JTable table; Random random = new Random(); public Board() { setLayout(new BorderLayout()); // !! DefaultTableModel model = new DefaultTableModel(boardHeight, boardWidth) { @Override public Class getColumnClass(int columnIndex) { return String.class; } }; // !! table = new JTable(this.boardHeight, this.boardWidth); table = new JTable(model); for (int row = 0; row < model.getRowCount(); row++) { for (int col = 0; col < model.getColumnCount(); col++) { String s = random.nextBoolean() ? "red" : "yellow"; model.setValueAt(s, row, col); } } table.setDefaultRenderer(String.class, new BoardTableCellRenderer()); table.setFocusable(false); table.setShowGrid(false); table.setRowMargin(0); table.setIntercellSpacing(new Dimension(0, 0)); table.setRowSelectionAllowed(false); table.setVisible(true); this.add(table); this.setPreferredSize(new Dimension(table.getPreferredSize().width, (table.getPreferredSize().height + 85))); } private static void createAndShowUI() { JFrame frame = new JFrame("Board"); frame.getContentPane().add(new Board()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { createAndShowUI(); } }); } } class BoardTableCellRenderer extends DefaultTableCellRenderer { private static final long serialVersionUID = 1L; public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) { Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); Object valueAt = table.getModel().getValueAt(row, col); String s = ""; if (valueAt != null) { s = valueAt.toString(); } if (s.equalsIgnoreCase("yellow")) { c.setForeground(Color.YELLOW); c.setBackground(Color.gray); } else { c.setForeground(Color.black); c.setBackground(Color.WHITE); } return c; } } 

添加此行:

 c.setOpaque(true); 

getTableCellRendererComponent返回的Component必须是不透明的,才能看到背景和前景颜色的变化。 这里的问题也是另一个问题:你正在扩展DefaultTableCellRenderer(它是一个JComponent),但是你返回的是一个没有setOpaque方法的Component。 我会像这样重构你的代码:

 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,int row,int col) { String s = table.getModel().getValueAt(row, col).toString(); this.setOpaque(true); if (s.equalsIgnoreCase("yellow")) { this.setForeground(Color.YELLOW); } else { this.setBackground(Color.WHITE); } return this; } 

这是一个简单的解决方案,使用TabaleCellRendere作为内部类。

  myTable.setDefaultRenderer(Object.class, new TableCellRenderer() { JLabel comp = new JLabel(); String val; @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { comp.setOpaque(true); comp.setForeground(Color.BLACK); // text color if (value != null) { val = value.toString(); comp.setText(val); if (val.equalsIgnoreCase("red")) { comp.setBackground(Color.RED); } else if (val.equalsIgnoreCase("yellow")) { comp.setBackground(Color.YELLOW); } else if (val.equalsIgnoreCase("green")) { comp.setBackground(Color.GREEN); } else { comp.setBackground(Color.WHITE); } } return comp; } });