简体   繁体   English

更改JTable的特定单元格中的字体颜色?

[英]Change the font color in a specific cell of a JTable?

Before starting, I've viewed a handful of solutions as well as documentation. 在开始之前,我已经查看了一些解决方案和文档。 I can't seem to figure out why my code isn't working the way I believe it should work. 我似乎无法弄清楚为什么我的代码无法按照我认为的方式工作。 I've extended DefaultTableCellRenderer but I don't believe it is being applied - that or I messed things up somewhere. 我已经扩展了DefaultTableCellRenderer,但是我不相信它正在被应用-否则我会将事情弄乱了。

Here are the threads / websites I've looked into before posting this question: 以下是发布此问题之前我调查过的主题/网站:

I realize the first link uses HTML to change the font color, but I would think the way I went about it should produce the same result. 我意识到第一个链接使用HTML来更改字体颜色,但是我认为我的处理方式应该会产生相同的结果。

To make it easier on those who want to help me figure out the issues, I've created an SSCCE. 为了使那些想帮助我解决问题的人更轻松,我创建了一个SSCCE。

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;


public class TableTest {

    private static final int IMPORTANT_COLUMN = 2;

    public static void createAndShowGUI() {
        Object[][] data = new Object[2][4];
        //create sample data
        String[] realRowData = { "1", "One", "1.0.2", "compile" };
        String[] fakeRowData = { "2", "Two", "1.3.2-FAKE", "compile" };
        //populate sample data
        for(int i = 0; i < realRowData.length; i++) {
            data[0][i] = realRowData[i];
            data[1][i] = fakeRowData[i];
        }

        //set up tableModel
        JTable table = new JTable();
        table.setModel(new DefaultTableModel(data, 
                new String[] { "ID #", "Group #", "version", "Action" }) 

            {
                Class[] types = new Class[] {
                    Integer.class, String.class, String.class, String.class
                };

                boolean[] editable = new boolean[] {
                    false, false, true, false  
                };

                @Override
                public Class getColumnClass(int columnIndex) {
                    return types[columnIndex];
                }

                @Override
                public boolean isCellEditable(int rowIndex, int columnIndex) {
                    return editable[columnIndex];
                }
            });

        //set custom renderer on table
        table.setDefaultRenderer(String.class, new CustomTableRenderer());

        //create frame to place table
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setMinimumSize(new Dimension(400, 400));
        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setViewportView(table);
        f.add(scrollPane);
        f.pack();
        f.setVisible(true);

    }

    //MAIN
    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                createAndShowGUI();
            }
        });
    }

    //Custom DefaultTableCellRenderer
    public static class CustomTableRenderer extends DefaultTableCellRenderer {
        public Component getTableCellRenderer(JTable table, Object value,
                boolean isSelected, boolean hasFocus, int row, int column)
        {
            Component c = super.getTableCellRendererComponent(table, value, isSelected,
                    hasFocus, row, column);

            String versionVal = table.getValueAt(row, IMPORTANT_COLUMN).toString();

            if(versionVal.contains("FAKE")) {
                //set to red bold font
                c.setForeground(Color.RED);
                c.setFont(new Font("Dialog", Font.BOLD, 12));
            } else {
                //stay at default
                c.setForeground(Color.BLACK);
                c.setFont(new Font("Dialog", Font.PLAIN, 12));
            }
            return c;
        }

    }
}

My goal is to highlight any value in the version column that contains the word FAKE in a red bold text. 我的目标是突出显示版本栏中包含红色粗体字FAKE所有值。

I've extended DefaultTableCellRenderer but I don't believe it is being applied 我已经扩展了DefaultTableCellRenderer,但是我不相信它已被应用

Some simple debugging tips: 一些简单的调试技巧:

  1. Add a simple System.out.println(...) to the method you think should be invoked 将简单的System.out.println(...)添加到您认为应调用的方法中
  2. When overriding a method, make sure you use the @Override annotation (you used it in the TableModel class, but not your renderer class). 覆盖方法时,请确保使用@Override批注(在TableModel类中使用了它,但在渲染器类中没有使用过)。

Your problem is a typing mistake because you are not overriding the proper method: 您的问题是键入错误,因为您没有覆盖正确的方法:

    @Override
    // public Component getTableCellRenderer(...) // this is wrong
    public Component getTableCellRendererComponent(...)

The override annotation will display a compile message. 覆盖注释将显示一条编译消息。 Try it before changing the code. 在更改代码之前尝试一下。

Also, your first column is NOT an Integer class. 同样,您的第一列也不是Integer类。 Just because it contains String representations of an Integer does not make it an Integer. 仅因为它包含整数的字符串表示形式,并不会使它成为整数。 You need to add an Integer object to the model. 您需要向模型添加一个Integer对象。

Replace your custom table cell rendere with the below. 将您的自定义表格单元格rendere替换为以下内容。

Explanations are in comments. 解释在注释中。 Basically, you should override getTableCellRendererComponent then check for correct column (there may be other methods instead of checking header value), then set cell depending on color. 基本上,您应该重写getTableCellRendererComponent然后检查是否有正确的列(可能有其他方法代替检查标题值),然后根据颜色设置单元格。

Do not forget last else block to set color to default if it is not the column you want. 如果不是您想要的列,请不要忘记将last else块设置为默认颜色。

//Custom DefaultTableCellRenderer
public static class CustomTableRenderer extends DefaultTableCellRenderer {

    // You should override getTableCellRendererComponent
    @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);

        // Check the column name, if it is "version"
        if (table.getColumnName(column).compareToIgnoreCase("version") == 0) {
            // You know version column includes string
            String versionVal = (String) value;

            if (versionVal.contains("FAKE")) {
                //set to red bold font
                c.setForeground(Color.RED);
                c.setFont(new Font("Dialog", Font.BOLD, 12));
            } else {
                //stay at default
                c.setForeground(Color.BLACK);
                c.setFont(new Font("Dialog", Font.PLAIN, 12));
            }
        } else {
            // Here you should also stay at default
            //stay at default
            c.setForeground(Color.BLACK);
            c.setFont(new Font("Dialog", Font.PLAIN, 12));
        }
        return c;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM