Hello I have a JTable And i want to grey out all the disabled checkbox cells i tried with a custom renderer checking isEnabled() and then changing the background color but still not workin.
Any suggestions?
thanks!!!
As noted in Concepts: Editors and Renderers, "a single cell renderer is generally used to draw all of the cells that contain the same type of data." You'll need to maintain the enabled state in your table model.
Addendum: As a concrete example, the data model in this example is a simple array of Date instances. Overriding getTableCellRendererComponent() as shown below causes odd days to be disabled. In this case, being odd is a property inherent to the Date value itself, but the model could be queried for any related property at all.
#Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row, int col) {
Calendar calendar = Calendar.getInstance();
calendar.setTime((Date) value);
Component c = super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, col);
c.setEnabled(calendar.get(Calendar.DAY_OF_MONTH) % 2 == 0);
return c;
}
Addendum: In the example above, the DateRenderer is evoked because the TableModel returns the type token Date.class, for which it has been made the default.
table.setDefaultRenderer(Date.class, new DateRenderer());
An identical appearance can be obtained by overriding prepareRenderer() as shown below, but the method is invoked for all cells, irrespective of class. As a result, prepareRenderer() is ideal for affecting entire rows, as shown in Table Row Rendering.
private final JTable table = new JTable(model) {
#Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int col) {
Component c = super.prepareRenderer(renderer, row, col);
if (col == DATE_COL) {
Calendar calendar = Calendar.getInstance();
calendar.setTime((Date) model.getValueAt(row, col));
c.setEnabled(calendar.get(Calendar.DAY_OF_MONTH) % 2 == 0);
}
return c;
}
};
Related
Hi i am working on jtable and i have to work with cell renderer in such a way that a am applying CurrencyRender in particular column. Also i am apply coloring ion each row. Everything going perfect but when i apply currencyRenderer in my numenric column, it lost the background color. This could be either due to adding cellrenderer of currency . Please suggest what should i do to color column with currency renderer .Here i my code
this.installAllignment(this.tblDemandView.getColumnModel().getColumn(numAmount), SwingConstants.RIGHT);
this.tblDemandView.getTableHeader().setReorderingAllowed(false);
this.tblDemandView.getTableHeader().setResizingAllowed(true);
tblDemandView.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
NumberFormat _formatf = NumberFormat.getNumberInstance();
_formatf.setMinimumFractionDigits(2);
_formatf.setMaximumFractionDigits(2);
MyCurrencyRenderer _rendererf = new MyCurrencyRenderer(_formatf);
TableColumnModel _model = tblDemandView.getColumnModel();
TableColumn _columnPu=_model.getColumn(_model.getColumnIndex("Amount"));
_columnPur.setCellRenderer(_rendererf);
private void installAllignment(TableColumn tableColumn, final int alignmentCode) {
tableColumn.setCellRenderer(new DefaultTableCellRenderer() {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
Component myself =
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
setHorizontalAlignment(alignmentCode);
DefaultTableModel model = (DefaultTableModel) table.getModel();
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
DefaultTableCellRenderer() {
if (row == table.getRowCount() - 1) {
Insets insets = new Insets(1, 0, 0, 0);
// setBorder(BorderFactory.createLineBorder(Color.BLACK));
}
return myself;
}
});
}
Your code doesn't make a lot of sense. You don't do anything with the model, c or insets variables.
But changing the renderer is really pretty trivial. Subclass the TableColumn and override getTableCellRenderer. In the body call the super method to generate the default renderer component and then set the background before returning it.
Alternatively you can implement your own TableCellRenderer and then call setTableCellRenderer on the column rather than subclassing.
Both approaches work fine and are useful in different situations.
Everything going perfect but when i apply currencyRenderer in my numenric column, it lost the background color.
I don't know if you are talking about losing the selection background color, or some other color you use for custom rendering.
Try using Table Row Rendering instead of cell rendering. This approach override the prepareRenderer(...) method of the table to do custom coloring.
You may also want to check out Table Format Renderers in the same blog. It show how to create custom renderer easily.
By the way the code in your renderer makes no sense to me:
Component myself = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
setHorizontalAlignment(alignmentCode);
DefaultTableModel model = (DefaultTableModel) table.getModel();
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
I have no idea why you would be invoking the getTableCellRendererComponent(...) method twice.
I have created a table and need to align every second row to the right, and every other row to default.
I understand how to align the rows. This is my default renderer
final DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
centerRenderer.setHorizontalAlignment(DefaultTableCellRenderer.CENTER);
final DefaultTableCellRenderer rightRenderer = new DefaultTableCellRenderer();
rightRenderer.setHorizontalAlignment(DefaultTableCellRenderer.RIGHT);
You'll have to tweak the renderer a little and override its getTableCellRendererComponent method. Something like:
DefaultTableCellRenderer renderer = new DefaultTableCellRenderer() {
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if (r % 2 == 0) {
setHorizontalAlignment(SwingConstants.LEFT);
}
else {
setHorizontalAlignment(SwingConstants.RIGHT);
}
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
};
Although creating your own proper class that extends DefaultTableCellRenderer and does this would be a better approach.
See Table Row Rendering.
This will allow you to change the alignment in one place even if your table uses multiple renderers and without creating a custom renderer.
I have created one Jtable.This table consist of two columns name and timestamp. I want to make color of row yellow if name is "jane". Following is the code for that :-
class CustomRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
String name = table.getModel().getValueAt(row, 0).toString();
if (name.trim().equals("jane")) {
c.setBackground(Color.YELLOW);
}
return c;
}
}
However instead of changing color of row to yellow for particular name, it is changing color of every row.I am setting data of table as following
tableModelName = (DefaultTableModel)jTableName.getModel();
jTableName.setDefaultRenderer(Object.class,new CustomRenderer());
for(int i=0; i<records.size(); i++)
{
tableModelName.addRow(records.get(i));
}
What I am doing wrong ?
You need an else clause to set the background color to something besides yellow if the name is not "jane". A single renderer instance is used for all rendering, so once you set the color to yellow on that instance, it stays yellow.
Take a look at the JTable source code to see how the built-in renderers work:
if (isSelected) {
setForeground(table.getSelectionForeground());
super.setBackground(table.getSelectionBackground());
}
else {
setForeground(table.getForeground());
setBackground(table.getBackground());
}
For an easier way of doing this, you might try subclassing JTable and overriding prepareRenderer. This is handy for changes that affect entire rows like this, so you can use custom renderers for the individual cells, and tweak all renderers for a row in the prepareRenderer method.
I have created a custom cell renderer class to achieve this.
public class MatchTableCellRenderer extends DefaultTableCellRenderer{
public Component getTableCellRendererComponent (JTable table,
Object obj, boolean isSelected, boolean hasFocus, int row, int column) {
Component cell;
cell = super.getTableCellRendererComponent(
table, obj, isSelected, hasFocus, row, column);
if( ((String[]) ((MatchTableModel) table.getModel()).getRow(row)).length==7 ){
System.out.println(((String[]) ((MatchTableModel) table.getModel()).getRow(row))[0]+" "+((String[]) ((MatchTableModel) table.getModel()).getRow(row))[6]);
cell.setForeground(Color.green);
}
return cell;
}
}
And I have set this renderer to be used by my table's columns:
tempColumn = table.getColumnModel().getColumn(0);
tempColumn.setCellEditor(new MacColumnEditor());
tempColumn.setCellRenderer(new MatchTableCellRenderer());
tempColumn = table.getColumnModel().getColumn(1);
tempColumn.setCellEditor(new IpColumnEditor());
tempColumn.setCellRenderer(new MatchTableCellRenderer());
tempColumn = table.getColumnModel().getColumn(2);
DefaultCellEditor dfEditor=new DefaultCellEditor(new JTextField());
dfEditor.setClickCountToStart(2);
tempColumn.setCellEditor(dfEditor);
tempColumn.setCellRenderer(new MatchTableCellRenderer());
I want the rows which contain a String[] of length=7 green and the others with the default color. But it is interesting that all my rows become green. I have a print line as you can see. It is printed 4 times (my table has 12 rows), but all rows are made green, instead of 4. What am I doing wrong?
The reason is the infamous color memory (TM) of the DefaultTableCellEditor: you have to set the colors always, instead of only in one branch.
if (myCondition) {
setBackground(...) {
} else {
setBackground(...)
}
the exact details are explained in a recent thread
You can use XxxCellRenderer, but better and easiest is to use prepareRenderer()
for correct code you have to override or test inside if-else follows patameters
isSelected
hasFocus
column
row
more in answers and question about similair issue
I have a JTable that is showing some records in a Java Swing application. The user only works with whole rows, not with individual cells. Is there any way I can focus on a whole row of a JTable? The default is to focus only the cell that the user has clicked on. I use a different color for the focus, so it doesn't look good if only a cell is focused instead of the whole row.
UPDATE: This is my current code of my custom TableCellRenderer, the issue is that when a row has focus and is painted with the "focus" color, and then the JTable loses focus, only the cell that had focus is repainted with the "selected" color but all cells in the selected row should be repainted with the "selected" color.
#Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
// Has any cell in this row focus?
if(table.getSelectedRow() == row && table.hasFocus()) {
hasFocus = true;
}
if (hasFocus) {
this.setBackground(CustomColors.focusedColor);
} else if (isSelected) {
this.setBackground(CustomColors.selectedColor);
} else {
// alternate the color of every second row
if(row % 2 == 0) {
this.setBackground(Color.WHITE);
} else {
this.setBackground(CustomColors.grayBg);
}
}
setValue(value);
return this;
}
Sounds like you're looking for the setRowSelectionAllowed() method.
Since you said just changing the color would be sufficient, you might want to look at the custom cell renderer section of the Swing Tutorial. You'd just have to set the logic to check on whether a given cell was in a selected row, and paint the background color accordingly.
A first idea would be something like
JTable jTable = new JTable() {
public TableCellRenderer getCellRenderer(int row, int column) {
final TableCellRenderer superRenderer = super.getCellRenderer(row, column);
return new TableCellRenderer() {
#Override
public Component getTableCellRendererComponent(JTable table, Object object, boolean isSelected, boolean hasFocus, int row, int column) {
// determine focus on row attribute only
hasFocus = hasFocus() && isEnabled() && getSelectionModel().getLeadSelectionIndex() == row;
return superRenderer.getTableCellRendererComponent(table, object, isSelected, hasFocus, row, column);
}
};
}
};
where I use my own logic to determine the focus based on the row attribute only. It uses the underlying cell renderers but looks strange if focus border is used.