0

I have a problem with a method that should change the color of one specific cell i a JTable, however all the cells change color.

This is the method I am trying to implement:

public Component cellBG(JTable table, int row, int column)
{
    TableCellRenderer renderer = table.getCellRenderer(row, column);
    Component c = table.prepareRenderer(renderer, row, column);

    Object steak = table.getValueAt(row,column);

    if(((String) steak).startsWith("+"))
    {
       c.setBackground(Color.GREEN);
    }
    else if(((String) steak).startsWith("-"))
    {
        c.setBackground(Color.RED);
    }
    else if(((String) steak).startsWith("~"))
    {
        c.setBackground(Color.YELLOW);
    }
    else if(((String) steak).equals(""))
    {
        c.setBackground(Color.WHITE);
    }

    return c;

}

my table contains 10 columns with 8 rows all containing either +, -, ~, or " ", which should result in a scattered pattern i different colors, however the tabel is colored solid in the last entri which is read.

Ass per request an SSCCE

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JFrame;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;

public class ptf_viewer extends JFrame {

    static JTable table;
    static DefaultTableModel model;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    ptf_viewer frame = new ptf_viewer();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }); 
    }

    public ptf_viewer(){
    getContentPane().setBackground(Color.WHITE);
    setTitle("Portable test file viewing");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(50, 50, 1024, 768);
    getContentPane().setLayout(null);

    final String[] columnNames = {"Test 1", "Test 2", "Test 3", "Test 4", "Test 5", "Test 6", "Test 7", "Test 8", "Test 9", "Test 10"};
    final Object[][] data = {
                {"+","+","","","","~","","","",""},
                {"-","+","","","","","","","",""},
                {"+","+","","","~","","","","",""},
                {"+","+","","","","","~","","",""},
                {"+","-","","~","","","","","",""},
                {"+","-","","","","","","","",""},
                {"+","-","","","","","","","",""},
                {"-","+","~","","","","","","","+"}
    };
    model = new DefaultTableModel(data, columnNames);
    table = new JTable(data, columnNames);
    table.setModel(model);
    for(int i = 0 ; i < 8 ; i++){
            cellBG(table, i, 9);
    }
    JTableHeader header = table.getTableHeader();
    header.setFont(new Font("Times New Roman", Font.BOLD, 13));
    header.setBackground(Color.black);
    header.setForeground(Color.white);

    JScrollPane scrollPane = new JScrollPane(table);
    scrollPane.setSize(988, 618);
    scrollPane.setFont(new Font("Times New Roman", Font.BOLD, 13));
    scrollPane.setLocation(10, 60);
    getContentPane().add(scrollPane);
    }
    public Component cellBG(JTable table, int row, int column)
    {
        TableCellRenderer renderer = table.getCellRenderer(row, column);
        Component c = table.prepareRenderer(renderer, row, column);

        Object bøf = table.getValueAt(row,column);

        if(((String) bøf).startsWith("+"))
        {
           c.setBackground(Color.GREEN);
        }
        else if(((String) bøf).startsWith("-"))
        {
            c.setBackground(Color.RED);
        }
        else if(((String) bøf).startsWith("~"))
        {
            c.setBackground(Color.YELLOW);
        }
        else if(((String) bøf).equals(""))
        {
            c.setBackground(Color.WHITE);
        }
        return c;
    }
    }
abbisDK
  • 35
  • 1
  • 1
  • 9
  • 1
    Looks like the renderer is shared by all the cells in your table. The last cell that is checked by the renderer will give the color to all the cells. – Jonathan Drapeau Jul 31 '13 at 11:41
  • 3
    for better help sooner post an [SSCCE](http://sscce.org/), short, runnable, compilable wtih hardocded value for JTable (contains 10 columns with 8 rows all containing either +, -, ~, or " ",), question how is possble that your prepareRenderer painting something – mKorbel Jul 31 '13 at 11:55
  • @JonathanDrapeau exact analysis. though not surprising, the renderer is designed to be shared :-) – kleopatra Jul 31 '13 at 12:19
  • SSCCE made and added to question – abbisDK Jul 31 '13 at 12:48

2 Answers2

3

abbisDK wrote - SSCCE made and added to question,

  • see by by using DefaultTableCellRenderer and Pattern.compile (one of variour ways, Strin.equals() or String.startWith, contains are another and quite easy)

  • the same, so very similair code could be used for prepareRenderer

.

table = new JTable(data, columnNames) {
   //logics place for prepareRenderer
};

enter image description here

from code

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.util.regex.Pattern;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;

public class Ptf_Viewer {

    private JFrame frame = new JFrame("Portable test file viewing");
    private JTable table;
    private final String[] columnNames = {"Test 1", "Test 2", "Test 3", "Test 4",
        "Test 5", "Test 6", "Test 7", "Test 8", "Test 9", "Test 10"};
    private final Object[][] data = {
        {"+", "+", "", "", "", "~", "", "", "", ""},
        {"-", "+", "", "", "", "", "", "", "", ""},
        {"+", "+", "", "", "~", "", "", "", "", ""},
        {"+", "+", "", "", "", "", "~", "", "", ""},
        {"+", "-", "", "~", "", "", "", "", "", ""},
        {"+", "-", "", "", "", "", "", "", "", ""},
        {"+", "-", "", "", "", "", "", "", "", ""},
        {"-", "+", "~", "", "", "", "", "", "", "+"}
    };
    private DefaultTableModel model = new DefaultTableModel(data, columnNames);

    public Ptf_Viewer() {
        table = new JTable(data, columnNames) {
            //logics place for prepareRenderer
        };
        table.setModel(model);
        table.setPreferredScrollableViewportSize(
                new Dimension(800, table.getPreferredSize().height));
        JTableHeader header = table.getTableHeader();
        header.setFont(new Font("Times New Roman", Font.BOLD, 13));
        header.setBackground(Color.black);
        header.setForeground(Color.white);
        for (int i = 0; i < table.getColumnCount(); i++) {
            RowColorRenderer rowRenderer = new RowColorRenderer(i);
            TableColumn column = table.getColumnModel().getColumn(i);
            column.setCellRenderer(rowRenderer);
        }
        JScrollPane scrollPane = new JScrollPane(table);
        scrollPane.setFont(new Font("Times New Roman", Font.BOLD, 13));
        frame.add(scrollPane);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(50, 50);
        frame.pack();
        frame.setVisible(true);
    }

    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("[+]").matcher(str).find())) {
                            setForeground(Color.magenta);
                            setBackground(Color.GREEN);
                            setFont(new Font("Serif", Font.BOLD, 16));
                            setHorizontalAlignment(CENTER);
                        } else if ((Pattern.compile("[-]").matcher(str).find())) {
                            setForeground(Color.blue);
                            setBackground(Color.RED);
                            setFont(new Font("Serif", Font.BOLD, 16));
                            setHorizontalAlignment(CENTER);
                        } else if ((Pattern.compile("[~]").matcher(str).find())) {
                            setForeground(Color.red);
                            setBackground(Color.YELLOW);
                            setFont(new Font("Serif", Font.BOLD, 16));
                            setHorizontalAlignment(CENTER);
                        } else {
                            setBackground(Color.WHITE);
                            setForeground(table.getForeground());
                            setFont(new Font("Serif", Font.PLAIN, 12));
                            setHorizontalAlignment(CENTER);
                        }
                    } else {
                        setBackground(Color.WHITE);
                        setForeground(table.getForeground());
                    }
                }
            }
            return this;
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                Ptf_Viewer frame = new Ptf_Viewer();
            }
        });
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • no need to grab the value from the table because: a) you get it as param b) super already has set it :-) – kleopatra Jul 31 '13 at 13:56
2

You will need to create your own cell renderer and have it return the proper background color depending on the text contained in the cell.

public class MyTableCellRenderer extends DefaultTableCellRenderer {
    @Override
    public Color getBackground() {
        String steak = getText();
        if (steak.startsWith("+")) {
            return Color.GREEN;
        } else if (steak.startsWith("-")) {
            return Color.RED;
        } else if (steak.startsWith("~")) {
            return Color.YELLOW;
        } else if (steak.equals("")) {
            return Color.WHITE;
        }

            return super.getBackground();
        }
    }
}

And make sure your table use it.

table.setDefaultRenderer(String.class, new MyTableCellRenderer());

Assuming here that type of all your cells is String.

Edit after SSCCE : The class is Obejct and not String, use

table.setDefaultRenderer(Object.class, new MyTableCellRenderer());
Jonathan Drapeau
  • 2,610
  • 2
  • 26
  • 32
  • 2
    beware: this will loose selection visuals – kleopatra Jul 31 '13 at 12:17
  • I tried to implement this, however it still does not Work, everthing is now White, I also tried to change from getBackground to setBackground, but nothing – abbisDK Jul 31 '13 at 12:25
  • @abbisDK Then provide a SSCCE. It should work but without all the code, it's impossible to help you more. – Jonathan Drapeau Jul 31 '13 at 12:31
  • SSCCE made and added to question – abbisDK Jul 31 '13 at 12:46
  • @abbisDK Shoud work with my latest edit, it does when I test it. – Jonathan Drapeau Jul 31 '13 at 12:53
  • doubt that you see the blue (in Metal f.i., it's LAF dependent) background if a row is selected, do you? @abbisDK While the renderer is the correct place for custom config, overriding the getter is suboptimal: it's highly brittle, as the coloring is unrelated to cell state (like focused, editable, alternate row coloring, dragging ... whatever the default deems necessary to colorize differently) – kleopatra Jul 31 '13 at 14:00
  • @kleopatra You're right, it does remove the selection background "marker". – Jonathan Drapeau Jul 31 '13 at 14:16