Results 1 to 9 of 9
Like Tree1Likes
  • 1 Post By DarrylBurke

Thread: Need guidance on how to change colour of a row in JTable.

  1. #1
    rhexis is offline Member
    Join Date
    Nov 2011
    Posts
    56
    Rep Power
    0

    Default Need guidance on how to change colour of a row in JTable.

    My code is awfully long, so I'll just try to keep it short.

    Basically, my code is running a for loop to generate a table. For every 1 round in the loop, it will generate 4 rows, which means if the loop is 3 times, there will be 12 rows all together.

    One of the column in the row is called Change

    The final step of my program is such that it will check every 4 rows, and if the Change for all 4 rows is false, it will set the row colour to RED.

    I'm lost at how to perform this task. I've been reading up on CellRenderer and all, and have downloaded several different programs to test, but all to no avail, probably because I have been coding for the past 8 hours as well, so any kind of help is GREATLY appreciated.

    As always, I of course do not wish to get the entire piece of code, just a little guidance on how I should start.

    Java Code:
    
    model = new DefaultTableModel(data, columnNames);
    table = new JTable(model);
    
    table.setDefaultRenderer(String.class, new CustomRenderer());
    
    			
    ...
    ...
    for (int i = 0; i < epochs; i++) {
    				changeArrayList = new ArrayList<Boolean>();
    				change = false;
    				Object[] newRow = new Object[16];
    				newRow[0] = model.getRowCount();
    				int epochCount = i + 1;
    				for (int j = 0; j < 4; j++) {
    
    					newRow[1] = epochCount;
    					newRow[2] = biasInput;
    					newRow[3] = biasWeight;
    					newRow[4] = wa;
    					newRow[5] = wb;
    					newRow[6] = inputA.get(j);
    					newRow[7] = inputB.get(j);
    
    					net = biasInput * biasWeight + (Integer) inputA.get(j) * wa
    							+ (Integer) inputB.get(j) * wb;
    					net = Math.round(net * 100) / 100.0d;
    
    					newRow[8] = net;
    
    					if (net < ifCondition) {
    						activation = thenCondition;
    					} else {
    						activation = elseCondition;
    					}
    
    					error = (Integer) target.get(j) - activation;
    
    					newRow[9] = target.get(j);
    					newRow[10] = activation;
    					newRow[11] = error;
    
    					weightChangeA = learningRate * error
    							* (Integer) inputA.get(j);
    					weightChangeB = learningRate * error
    							* (Integer) inputB.get(j);
    					biasWeightChange = learningRate * error * biasInput;
    
    					if (weightChangeA != 0 || weightChangeB != 0
    							|| biasWeightChange != 0) {
    						change = true;
    						wa = wa + weightChangeA;
    						wa = Math.round(wa * 100) / 100.0d;
    						wb = wb + weightChangeB;
    						wb = Math.round(wb * 100) / 100.0d;
    						biasWeight = biasWeight + biasWeightChange;
    						biasWeight = Math.round(biasWeight * 100) / 100.0d;
    						newRow[12] = weightChangeA;
    						newRow[13] = weightChangeB;
    						newRow[14] = biasWeightChange;
    					} else {
    						change = false;
    						newRow[12] = 0;
    						newRow[13] = 0;
    						newRow[14] = 0;
    					}
    
    					newRow[15] = change;
    
    					changeArrayList.add(j, change);
    
    					if (changeArrayList.size() == 4) {
    						System.out.println(changeArrayList.get(0) + ","
    								+ changeArrayList.get(1) + ","
    								+ changeArrayList.get(2) + ","
    								+ changeArrayList.get(3));
    						if (changeArrayList.get(0) == false
    								&& changeArrayList.get(1) == false
    								&& changeArrayList.get(2) == false
    								&& changeArrayList.get(3) == false) {
    						}
    					}
    					model.addRow(newRow);
    				}
    			}
    I'm confused because I don't know what the .setDefaultRenderer does and how it interacts with the CustomRenderer.

    This is the CellRenderer Class I found, hopefully to get me started.
    Java Code:
    	class CustomRenderer extends DefaultTableCellRenderer {
    		public Component getTableCellRendererComponent(JTable table,
    				Object value, boolean isSelected, boolean hasFocus, int row,
    				int col) {
    			Component comp = super.getTableCellRendererComponent(table, value,
    					isSelected, hasFocus, row, col);
    
    			String s = table.getModel().getValueAt(row, col).toString();
    
    			if (s.equalsIgnoreCase("false")) {
    				comp.setForeground(Color.red);
    			} else {
    				comp.setForeground(null);
    			}
    
    			return (comp);
    		}
    	}
    This is my code that is generating the rows for the table. I'd be happy to provide any other codes that you might need. Once again, thank you for your time.

  2. #2
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,242
    Rep Power
    19

    Default Re: Need guidance on how to change colour of a row in JTable.

    1. The row/column int values passed to getTableCellRendererComponent are the view row/column values. It your table is sortable/filtered, those may not be the same as the model row/column values. See the API for JTable for the methods to convert between view nad model indexes.

    2. Setting a foreground to null is a no-op (trace the source through JComponent and Component). Set it to the Color you require -- possibly obtained from the table parameter to getTableCellRendererComponent.

    If you still have a problem, post a SSCCE (Short, Self Contained, Compilable and Executable) example that demonstrates the problem. Not all your code.

    db
    rhexis likes this.
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  3. #3
    rhexis is offline Member
    Join Date
    Nov 2011
    Posts
    56
    Rep Power
    0

    Default Re: Need guidance on how to change colour of a row in JTable.

    Hi DB,

    Thank you for your quick reply, as always. :)

    Sorry about not posting a proper code yesterday, but because it was already midnight and I was heading to bed, so I thought I'd just post something before I sleep. I've managed to come up with a short code now.

    Java Code:
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.EventQueue;
    import java.util.ArrayList;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.border.EmptyBorder;
    import javax.swing.table.DefaultTableCellRenderer;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    
    public class Test extends JFrame {
    
    	private JPanel contentPane;
    	private JTable table;
    	private DefaultTableModel model;
    
    	/**
    	 * Launch the application.
    	 */
    	public static void main(String[] args) {
    		EventQueue.invokeLater(new Runnable() {
    			public void run() {
    				try {
    					Test frame = new Test();
    					frame.setVisible(true);
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    		});
    	}
    
    	/**
    	 * Create the frame.
    	 */
    	public Test() {
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		setBounds(100, 100, 450, 300);
    		contentPane = new JPanel();
    		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    		setContentPane(contentPane);
    		contentPane.setLayout(null);
    
    		Object[][] data = {};
    		String[] columnNames = { "No.",  "True/False?" };
    		model = new DefaultTableModel(data, columnNames);
    		table = new JTable(model);
    		table.setDefaultRenderer(Object.class, new CustomRenderer());
    		table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
    		JScrollPane tableScrollPane = new JScrollPane(table);
    		tableScrollPane.setBounds(0, 0, 434, 264);
    		contentPane.add(tableScrollPane);
    
    		ArrayList number1 = new ArrayList();
    		number1.add(1);
    		number1.add(1);
    		number1.add(2);
    		number1.add(2);
    
    		ArrayList number2 = new ArrayList();
    		number2.add(0);
    		number2.add(1);
    		number2.add(0);
    		number2.add(0);
    
    		int cycle = 2;
    
    		for (int i = 0; i < cycle; i++) {
    			ArrayList checkingFalse = new ArrayList();
    			for (int j = 0; j < 4; j++) {
    
    				Object[] newRow = new Object[2];
    				int no1 = (Integer) number1.get(j);
    				int no2 = (Integer) number2.get(j);
    				int number3 = no1 * no2;
    				newRow[0] = number3;
    				String check = "";
    				if (number3 != 0) {
    					check = "false";
    					newRow[1] = check;
    				} else {
    					check = "true";
    					newRow[1] = check;
    				}
    				checkingFalse.add(check);
    				System.out.println(checkingFalse.size());
    				if (checkingFalse.size() == 4) {
    					if (checkingFalse.get(2) == "true"
    							&& checkingFalse.get(3) == "true") {
    						System.out.println("2 true");
    					}
    				}
    				model.addRow(newRow);
    			}
    		}
    	}
    
    	class CustomRenderer extends DefaultTableCellRenderer {
    		public Component getTableCellRendererComponent(JTable table,
    				Object value, boolean isSelected, boolean hasFocus, int row,
    				int col) {
    			Component comp = super.getTableCellRendererComponent(table, value,
    					isSelected, hasFocus, row, col);
    
    			String s = table.getModel().getValueAt(row, col).toString();
    
    			if (s.equalsIgnoreCase("true")) {
    				comp.setForeground(Color.red);
    			} else {
    				comp.setForeground(Color.black);
    			}
    
    			return (comp);
    		}
    	}
    }
    
    				comp.setForeground(null);
    			}
    
    			return (comp);
    		}
    	}
    }
    The above is a short and simple code that displays a table example of my question. Basically, it loops through arrayList number1 & number2, and multiply them.

    As of now, I can successfully get the table to change the color of TRUE to red, but what I want to happen is that it will only change the color of TRUE to red if and only if there are the 3rd and 4th multiplication is a 0.

    I know the 2 cycle is redundant, since both cycles are the same. But my actual code has more complicated calculations such that it will take the values of the previous row and manipulate it before calculating the next row.

    Once again, thank you for your help.

  4. #4
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,242
    Rep Power
    19

    Default Re: Need guidance on how to change colour of a row in JTable.

    Java Code:
    String s = table.getModel().getValueAt(row, col).toString();
    The value at [row, column] is the same as the value parameter passed to the method. Did you really want to test that, or did you want to test the value contained in the same row, but one particular column?

    Also, why use a String set to "true" or "false" to do the work of a boolean?

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  5. #5
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,242
    Rep Power
    19

    Default Re: Need guidance on how to change colour of a row in JTable.

    Quote Originally Posted by rhexis View Post
    Hi DB,

    Thank you for your quick reply, as always. :)

    Sorry about not posting a proper code yesterday, but because it was already midnight and I was heading to bed, so I thought I'd just post something before I sleep.
    Humph. It's 7:30 am here and I've been up all night. And at a guess, I'm around 3 times your age.

    You young people have no stami -- Hey you whippersnappers! Get off my lawn!
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  6. #6
    rhexis is offline Member
    Join Date
    Nov 2011
    Posts
    56
    Rep Power
    0

    Default Re: Need guidance on how to change colour of a row in JTable.

    Quote Originally Posted by DarrylBurke View Post
    The value at [row, column] is the same as the value parameter passed to the method. Did you really want to test that, or did you want to test the value contained in the same row, but one particular column?

    Also, why use a String set to "true" or "false" to do the work of a boolean?

    db
    Hi DB, that was an awfully quick reply, thank you.

    You are right, I only one to test the value of a column passed in from that row, in this case, is the 2nd column.

    The Stringset thing is just a quick code, as this is just a test code. My actual code is in boolean.

    And wow, you should get some sleep. Lol. I have class at 8:30 and so I had to head to bed. It's a 8 hours class.

    Java Code:
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.EventQueue;
    import java.util.ArrayList;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.border.EmptyBorder;
    import javax.swing.table.DefaultTableCellRenderer;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    
    public class Test extends JFrame {
    
    	private JPanel contentPane;
    	private JTable table;
    	private DefaultTableModel model;
    
    	/**
    	 * Launch the application.
    	 */
    	public static void main(String[] args) {
    		EventQueue.invokeLater(new Runnable() {
    			public void run() {
    				try {
    					Test frame = new Test();
    					frame.setVisible(true);
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    		});
    	}
    
    	/**
    	 * Create the frame.
    	 */
    	public Test() {
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		setBounds(100, 100, 450, 300);
    		contentPane = new JPanel();
    		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    		setContentPane(contentPane);
    		contentPane.setLayout(null);
    
    		Object[][] data = {};
    		String[] columnNames = { "True/False?", "No." };
    		model = new DefaultTableModel(data, columnNames);
    		table = new JTable(model);
    		table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
    		JScrollPane tableScrollPane = new JScrollPane(table);
    		tableScrollPane.setBounds(0, 0, 434, 264);
    		table.setDefaultRenderer(Object.class, new CustomRenderer());
    		contentPane.add(tableScrollPane);
    
    		ArrayList number1 = new ArrayList();
    		number1.add(1);
    		number1.add(1);
    		number1.add(2);
    		number1.add(2);
    
    		ArrayList number2 = new ArrayList();
    		number2.add(0);
    		number2.add(1);
    		number2.add(0);
    		number2.add(0);
    
    		int cycle = 2;
    
    		for (int i = 0; i < cycle; i++) {
    			ArrayList checkingFalse = new ArrayList();
    			for (int j = 0; j < 4; j++) {
    
    				Object[] newRow = new Object[2];
    				int no1 = (Integer) number1.get(j);
    				int no2 = (Integer) number2.get(j);
    				int number3 = no1 * no2;
    				newRow[0] = number3;
    				String check = "";
    				if (number3 != 0) {
    					check = "false";
    					newRow[1] = check;
    				} else {
    					check = "true";
    					newRow[1] = check;
    				}
    				checkingFalse.add(check);
    				if (checkingFalse.size() == 4) {
    					if (checkingFalse.get(2) == "true"
    							&& checkingFalse.get(3) == "true") {
    					}
    				}
    				model.addRow(newRow);
    			}
    		}
    	}
    
    	class CustomRenderer extends DefaultTableCellRenderer {
    		public Component getTableCellRendererComponent(JTable table,
    				Object value, boolean isSelected, boolean hasFocus, int row,
    				int col) {
    			Component comp = super.getTableCellRendererComponent(table, value,
    					isSelected, hasFocus, row, col);
    
    			String s = table.getModel().getValueAt(row, 1).toString();
    			if (s.equalsIgnoreCase("true")) {
    				System.out.println("COL" + col);
    				System.out.println("ROW" + row + "\n");
    				comp.setForeground(Color.red);
    			} else {
    				comp.setForeground(Color.black);
    			}
    			return (comp);
    		}
    	}
    }
    I did a little test with my code again, as you can see under CustomRenderer. I did a System.out.println, and I have a question.

    My output is

    COL1
    ROW0

    COL1
    ROW2

    COL1
    ROW3

    COL1
    ROW4

    COL1
    ROW6

    COL1
    ROW7

    COL1
    ROW0

    COL1
    ROW2

    COL1
    ROW3

    COL1
    ROW4

    COL1
    ROW6

    COL1
    ROW7

    May I know why did it run twice? And when exactly is table.setDefaultRenderer being run?
    Last edited by rhexis; 02-17-2012 at 03:58 AM.

  7. #7
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,242
    Rep Power
    19

    Default Re: Need guidance on how to change colour of a row in JTable.

    For the answer to both those questions, go through the source code. you'll find that in the file src.zip in your JDK folder.

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  8. #8
    rhexis is offline Member
    Join Date
    Nov 2011
    Posts
    56
    Rep Power
    0

    Default Re: Need guidance on how to change colour of a row in JTable.

    I'm sorry I'm sorry but where? I didn't quite understand that. Which file am I looking for specifically?

    EDIT: Just ran a check, I don't have JDK!
    Last edited by rhexis; 02-17-2012 at 05:14 AM.

  9. #9
    rhexis is offline Member
    Join Date
    Nov 2011
    Posts
    56
    Rep Power
    0

    Default Re: Need guidance on how to change colour of a row in JTable.

    Alright, so I further worked upon the codes and have came up with this. I also disabled to table so we can't edit the values in it.

    Java Code:
    import java.awt.BorderLayout;
    
    public class Test extends JFrame {
    
    	private JPanel contentPane;
    	private JTable table;
    	private DefaultTableModel model;
    	private ArrayList checking = new ArrayList();
    
    	/**
    	 * Launch the application.
    	 */
    	public static void main(String[] args) {
    		EventQueue.invokeLater(new Runnable() {
    			public void run() {
    				try {
    					Test frame = new Test();
    					frame.setVisible(true);
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    		});
    	}
    
    	/**
    	 * Create the frame.
    	 */
    	public Test() {
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		setBounds(100, 100, 450, 300);
    		contentPane = new JPanel();
    		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    		setContentPane(contentPane);
    		contentPane.setLayout(null);
    
    		Object[][] data = {};
    		String[] columnNames = { "True/False?", "No." };
    		model = new DefaultTableModel(data, columnNames);
    		table = new JTable(model);
    		table.setEnabled(false);
    		table.setRowSelectionAllowed(false);
    		table.setCellSelectionEnabled(true);
    		table.setColumnSelectionAllowed(true);
    		table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
    		JScrollPane tableScrollPane = new JScrollPane(table);
    		tableScrollPane.setBounds(0, 0, 434, 264);
    		table.setDefaultRenderer(Object.class, new CustomRenderer());
    		contentPane.add(tableScrollPane);
    
    		ArrayList number1 = new ArrayList();
    		number1.add(1);
    		number1.add(1);
    		number1.add(2);
    		number1.add(2);
    
    		ArrayList number2 = new ArrayList();
    		number2.add(0);
    		number2.add(1);
    		number2.add(0);
    		number2.add(0);
    
    		int cycle = 2;
    
    		for (int i = 0; i < cycle; i++) {
    			ArrayList checkingFalse = new ArrayList();
    			for (int j = 0; j < 4; j++) {
    
    				Object[] newRow = new Object[2];
    				int no1 = (Integer) number1.get(j);
    				int no2 = (Integer) number2.get(j);
    				int number3 = no1 * no2;
    				newRow[0] = number3;
    				String check = "";
    				if (number3 != 0) {
    					check = "false";
    					newRow[1] = check;
    				} else {
    					check = "true";
    					newRow[1] = check;
    				}
    				checkingFalse.add(check);
    				if (checkingFalse.size() == 4) {
    					if (checkingFalse.get(2) == "true"
    							&& checkingFalse.get(3) == "true") {
    					}
    				}
    				model.addRow(newRow);
    			}
    		}
    	}
    
    	class CustomRenderer extends DefaultTableCellRenderer {
    		public Component getTableCellRendererComponent(JTable table,
    				Object value, boolean isSelected, boolean hasFocus, int row,
    				int col) {
    			Component comp = super.getTableCellRendererComponent(table, value,
    					isSelected, hasFocus, row, col);
    			int numberOfRows = table.getModel().getRowCount();
    			String s = "";
    			for (int y = 0; y < numberOfRows; y++) {
    				s = table.getModel().getValueAt(y, 1).toString();
    				checking.add(s);
    				if (checking.size() == 2) {
    					System.out.println("CHECKING");
    					System.out.println(checking.get(0) + " " + checking.get(1));
    					if (checking.get(0).equals("true")
    							&& checking.get(1).equals("true")) {
    						System.out.println("TRUE!!!");
    						comp.setForeground(Color.red);
    					} else {
    						System.out.println("FALSE!!!!");
    						comp.setForeground(Color.black);
    					}
    					checking.clear();
    				}
    			}
    			return (comp);
    		}
    	}
    }
    So basically, I believe, getTableCellRendererComponent is run every time there is a column that is being inserted/update, and what my getTableCellRendererComponent does is that it gets and store the value of the table Row x Col 1, where x is the number of Row the table has.

    Everything seems all right, except it's not.

    For some reason, it SEEMS to check Row X twice. Why? :(

    ***EDIT: I think I sort of understand it a little more now. Correct me if I'm wrong, but getTableCellRendererComponent runs through every cell in a row right? So how do I get it to specifically go to Row x Column X?

    ***EDIT: I realized I have been too rigid in my thoughts, and finally found out what is wrong. Now, I'm finally managing to get the specific column in the row. The entire code now manages to group the true/false and check if it meets 2 straight true. However, the coloring part is wrong. While it enters the else, it still appears as red after the code is being run.
    Last edited by rhexis; 02-17-2012 at 06:35 AM. Reason: Change of codes.

Similar Threads

  1. Jtable colour cell problem
    By fuzzdn in forum New To Java
    Replies: 10
    Last Post: 07-30-2011, 05:30 PM
  2. Replies: 4
    Last Post: 05-30-2011, 02:53 AM
  3. Replies: 2
    Last Post: 05-30-2011, 02:38 AM
  4. Change colour of JOptionPane
    By chirag123 in forum AWT / Swing
    Replies: 1
    Last Post: 05-03-2011, 02:48 AM
  5. Replies: 0
    Last Post: 03-26-2009, 01:23 AM

Posting Permissions

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