【问题标题】:Changing Cell Color without changing color in other cells (Jtable)更改单元格颜色而不更改其他单元格中的颜色(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 视图
  • 每次修改都会重新绘制表格。然后你需要保存所有你想改变颜色的单元格。

标签: java swing colors jtable tablecellrenderer


【解决方案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 中的值发生了变化,那么您应该会看到这些变化。
猜你喜欢
  • 2011-08-06
  • 2011-11-03
  • 2011-08-14
  • 2018-08-20
  • 2011-09-24
  • 2020-08-25
  • 1970-01-01
  • 2013-02-23
  • 2011-08-13
相关资源
最近更新 更多