更改单元格颜色而不更改其他单元格中的颜色(Jtable)
Posted
技术标签:
【中文标题】更改单元格颜色而不更改其他单元格中的颜色(Jtable)【英文标题】:Changing Cell Color without changing color in other cells (Jtable) 【发布时间】:2014-08-24 16:06:22 【问题描述】:假设我们有一个 31 列和 10 行的 JTable。 我想将 2 Column 4 行的颜色更改为红色。 在我这样做之后,更改另一个单元格的颜色,而不会丢失我之前的单元格的颜色。
我尝试了以下方法但没有成功:
public class CellR extends DefaultTableCellRenderer
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row, int column)
setForeground(Color.white);
if(row == TestHotel.v.getRow() && column == TestHotel.v.getCol())
// Only for specific cell
// c.setFont(/* special font*/);
// you may want to address isSelected here too
setForeground(Color.BLACK);
setBackground(Color.RED);
return this;
如果我在第一次工作时调用渲染器...但是如果我想更改另一种单元格颜色,我将失去第一个。
【问题讨论】:
这些信息不足以调试您的问题。请提供MCVE。 同意 SSCCE/MCVE,简短,可运行,可编译,在局部变量中为 JTable/XxxTableModel 硬编码值,因为看起来像if(row == TestHotel.v.getRow() && column == TestHotel.v.getCol())
返回银河系中的恒星数量
此表单中的注释代码可能适用于未排序或过滤的 JTables 视图
每次修改都会重新绘制表格。然后你需要保存所有你想改变颜色的单元格。
【参考方案1】:
表格和列表中的单元格渲染器就像“邮票”一样使用。 一个组件用于绘制所有单元格。另见Concepts: Editors and Renderers。如果您想保留有关“突出显示”单元格的信息,您必须以某种方式存储它们。
一个例子(基于 cmets 扩展):
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
public class CellRendererTest
public static void main(String[] args)
SwingUtilities.invokeLater(new Runnable()
@Override
public void run()
createAndShowGUI();
);
private static void createAndShowGUI()
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String[] columnNames =
"First Name", "Last Name", "Sport" ;
Object[][] data =
"Kathy", "Smith", "Snowboarding" ,
"John", "Doe", "Rowing" ,
"Sue", "Black", "Knitting",
"Jane", "White", "Speed reading",
"Joe", "Brown", "Pool"
;
final JTable table = new JTable(data, columnNames);
final ColoringCellRenderer cellRenderer = new ColoringCellRenderer();
TableColumnModel columnModel = table.getColumnModel();
int cc = columnModel.getColumnCount();
for (int c=0; c<cc; c++)
TableColumn column = columnModel.getColumn(c);
column.setCellRenderer(cellRenderer);
JScrollPane scrollPane = new JScrollPane(table);
f.getContentPane().setLayout(new BorderLayout());
f.getContentPane().add(scrollPane, BorderLayout.CENTER);
JButton addRandomColorButton = new JButton("Add random color");
addRandomColorButton.addActionListener(new ActionListener()
private Random random = new Random(0);
@Override
public void actionPerformed(ActionEvent e)
int rows = table.getRowCount();
int cols = table.getColumnCount();
int row = random.nextInt(rows);
int col = random.nextInt(cols);
int r = random.nextInt(255);
int g = random.nextInt(255);
int b = random.nextInt(255);
cellRenderer.setCellColor(row, col, new Color(r,g,b));
table.repaint();
);
f.getContentPane().add(addRandomColorButton, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
class ColoringCellRenderer extends DefaultTableCellRenderer
private final Map<Point, Color> cellColors = new HashMap<Point, Color>();
void setCellColor(int r, int c, Color color)
if (color == null)
cellColors.remove(new Point(r,c));
else
cellColors.put(new Point(r,c), color);
private Color getCellColor(int r, int c)
Color color = cellColors.get(new Point(r,c));
if (color == null)
return Color.WHITE;
return color;
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
Color color = getCellColor(row, column);
setBackground(color);
return this;
编辑:其余部分来自原始答案,仅使用单个单元格颜色。上面的新版本更完整(也更强大,因为它可以模拟单色渲染器),但为了完整起见,我将把它留在这里
这可以通过像这样的渲染器来实现:
class ColoringCellRenderer extends DefaultTableCellRenderer
private final Set<Point> highlightedCells = new HashSet<Point>();
void setHighlighted(int r, int c, boolean highlighted)
if (highlighted)
highlightedCells.add(new Point(r,c));
else
highlightedCells.remove(new Point(r,c));
private boolean isHighlighted(int r, int c)
return highlightedCells.contains(new Point(r,c));
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
if (isHighlighted(row, column))
setForeground(Color.BLACK);
setBackground(Color.RED);
else
setForeground(Color.BLACK);
setBackground(Color.WHITE);
return this;
然后您可以创建此渲染器的实例,并添加或删除要突出显示的单元格:
ColoringCellRenderer r = new ColoringCellRenderer();
// Assign renderer to table...
...
// Later, highlight cells:
r.setHighlighted(4,2,true);
r.setHighlighted(6,1,true);
r.setHighlighted(1,5,false);
...
如果您希望单元格的颜色不同,您可以将Set
替换为将特定Map
映射到特定的Point
(表示单元格的行/列)到Color
对象。
【讨论】:
谢谢..这正是我想要的..:) 你能否提供更多关于我如何用 2 种颜色制作它的信息...(我是这方面的初学者) @user3801896 我相应地扩展了答案 好的...我明白了..谢谢您的帮助:D @Marco13 不同意 (JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) 太费劲了,prepareRenderer 使用简单,逐个测试,改成JTables 视图应该是,必须包裹进 if (table.getRowCount > 0)
@mKorbel 不完全确定您的意思。可以覆盖此方法,但必须将单元格->颜色映射存储在某个地方(我更喜欢使用渲染器而不是子类化 JTable,但这可能是这里的一个细节......)【参考方案2】:
你需要在你想要的列上设置单元格渲染器。
如果您说希望第 2 行第 4 列 的单元格颜色为红色,则应将渲染器设置在第 4 列。您甚至可以在所有列上设置渲染器。
那么您所要做的就是对行进行 if-check。 IE。如果(行 == 4)。但我假设您将从 TestHotel.v 对象中获取您的值。
【讨论】:
但是如果我在特定列中设置让我们说数字 2 并且我第一次更改第 10 行中的单元格。如果下次我想更改第 2 列中的第 11 行我会松开以前的编辑...我认为.. 您只需要更新表 updateUI(),它应该尊重模型的任何更改。如果您的 TestHotl.v 中的值发生了变化,那么您应该会看到这些变化。以上是关于更改单元格颜色而不更改其他单元格中的颜色(Jtable)的主要内容,如果未能解决你的问题,请参考以下文章
AG-Grid:如何根据同一行中其他单元格中的值更改单元格的颜色