First, this is my goal.
The first row, second column is "male", and the background color of the row is light gray.
As I change the male to female, the background color is changed to Orange.
I will explain this in source code.
package jtbl_color;
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
/**
*
* @author Lee
*/
public class ColoredTable extends JPanel{
private JTable table;
private JScrollPane scrollPane;
private MyTableModel model;
private int sexColumn = 1;
// data for the table
private Object[][] data = {
{"Singed", "male", false},
{"Akali", "female", false},
{"Tristina", "female", true},
{"Udyr", "male", false},
{"Janna", "female", true}
};
// column names for the table
private final String[] columnNames = {
"Name", "Sex", "Vegetarian"
};
public ColoredTable() {
super(new BorderLayout());
initComponents();
}
public void initComponents() {
// Initiate the Abstract Table Model
model = new MyTableModel();
// Add TableModelListener to the model
model.addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
// get the event, and check if the changed event is data update
if(e.getType() == TableModelEvent.UPDATE) {
// repaint the row
rowRepaint(table, table.convertRowIndexToView(e.getFirstRow()));
}
}
});
// Add the model to the JTable
table = makeTable(model);
// set the Combo box to sex column
setSexColumn(table.getColumnModel().getColumn(sexColumn));
// Add the table to the JScrollPane
scrollPane = new JScrollPane(table);
// Add the scrollPane to the JPanel
this.add(scrollPane);
}
// set combo box for sex column
public static void setSexColumn(TableColumn sexColumn){
// new combo box
JComboBox comboBox = new JComboBox();
// add male and female items to the combo box
comboBox.addItem("male");
comboBox.addItem("female");
// set combo box to the sex column
sexColumn.setCellEditor(new DefaultCellEditor(comboBox));
}
// repaint the selected row
private static void rowRepaint(JTable table, int row) {
Rectangle r = table.getCellRect(row, 0, true);
r.width = table.getWidth();
table.repaint(r);
}
// make table for changing colors
private JTable makeTable(final MyTableModel model) {
return new JTable(model) {
@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
String sex = (String)model.getValueAt(
convertRowIndexToModel(row), sexColumn);
if(sex.equals("female")) {
c.setBackground(Color.ORANGE);
} else if (sex.equals("male")) {
c.setBackground(Color.LIGHT_GRAY);
}
return c;
}
};
}
// Define the model for the table using AbstractTableModel
class MyTableModel extends AbstractTableModel {
// Decide the row count according to the data length
@Override
public int getRowCount() {
return data.length;
}
// decide the column count according to the columnNames length
@Override
public int getColumnCount() {
return columnNames.length;
}
// put the data values into the table.
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return data[rowIndex][columnIndex];
}
// put the columnNames values into the table column names
@Override
public String getColumnName(int col){
return columnNames[col];
}
// set if the cells in the table are editable.
// In this example, all the cells are editable
@Override
public boolean isCellEditable(int row, int col) {
return true;
}
// this is for data change.
@Override
public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
}
/*
* JTable uses this method to determine the default renderer/
* editor for each cell. If we didn't implement this method,
* then the last column would contain text ("true"/"false"),
* rather than a check box. (From oracle JTable tutorial)
*/
@Override
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
}
/**
* Create the GUI and show it.
* For thread safety,
* this method should be invoked from the
* event-dispatching thread.
* (from Oracle table tutorial)
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("TableRenderDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
ColoredTable newContentPane = new ColoredTable();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
}
I don't remember where I saw this method, so I cannot give you the reference page.
Also, I'm not quite sure what the prepareRenderer does..
More study is required here


No comments:
Post a Comment