Java JTable - Coloring the Selected Row - java

Ive searched through but cant seem to find an answer thats similar.
Id like to color a selected row AND at the same time permanently color other rows.
i.e have the total Column always GRAY but dynamically make the selected row GRAY
Im trying
JTable table = new JTable(model) {
public Component prepareRenderer(TableCellRenderer renderer, int index_row, int index_col) {
Component comp = super.prepareRenderer(renderer, index_row, index_col);
//odd col index, selected or not selected
if(isCellSelected(index_row, index_col)){
comp.setBackground(Color.GRAY);
}
if (index_col == 34) {
comp.setBackground(Color.GRAY);
} else {
comp.setBackground(Color.WHITE);
setSelectionForeground(Color.BLUE);
setSelectionBackground(Color.GRAY); // Thought this would work but has no affect.
// comp.setFont(new Font("Serif", Font.BOLD, 12));
}
return comp;
}
};
But its not changing the background Color on selected Row, Just the Total Row.

I'm not sure, but I think you need an "else" after the if (isCellSelected(index_row, index_col))
block. This could solve your problem:
...
if (isCellSelected(index_row, index_col)){
comp.setBackground(Color.GRAY);
} else {
if (index_col == 34) {
comp.setBackground(Color.GRAY);
} else {
comp.setBackground(Color.WHITE);
}
}
...

Related

How to use HTML in JTable custom renderer

When using HTML in my JTable cells it will be displayed as
<html><b>Example</html></b>
and not with the proper html styles. I read that default renderers work with html text. How do i change my custom renderer to display HTML correctly ?
My Jtable:
tab_months = new JTable(tabmod_months) {
#Override public Component prepareRenderer(TableCellRenderer renderer,
int row,
int col){
Component c = super.prepareRenderer(renderer, row, col);
int selCol = tab_months.getSelectedColumn();
int selRow = tab_months.getSelectedRow();
if ( selCol != -1 && selRow != -1 ){
if (row == selRow){
c.setBackground(new Color(163,198,255));
} else {
c.setBackground(new Color(255,240,245));
}
}
if (row>=0 && row<listOpenmonths.size()+1) {
setToolTipText(listOpenmonths.get(row).getmonthsString());
}
return c;
}
};
Found the problem: my html tag was inside of the string and it wasn't recognized...changed the string format and it worked. Thank you !

remove unused rows in jtable (Empty Rows)?

a question about removing unused rows in jtable i am using DefualtTableModel my table already has some data & when i update it leave some columns empty to update theme later so they are null column.. i want to remove theme with a push button before saving data.. i actually tried this code:
private void btn_ClearActionPerformed(java.awt.event.ActionEvent evt) {
table.setAutoCreateRowSorter(true);
TableRowSorter sorter = (TableRowSorter) table.getRowSorter();
sorter.setRowFilter(new RowFilterImpl());
}
i also tried this:
private void btn_ClearActionPerformed(java.awt.event.ActionEvent evt) {
table.setAutoCreateRowSorter(true);
TableRowSorter sorter = (TableRowSorter) table.getRowSorter();
sorter.setRowFilter(new RowFilter<TableModel, Integer>() {
#Override
public boolean include(RowFilter.Entry<? extends TableModel, ? extends Integer> entry) {
boolean included = true;
Object cellValue = entry.getModel().getValueAt(entry.getIdentifier(), 0);
if (cellValue == null || cellValue.toString().trim().isEmpty()) {
included = false;
}
return included;
}
});
}
the code above is working but i don't like it becuase it resizes rows after filtering so i want to do something with model.remove(); using if conditions.. and i want to specify columns for example column 7 & 12 and want to remove only empty rows in specified columns..
ok i tried this code:
for (int i = model.getRowCount() - 1; i >= 0; i--)
{
Object col1 = model.getValueAt( i,model.getColumnCount() - 6);
Object col2 = model.getValueAt( i,model.getColumnCount() - 11);
if (col1 == null || col2 == null)
model.removeRow(i);
}
i faced same problem and i found this code below cuasing that problem so i removed it ... i also found that it counts how many time you selected or clicked on a row and then resizes it as many you clicked!
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
int lastRow = -1;
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
if (lastRow != -1) {
table.setRowHeight(lastRow, table.getRowHeight());
}
int row = table.getSelectedRow();
table.setRowHeight(row, 23);
lastRow = row;
}
}
});
any idea guys?
thanx in advance
Create a loop to remove the data from the model.
Maybe something like:
for (int i = model.getRowCount() - 1; i >= 0; i--)
{
if (column?? == null && column?? == null)
model.removeRow(i);
}
added the problem above in table.setRowHeight();
Well, that should have been part of the original question. How do we know you have custom logic doing something strange???
In the future post a proper SSCCE that demonstrates the problem so we don't have to guess what you are doing.
i get the same problem it resizes rows
Then remove the listener:
remove the listener
delete the rows
add the listener

Error when sorting rows in Jtable

I'm trying to set a RowSorter on my Jtable, I used the method setAutoCreateRowSorter(Boolean b) to sort the rows
table.setAutoCreateRowSorter(true);
But when I make the table as rawSorted, I get a strange error!
The conflict is visible when I want to delete a line, I used fireTableRowsDeleted().
int raw = table.getSelectedRow(); // the index of raw that i want to delete it
System.out.println(raw);
model.delte_raw(raw); // model is my table model
public void delte_raw(int raw)
{
if (!ls.isEmpty()) {
this.fireTableRowsDeleted(raw+1, raw);
ls.remove(raw);
}
I want to show you what result return the code as above in 2 cases:
Case 1:
When I make my table as not rawsorted:
table.setAutoCreateRowSorter(false);
when I delete a line, it all works successfully.
Case 2:
When I make my table as rawsorted:
table.setAutoCreateRowSorter(true);
when I delete a line, I get the error as below:
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Invalid range
at javax.swing.DefaultRowSorter.checkAgainstModel(DefaultRowSorter.java:921)
at javax.swing.DefaultRowSorter.rowsDeleted(DefaultRowSorter.java:878)
at javax.swing.JTable.notifySorter(JTable.java:4277)
at javax.swing.JTable.sortedTableChanged(JTable.java:4121)
at javax.swing.JTable.tableChanged(JTable.java:4398)
at javax.swing.table.AbstractTableModel.fireTableChanged(AbstractTableModel.java:296)
at javax.swing.table.AbstractTableModel.fireTableRowsDeleted(AbstractTableModel.java:261)
I think that the error is in my defaultRowSorter, so I defined my specific cellRenderer as below:
// final TableCellRenderer r = table.getTableHeader().getDefaultRenderer();
//TableCellRenderer wrapper = new TableCellRenderer() {
// private Icon ascendingIcon = new ImageIcon("images/e.png");
// private Icon descendingIcon = new ImageIcon("images/e.png");
//
// #Override
// public Component getTableCellRendererComponent(JTable table,
// Object value, boolean isSelected, boolean hasFocus,
// int row, int column)
// {
// Component comp = r.getTableCellRendererComponent(table, value, isSelected,
// hasFocus, row, column);
// if (comp instanceof JLabel) {
// JLabel label = (JLabel) comp;
// label.setIcon(getSortIcon(table, column));
// }
// return comp;
// }
//
// /**
// * Implements the logic to choose the appropriate icon.
// */
// private Icon getSortIcon(JTable table, int column) {
// SortOrder sortOrder = getColumnSortOrder(table, column);
// if (SortOrder.UNSORTED == sortOrder) {
// return null;
// }
// return SortOrder.ASCENDING == sortOrder ? ascendingIcon : descendingIcon;
// }
//
// private SortOrder getColumnSortOrder(JTable table, int column) {
// if (table == null || table.getRowSorter() == null) {
// return SortOrder.UNSORTED;
// }
// List<? extends RowSorter.SortKey> keys = table.getRowSorter().getSortKeys();
// if (keys.size() > 0) {
// RowSorter.SortKey key = keys.get(0);
// if (key.getColumn() == table.convertColumnIndexToModel(column)) {
// return key.getSortOrder();
// }
// }
// return SortOrder.UNSORTED;
// }
//
//};
//table.getTableHeader().setDefaultRenderer(wrapper);
But again, the same error!
Why do I get this error? I googled it a lot, but either I used the wrong keywords or there are no simple solutions on the internet.
In your table model:
public void delte_raw(int raw) {
if (!ls.isEmpty()) {
this.fireTableRowsDeleted(raw+1, raw); // why raw+1 ???
ls.remove(raw);
}
}
As your table model extends from AbstractTableModel and looking at fireTableRowsDeleted(int firstRow, int lastRow) javadoc:
Notifies all listeners that rows in the range [firstRow, lastRow],
inclusive, have been deleted.
So it should be:
public void delte_raw(int raw) {
if (!ls.isEmpty()) {
ls.remove(raw); // remove the row index from the List and then fire the event
fireTableRowsDeleted(raw, raw);
}
}
Knowing the exception source: looking at DefaultRowSorter.checkAgainstModel(int firstRow, int endRow) implementation:
private void checkAgainstModel(int firstRow, int endRow) {
if (firstRow > endRow || firstRow < 0 || endRow < 0 ||
firstRow > modelRowCount) {
throw new IndexOutOfBoundsException("Invalid range");
}
}
As you can see, calling this method with [raw+1,raw] range causes an IndexOutOfBoundsException.
Edit
As #mKorbel masterfully points out, I've totally overlooked this:
int raw = table.getSelectedRow(); // this is the index in the view
model.delte_raw(raw); // convert raw in the right model index is needed
You need to convert raw in the right model index. Otherwise it can cause side effects since in a sorted table is most likely the selected index in the view be different than its related model's index:
int raw = table.getSelectedRow(); // this is the index in the view
model.delte_raw(table.convertRowIndexToModel(raw)); // perfect
See JTable.convertRowIndexToModel(int viewRowIndex)

Set a cell's background in JTable based on some other inputs

All - I'm trying to set a specific cell's background color after it is clicked AND a successful operation has occurred. I cant seem to do it. Here is the code:
JTable table = new JTable(new DefaultTableModel());
String [] colNames = {"col1", "col2", "ClickMe"};
for (String name : colNames)
table.addColumn(name);
.... some code .....
String [] someArray = {"t", "t2", "t3"};
....
for (int i=0; i<someArray.length;i++) {
Object [] row = new Object[3];
row[0] = "bla";
row[1] = "bla";
row[2] = "Update";
((DefaultTableModel)table.getModel()).addRow(row);
((DefaultTableCellRenderer)gameTable.getCellRenderer(i, 2)).setBackground(Color.LIGHT_GRAY);
((DefaultTableCellRenderer)gameTable.getCellRenderer(i, 2)).setHorizontalAlignment(JLabel.CENTER);
}
table.addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent e) {
int row = gameTable.rowAtPoint(e.getPoint());
int col = gameTable.columnAtPoint(e.getPoint());
if (col == 2) {
Color cellColor = ((DefaultTableCellRenderer)gameTable.getCellRenderer(row,col)).getBackground();
if (cellColor == Color.LIGHT_GREY) {
String val1 = (String)table.getModel().getValueAt(row,1);
String val2 = (String)table.getModel().getValueAt(row,0);
if (doSomething(val1, val2)) { //this returns either true or false, its a Database operations
((DefaultTableCellRenderer)table.getCellRenderer(row, 2)).setBackground(Color.BLUE);
}
}
}
};
Even thought i am specific calling setBackground on a row & column, it makes every cell in every row in column "2" change background color instead of just one specific one.
All the examples with customRenderers seem to just change the color based on when its clicked just change it to something else, i need to do some processing as well.
any thoughts here?
Thanks-
Try this
table.setDefaultRenderer(Object.class, new TableCellRenderer(){
private DefaultTableCellRenderer DEFAULT_RENDERER = new DefaultTableCellRenderer();
private Component comp;
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component c = DEFAULT_RENDERER.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if(isSelected){
c.setBackground(Color.YELLOW);
}else{
if (row%2 == 0){
if (column==2){
c.setBackground(Color.WHITE);
}
else {
c.setBackground(Color.LIGHT_GRAY);
} } }
return c;
}
});

Multiple alignments in a single table

Well the question is simple.
How do I set a different alignment for two rows in te same table? I tried:
table.getColumnModel().getColumn(0).setCellRenderer(renderer)
but it didn't work. Any ideas?
Ok. There's the code:
table = new JTable(){
#Override
public TableCellRenderer getCellRenderer(int row, int col) {
DefaultTableCellRenderer leftRenderer = new DefaultTableCellRenderer();
DefaultTableCellRenderer rightRenderer = new DefaultTableCellRenderer();
leftRenderer.setHorizontalAlignment(SwingConstants.LEFT);
rightRenderer.setHorizontalAlignment(SwingConstants.RIGHT);
// Return renderer for left aligned cells
if (col == 0) return leftRenderer;
// Return renderer for right aligned cells
else return rightRenderer;
}
};

Categories