简体   繁体   English

Look&Feel忽略自定义TableCellRenderer

[英]Custom TableCellRenderer ignored by Look&Feel

I have a JTable for which I have provided a custom TableCellRenderer that colors numeric cells in red/gray/green depending on their value (<0, 0, >0). 我有一个JTable,我提供了一个自定义TableCellRenderer,根据它们的值(<0,0,> 0)为红色/灰色/绿色的数字单元着色。

However, when I use the Nimbus L&F, the label.setForeground() method is ignored: when calling label.getForeground() I can see that the number has the right color, for example red, but on the screen it comes black. 但是,当我使用Nimbus L&F时,将忽略label.setForeground()方法:当调用label.getForeground()我可以看到该数字具有正确的颜色,例如红色,但在屏幕上它label.getForeground()黑色。 If I remove the L&F it works fine. 如果我删除L&F它工作正常。

Is there a way to gently ask the L&F to accept using my color for that cell? 有没有办法轻轻地要求L&F接受使用我的颜色为那个细胞?

ps: I know that the javadoc of setForeground() is clear about the fact that the L&F might ignore the call, so I'm looking for a workaround. ps:我知道setForeground()javadoc清楚L&F可能忽略了这个调用,所以我正在寻找一个解决方法。

在此输入图像描述

import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;

public class TablePrepareRenderer extends JFrame {

    private static final long serialVersionUID = 1L;
    private JTable table;

    public TablePrepareRenderer() {
        Object[] columnNames = {"Type", "Company", "Shares", "Price", "Boolean"};
        Object[][] data = {
            {"Buy", "IBM", new Integer(1000), new Double(80.50), false},
            {"Sell", "MicroSoft", new Integer(2000), new Double(6.25), true},
            {"Sell", "Apple", new Integer(3000), new Double(7.35), true},
            {"Buy", "Nortel", new Integer(4000), new Double(20.00), false}
        };
        DefaultTableModel model = new DefaultTableModel(data, columnNames) {

            private static final long serialVersionUID = 1L;

            @Override
            public Class getColumnClass(int column) {
                return getValueAt(0, column).getClass();
            }
            /*@Override
            public Class getColumnClass(int column) {
            switch (column) {
            case 0:
            return String.class;
            case 1:
            return String.class;
            case 2:
            return Integer.class;
            case 3:
            return Double.class;
            default:
            return Boolean.class;
            }
            }*/
        };
        table = new JTable(model) {

            private static final long serialVersionUID = 1L;

            @Override
            public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
                Component c = super.prepareRenderer(renderer, row, column);
                int firstRow = 0;
                int lastRow = table.getRowCount() - 1;
                if (row == lastRow) {
                    ((JComponent) c).setBackground(Color.red);
                } else if (row == firstRow) {
                    ((JComponent) c).setBackground(Color.blue);
                } else {
                    ((JComponent) c).setBackground(table.getBackground());
                }
                return c;
            }
        };
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane scrollPane = new JScrollPane(table);
        getContentPane().add(scrollPane);
    }
    /*private static String[] suffix = new String[]{"", "k", "m", "b", "t"};
    private static int MAX_LENGTH = 4;

    private static String format(double number) {
    String r = new DecimalFormat("##0E0").format(number);
    r = r.replaceAll("E[0-9]", suffix[Character.getNumericValue(r.charAt(r.length() - 1)) / 3]);
    return r.length() > MAX_LENGTH ? r.replaceAll("\\.[0-9]+", "") : r;
    }*/

    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (Exception fail) {
        }
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                TablePrepareRenderer frame = new TablePrepareRenderer();
                frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
        /*long[] numbers = new long[]{1000, 5821, 10500, 101800, 2000000, 7800000, 92150000, 123200000, 99999900};
        for (long number : numbers) {
        System.out.println(number + " = " + format(number));
        }*/
    }
}

Ok, thanks to mKorbel's answer , I realised that I was using ColorUIResource instead of Color . 好的,多亏了mKorbel的回答 ,我意识到我使用的是ColorUIResource而不是Color In other words: 换一种说法:

label.setForeground(Color.red); //works
label.setForeground(new ColorUIResource(Color.red)); //doesn't work

I'm not sure I understand why one works and not the other ( Color is the direct superclass of ColorUIResource ), but problem solved. 我不确定我理解为什么一个工作而不是另一个( ColorColorUIResource的直接超类),但问题解决了。

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

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