2

I have CustomTableCellRender

  
public class CustomCellRenderer extends JLabel implements TableCellRenderer {

    private TableCellRenderer defaultCellRenderer;

    public CustomCellRenderer(TableCellRenderer defaultCellRenderer) {
        this.defaultCellRenderer = defaultCellRenderer;
    }

    public Component getTableCellRendererComponent(JTable table, Object ovalue, boolean isSelected, boolean hasFocus, int row, int column) {
        String val = (String) ovalue;
        Component c = defaultCellRenderer.getTableCellRendererComponent(table, ovalue, isSelected, hasFocus, row, column);
        if (c != null) {
            if (val.equals("0h")) {
                c.setForeground(Color.RED);
            } else {
                c.setForeground(table.getForeground());
            }
            return c;
        } else return null;
    }
}
 

...

 

            TableCellRenderer renderer = new CustomCellRenderer(sumTable.getDefaultRenderer(columnModel.getColumn(i).getClass()));
            columnModel.getColumn(i).setCellRenderer(renderer);

 

and it worked normal util I need change cell Background Color it sets Color not in certain cells and in all column, all cells.


...
            if (val.equals("0h")) {
                c.setBackground(Color.GRAY);
            } else {
                c.setForeground(table.getForeground());
            }
...

What do I need to do?

mKorbel
  • 109,525
  • 20
  • 134
  • 319
guzick
  • 23
  • 1
  • 3

3 Answers3

3

The reason is (as often) the infamous color memory of the DefaultTableCellRenderer, as described in a recent answer

The problem in your particular context is that you use the same instance of the renderer as delegate and as default renderer elsewhere. Easiest solution is to use 2 different instances (after all, you know which type of renderers are installed by default).

Most simple solution for custom coloring (or other visual decorations of cells), is to use SwingX with its consistent configuration support for rendering components.

Community
  • 1
  • 1
kleopatra
  • 51,061
  • 28
  • 99
  • 211
2

In your else statement, you need to set your background back to something. E.g. :
c.setBackground(Color.WHITE);

2

What do I need to do?

public Component getTableCellRendererComponent(
    JTable table, Object ovalue, boolean isSelected, 
    boolean hasFocus, int row, int column) {
  • has two parameters int row and int column use these two coordinates in the JTable matrix,

  • have to accepting and don't forger that all(???) Arrays in Java started with zero

  • (0, 0) is first column in the first row

EDIT

one of ways

import java.awt.*;
import java.util.Vector;
import java.util.regex.Pattern;
import javax.swing.*;
import javax.swing.table.*;

public class HiglightNumberValueInTableCell {

    private String testS;
    private JFrame frame = new JFrame("frameTitle");
    private JScrollPane tblS = new JScrollPane();
    private JTable tbl;
    private Vector<String> rOrH;
    private long t1 = 0L;
    private long t2 = 0L;

    public HiglightNumberValueInTableCell() {
        t1 = System.currentTimeMillis();
        int regLenght = 25000;
        int chars = 0;
        AlphaChars aChars = new AlphaChars();
        testS = aChars.getNext(regLenght);
        rOrH = new Vector<String>();
        Vector<Vector<String>> rowD = new Vector<Vector<String>>();
        for (int e = 0; e < regLenght;) {
            chars++;
            //if (chars > 50) { //one char in table cell
            if (chars > 20) {
                chars = 1;
                rowD.add(rOrH);
                rOrH = new Vector<String>();
            }
            //String str = (testS.substring(e, (e + 1))).toString();//one char in table cell
            String str = (testS.substring(e, (e + 5))).toString();
            if (str != null) {
                rOrH.add(str);
            } else {
                rOrH.add("");
            }
            //e++;//one char in table cell
            e += 5;
        }
        rOrH = new Vector<String>();
        //for (int i = 0; i < 50; i++) {//one char in table cell
        for (int i = 0; i < 20; i++) {
            rOrH.add(String.valueOf(i + 1));
        }
        tbl = new JTable(rowD, rOrH);
        tblS = new JScrollPane(tbl, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        tblS.setPreferredSize(new Dimension(1000, 403));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(tblS, BorderLayout.CENTER);
        frame.setLocation(50, 50);
        frame.pack();
        addColumnRenderes();
    }

    private void addColumnRenderes() {
        for (int i = 0; i < tbl.getColumnCount(); i++) {
            RowColorRenderer rowRenderer = new RowColorRenderer(i);
            TableColumn column = tbl.getColumnModel().getColumn(i);
            column.setCellRenderer(rowRenderer);
        }
        Runnable doRun = new Runnable() {

            @Override
            public void run() {
                showFrame();
            }
        };
        SwingUtilities.invokeLater(doRun);
    }

    private void showFrame() {
        Runnable doRun = new Runnable() {

            @Override
            public void run() {
                frame.setVisible(true);
                t2 = System.currentTimeMillis();
                System.out.println("miliSec:" + (t2 - t1)); //aver. 45 miliSec.
            }
        };
        SwingUtilities.invokeLater(doRun);
    }

    private class RowColorRenderer extends DefaultTableCellRenderer {

        private static final long serialVersionUID = 1L;
        private int colNo = 0;

        RowColorRenderer(int col) {
            colNo = col;
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value,
                boolean isSelected, boolean hasFocus, int row, int column) {
            Component comp = super.getTableCellRendererComponent(table, value,
                    isSelected, hasFocus, row, column);
            JComponent jc = (JComponent) comp;
            if (!isSelected) {
                if (table.getValueAt(row, colNo) != null) {
                    String str = table.getValueAt(row, colNo).toString();
                    if (!str.isEmpty()) {
                        if (Pattern.compile("\\d").matcher(str).find()) {
                            if (((Pattern.compile("[02468]").matcher(str).find()))
                                    && (!(Pattern.compile("[13579]").matcher(str).find()))) {
                                setForeground(Color.magenta);
                                setBackground(Color.orange);
                            } else if ((!(Pattern.compile("[02468]").matcher(str).find()))
                                    && ((Pattern.compile("[13579]").matcher(str).find()))) {
                                setForeground(Color.blue);
                                setBackground(Color.yellow);
                            } else if (((Pattern.compile("[02468]").matcher(str).find()))
                                    && ((Pattern.compile("[13579]").matcher(str).find()))) {
                                setForeground(Color.red);
                                setBackground(Color.cyan);
                            }
                            setFont(new Font("Serif", Font.BOLD, 12));
                            setHorizontalAlignment(CENTER);
                        } else {
                            setBackground(table.getBackground());
                            setForeground(table.getForeground());
                            setFont(new Font("Serif", Font.PLAIN, 8));
                            setHorizontalAlignment(CENTER);
                        }
                    }
                }
            }
            return this;
        }
    }

    private class AlphaChars {

        public static final int MIN_LENGTH = 2000;
        private java.util.Random rand = new java.util.Random();
        private char[] AlphaChars = {
            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
            'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
            'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
            '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '+', '-', '*', '/', '<', '>', '&',
            '#', '@', '{', '}', '?', ':', '_', '"', '!', ')', '('};

        public String getNext() {
            StringBuilder strbuf = new StringBuilder();
            for (int i = 0; i < MIN_LENGTH; i++) {
                strbuf.append(getAlphaChars()[getRand().nextInt(getAlphaChars().length)]);
            }
            return strbuf.toString();
        }

        public String getNext(int reqLenght) {
            StringBuilder strbuf = new StringBuilder();
            for (int i = 0; i < reqLenght; i++) {
                strbuf.append(getAlphaChars()[getRand().nextInt(getAlphaChars().length)]);
            }
            return strbuf.toString();
        }

        public java.util.Random getRand() {
            return rand;
        }

        public void setRand(java.util.Random aRand) {
            rand = aRand;
        }

        public char[] getAlphaChars() {
            return AlphaChars;
        }

        public void setAlphaChars(char[] aAlphaChars) {
            AlphaChars = aAlphaChars;
        }
    }

    public static void main(String args[]) {
        HiglightNumberValueInTableCell hnvit = new HiglightNumberValueInTableCell();
    }
}
Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • I need to change background color in cell, where was written "0h", but I get ALL cells with background color GRAY. I remember, that arrays in java start with zero, but how this helps me? – guzick Aug 24 '12 at 11:33
  • Ok. I can use getTableCellRender, but what do I need to put in parametr Object? – guzick Aug 24 '12 at 11:41
  • [Object](http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#editrender) – mKorbel Aug 24 '12 at 11:44
  • @trashgod that's not a good option in this context as it requires to subclass the table: hooking there is appropriate for some framework-style decoration (like f.i. done in SwingX) or effects that should be applied across all types of rendering components or for a complete row. For per-value decorations, doing so in a custom renderer is the way to go – kleopatra Aug 24 '12 at 11:53
  • @kleopatra I thing not true, this is advantage of prepareRenderer, that not causing effect described in your answer +1 (Robs answer to Jerome jduprez, I have only the code not url reference to OTN) – mKorbel Aug 24 '12 at 12:00
  • the color memory is the same, independ of where you decorate. Though, thinking about it, in this context it might be true: the reason for its appearance is that while using "elsewhere" it's not resetted. Anyway, biased me would always recommend to not re-invent the wheel, simply use SwingX rendering support and you'll never again have to worry about that crappy default implementation :-) – kleopatra Aug 24 '12 at 12:07
  • @kleopatra yes, agreed with SwingX and Gob bless you for this great job :-), – mKorbel Aug 24 '12 at 12:10