Results 1 to 10 of 10
  1. #1
    mine0926 is offline Senior Member
    Join Date
    Apr 2010
    Location
    Philippines
    Posts
    580
    Rep Power
    5

    Default CellRenderer, change background color per row

    Hi, I would like to change JTable's background color per row and the other row's color will not change. I created a SSCCE to describe my problem, in this program user will input the row that he want to change then that row will change its background color, that part is ok, but when user input another row the background color of the first input row change to white.

    Java Code:
    [B][U]FrmMain[/U][/B]
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTable;
    import javax.swing.JTextField;
    import javax.swing.JLabel;
    import javax.swing.JTable;
    import javax.swing.table.TableCellRenderer;
    
    public class FrmMain extends JFrame
    {
        private JPanel pnlMain;
        private JPanel pnlForTable;
        private JPanel pnlForButton;
        private JTable aTable;
        private JButton aButton;
        private JTextField aText;
        public FrmMain()
        {
            initComponents();
            designTable();
        }
    
        private void initComponents()
        {
            setLayout(new GridLayout());
            pnlMain = new JPanel(new BorderLayout());
            pnlForButton = new JPanel(new GridLayout(0,5));
            pnlForTable = new JPanel(new GridLayout());
            aButton = new JButton("Apply Diff. Colors");
            aButton.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {
                    btnActionPerFormed(e);
                }
            });
            aText = new JTextField(5);
    
            Object[][] tableData = { {"ROW=0:COL=0", "ROW=0:COL=1", "ROW=0:COL=2"},
            {"ROW=1:COL=0", "ROW=1:COL=1", "ROW=1:COL=2"},
            {"ROW=2:COL=0", "ROW=2:COL=1", "ROW=2:COL=2"},
            {"ROW=3:COL=0", "ROW=3:COL=1", "ROW=3:COL=2"},
            {"ROW=4:COL=0", "ROW=4:COL=1", "ROW=4:COL=2"}};
            Object[] tableHeader = {"FIELD 1", "FIELD 2", "FIELD 3"};
            aTable = new JTable(tableData, tableHeader);
    
            add(pnlMain);
    
            pnlMain.add(pnlForButton, BorderLayout.BEFORE_FIRST_LINE);
            pnlMain.add(pnlForTable, BorderLayout.CENTER);
    
            pnlForButton.add(aButton);
            pnlForButton.add(aText);
    
            pnlForTable.add(aTable);
    
            pack();
        }
    
        private void designTable()
        {
            RowRenderer CELL_RENDERER = new RowRenderer();
    
            for(int i = 0; i < aTable.getColumnCount(); i++)
            {
                aTable.getColumn(aTable.getColumnName(i))
                        .setCellRenderer(CELL_RENDERER);
            }
        }
    
        private void btnActionPerFormed(ActionEvent ae)
        {   [B]
            Color newRowColor = new Color(255,0,0);
            ((RowRenderer)aTable.getCellRenderer(Integer.parseInt(aText.getText()), 0)).setLabelBackground(
                    newRowColor, Integer.parseInt(aText.getText()), 0, aTable);
            aTable.revalidate();
            aTable.repaint();[/B]
        }
    
        public static void main(String[] args)
        {
            FrmMain main = new FrmMain();
            main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            main.setVisible(true);
        }
    
    
    
    [B][U]RowRenderer[/U][/B]
        protected class RowRenderer implements TableCellRenderer
        {
            private JLabel renderLabel;
            private String text;
            private int currentRow;
            private Color color;
    
            public RowRenderer()
            {
                renderLabel = new JLabel();
                renderLabel.setOpaque(true);
            }
    
            public Component getTableCellRendererComponent(JTable table, Object value,
                    boolean isSelected, boolean hasFocus, int row, int column)
            {
                text = (value == null) ? "0.00" : value.toString();
    
                if(row == currentRow)
                {
                    renderLabel.setBackground(color);
                }
                else
                {
        //            if(renderLabel.getBackground() == color)
        //            {
        //                renderLabel.setBackground(renderLabel.getBackground());
        //            }
        //            else
        //            {
                        renderLabel.setBackground(Color.WHITE);
        //            }
                }
                renderLabel.setText(text);
                return renderLabel;
            }
    
            public void setLabelBackground(Color color, int row, int col, JTable table)
            {
                if(color != null)
                {
                    System.out.println("FROM setLabel");
                    currentRow = row;
                    this.color = color;
                    this.getTableCellRendererComponent(table,
                            table.getValueAt(row, col), false, false,
                            row, col);
                }
            }
        }
    }
    Thanks in advance.

  2. #2
    Junky's Avatar
    Junky is offline Grand Poobah
    Join Date
    Jan 2011
    Location
    Dystopia
    Posts
    3,798
    Rep Power
    7

    Default

    Java Code:
    renderLabel.setBackground(Color.WHITE);
    It seems that the above line (which is the only uncommented line in the else branch of the getTableCellRendererComponent method) is being executed. Maybe you need to rethink your design.

  3. #3
    mine0926 is offline Senior Member
    Join Date
    Apr 2010
    Location
    Philippines
    Posts
    580
    Rep Power
    5

    Default

    But when I remove else statement, all rows became color red, because renderLabel is color red.
    Java Code:
            if(row == currentRow)
            {
                renderLabel.setBackground(color);
                System.out.println("INSIDE IF (ROW=" + row + ":COL=" + column
                        + "): " + renderLabel.getBackground());
            }
    //        else
    //        {
    //            if(renderLabel.getBackground() == color)
    //            {
    //                renderLabel.setBackground(renderLabel.getBackground());
    //            }
    //            else
    //            {
    //                renderLabel.setBackground(Color.WHITE);
    //            }
    //        }

  4. #4
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,423
    Rep Power
    20

    Default

    Don't reinvent the wheel. DefaultTableCellRenderer already extends JLabel, and incorporates features for optimization (read the documentation).
    Java Code:
    import java.awt.*;
    import javax.swing.*;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
    import javax.swing.table.DefaultTableCellRenderer;
    
    public class RowHighlightTable {
    
      public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
    
          public void run() {
            new RowHighlightTable().makeUI();
          }
        });
      }
    
      public void makeUI() {
        final JTable table = new JTable(20, 3) {
    
          @Override
          public Object getValueAt(int row, int column) {
            return "Row " + row + "Column" + column;
          }
        };
        final RowHighlightRenderer renderer = new RowHighlightRenderer();
        table.setDefaultRenderer(Object.class, renderer);
    
        final SpinnerModel model = new SpinnerNumberModel(-1, -1, table.getRowCount(), 1);
        final JSpinner spinner = new JSpinner(model);
        spinner.addChangeListener(new ChangeListener() {
    
          public void stateChanged(ChangeEvent e) {
            renderer.setHighlightRow((Integer) model.getValue());
            table.repaint();
          }
        });
    
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(table), BorderLayout.CENTER);
        frame.add(spinner, BorderLayout.SOUTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 400);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
      }
    }
    
    class RowHighlightRenderer extends DefaultTableCellRenderer {
    
      private int highlightRow = -1;
      private static final Color HIGHLIGHT = Color.RED;
    
      @Override
      public Component getTableCellRendererComponent(JTable table, Object value,
              boolean isSelected, boolean hasFocus, int row, int column) {
        super.getTableCellRendererComponent(table, value,
                isSelected, hasFocus, row, column);
        setBackground(row == highlightRow
                ? HIGHLIGHT
                : isSelected
                ? table.getSelectionBackground()
                : table.getBackground());
        return this;
      }
    
      public void setHighlightRow(int rowToHighlight) {
        highlightRow = rowToHighlight;
      }
    }
    db

  5. #5
    mine0926 is offline Senior Member
    Join Date
    Apr 2010
    Location
    Philippines
    Posts
    580
    Rep Power
    5

    Default

    What I am trying to do is not to change the background color of the past selected row.

    When user enter row 1, then row 1 should change its background color to red
    Then user enter row 5, I wouild like row 1 and 5 to be color red.

  6. #6
    mine0926 is offline Senior Member
    Join Date
    Apr 2010
    Location
    Philippines
    Posts
    580
    Rep Power
    5

    Default

    Hi, I am still working with it :-(
    I was thinking of
    * getting the current background color of that "cell" or "row" so that I could check if its background color is already red or not. Just to try I did something like
    Java Code:
            Component cell = super.getTableCellRendererComponent(table, value,
                    isSelected, hasFocus, row, 0+1);
            System.out.println("ROW=" + row + ":COL=" + column + "\t" + cell.getBackground());
    but cell.getBackground() returns the lasest/last color I set - If I set Row#1 to red background color, Row#2 background color return color red too though it is color white

    * Second thing that I am thinking is to pass an array which holds the row that is color red. Have not yet do this but I will post back what happen


    This is the latest code of RowRenderer class
    Java Code:
    protected class RowRenderer extends DefaultTableCellRenderer //implements TableCellRenderer
    {
        private String text;
        private int currentRow;
        private Color color;
    
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value,
                boolean isSelected, boolean hasFocus, int row, int column)
        {
            Component cell = super.getTableCellRendererComponent(table, value,
                    isSelected, hasFocus, row, 0+1);
            System.out.println("ROW=" + row + ":\t" + cell.getBackground());
    
            text = (value == null) ? "0.00" : value.toString();
    
    
            if(row == currentRow)
            {
                setBackground(color);
    //            System.out.println("IF (ROW=" + row + ":COL=" + column + "): "
    //                    + getBackground());
            }
            else
            {
    //            System.out.println("ELSE (ROW=" + row + ":COL=" + column + "): "
    //                    + cell.getBackground() + ":" + color);
                if(cell.getBackground() == color)
                {
                    setBackground(getBackground());
                }
                else
                {
                    setBackground(Color.WHITE);
                }
            }
            setText(text);
            return this;
        }
    
        public void setLabelBackground(Color color, int row, int col)
        {
            if(color != null)
            {
                System.out.println("FROM setLabel");
                currentRow = row;
                this.color = color;
            }
        }
    }
    @DB - thanks for correcting me. :)

  7. #7
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,423
    Rep Power
    20

    Default

    Minor changes. You really should have been able to do this yourself.
    Java Code:
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.HashSet;
    import java.util.Set;
    import javax.swing.*;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
    import javax.swing.table.DefaultTableCellRenderer;
    
    public class RowHighlightTable {
    
      private static final String ADD_ROW = "Add Row";
    
      public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
    
          public void run() {
            new RowHighlightTable().makeUI();
          }
        });
      }
    
      public void makeUI() {
        final JTable table = new JTable(20, 3) {
    
          @Override
          public Object getValueAt(int row, int column) {
            return "Row " + row + "Column" + column;
          }
        };
        final RowHighlightRenderer renderer = new RowHighlightRenderer();
        table.setDefaultRenderer(Object.class, renderer);
    
        final SpinnerModel model = new SpinnerNumberModel(0, 0, table.getRowCount() - 1, 1);
        JSpinner spinner = new JSpinner(model);
        final JButton button = new JButton(ADD_ROW);
        spinner.addChangeListener(new ChangeListener() {
    
          public void stateChanged(ChangeEvent e) {
            button.setText(renderer.isHighlighted((Integer) model.getValue())
                    ? "Remove Row"
                    : ADD_ROW);
          }
        });
        button.addActionListener(new ActionListener() {
    
          public void actionPerformed(ActionEvent e) {
            renderer.setHighlighted((Integer) model.getValue(),
                    button.getText().equals(ADD_ROW));
            table.repaint();
          }
        });
        JPanel panel = new JPanel(new GridLayout(1, 2));
        panel.add(spinner);
        panel.add(button);
    
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(table), BorderLayout.CENTER);
        frame.add(panel, BorderLayout.SOUTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 400);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
      }
    }
    
    class RowHighlightRenderer extends DefaultTableCellRenderer {
    
      Set<Integer> highlightedRows = new HashSet<Integer>();
      private static final Color HIGHLIGHT = Color.RED;
    
      @Override
      public Component getTableCellRendererComponent(JTable table, Object value,
              boolean isSelected, boolean hasFocus, int row, int column) {
        super.getTableCellRendererComponent(table, value,
                isSelected, hasFocus, row, column);
        setBackground(highlightedRows.contains(row)
                ? HIGHLIGHT
                : isSelected
                ? table.getSelectionBackground()
                : table.getBackground());
        return this;
      }
    
      public void setHighlighted(Integer row, boolean set) {
        if (set) {
          highlightedRows.add(row);
        } else {
          highlightedRows.remove(row);
        }
      }
    
      public boolean isHighlighted(Integer row) {
        return highlightedRows.contains(row);
      }
    }
    db

  8. #8
    mine0926 is offline Senior Member
    Join Date
    Apr 2010
    Location
    Philippines
    Posts
    580
    Rep Power
    5

    Default

    Hi, I was able to do it, I use ArrayList<Integer>. I think HashSet is better than ArrayList.

    Thanks

  9. #9
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,423
    Rep Power
    20

    Default

    If you use an ArrayList, you have to check that the same Integer isn't repeatedly added. A Set does that for you.

    db

  10. #10
    mine0926 is offline Senior Member
    Join Date
    Apr 2010
    Location
    Philippines
    Posts
    580
    Rep Power
    5

Similar Threads

  1. Change JPanel background color
    By snaquetime in forum AWT / Swing
    Replies: 5
    Last Post: 06-04-2011, 11:03 PM
  2. Change BufferedImage background color
    By Nosrettap in forum New To Java
    Replies: 0
    Last Post: 03-20-2011, 11:29 PM
  3. Replies: 4
    Last Post: 03-21-2009, 05:48 PM
  4. my code doesn't change background color
    By javanoobita in forum New To Java
    Replies: 5
    Last Post: 02-22-2009, 04:30 AM
  5. JButton onClick change color background
    By behrk2 in forum AWT / Swing
    Replies: 6
    Last Post: 07-09-2008, 04:54 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •