Creating a JTable with alternating row colors - java

I am pretty new to java swing and i just started working on JTable. I want to create a JTable Which look like the above image? Can anybody help me beacause i am not so familiar with JTable?

Overriding the prepareRender(...) method of the JTable allows you to customize rendering for the entire row without providing custom renderers.
The basic logic would be something like:
JTable table = new JTable( model )
{
public Component prepareRenderer(TableCellRenderer renderer, int row, int column)
{
Component c = super.prepareRenderer(renderer, row, column);
// Alternate row color
if (!isRowSelected(row))
c.setBackground(row % 2 == 0 ? getBackground() : Color.LIGHT_GRAY);
return c;
}
};
Check out Table Row Rendering for more information and working examples.

How can I achieve the border of the table header like the figure?
You can obtain a copy of the default table header renderer for a given L&F, as shown here, and modify it as desired. With some caveats, you can modify the renderer for a particular TableColumn, as shown here.

Related

How to change the background color of a specific table header and font color of a specific column in a JTable?

Is there a way to change the background color of the 3 circled table headers of a JTable?
I also want to change the font color of all the 3 circled columns to red.
An image of my table is down below. Thanks.
The way I know of is to create a TableCellRenderer that will handle the coloring of the foreground and background color.
You could create a simple coloring scheme where the color doesn't change. You often see this in tables with alternating colored rows. You could also use it for "conditional formatting". For example, highlight a cell if a value falls under a certain value. With a cell renderer, you will have better control of this.
Here is a link to Oracle's tutorial on renderers.
Lastly, since your question specifically asks to do this on specific cells, the link documentation states that
To specify a cell-specific renderer, you need to define a JTable subclass that overrides the getCellRenderer method. For example, the following code makes the first cell in the first column of the table use a custom renderer:
TableCellRenderer weirdRenderer = new WeirdRenderer();
table = new JTable(...) {
public TableCellRenderer getCellRenderer(int row, int column) {
if ((row == 0) && (column == 0)) {
return weirdRenderer;
}
// else...
return super.getCellRenderer(row, column);
}
};

How to change a cell in a jTable programmatically?

I'm currently writing an application where I present to the user amongst other things links to websites in a JTable. I already set up my JTable correctly to open up the corresponding website upon clicking the regarding cell. However I struggle with correctly formatting the cell so that users know they actually have the possibility of clicking the cell for instantly opening the website.
Hence what I want to achieve is to have the colour of the link being blue at least and even better also underlined. I searched through different articles on SO regarding this but couldn't quite grasp how the things explained there work together - despite I'm not entirely sure if these things would have even be what I'm actually looking for.
The way I fill my table is the following:
String[][] rowData = new String[entries.size() + 1][entries.get(0).length + 1];
rowData[0] = columnNames;
int i = 1;
Iterator<String[]> iterator = entries.iterator();
while (iterator.hasNext()) {
rowData[i] = iterator.next();
i++;
}
tblEntries = new JTable(rowData, columnNames);
entries in this case is an ArrayList that is passed over by the database handler and - as the name suggests - contains all entries for the table. After reading the ArrayList into the respective Array I initialize the table as seen in the last row. Now all the links are actually stored in all rows > 0 and the 4th column.
My first approach was doing something like this:
for (int j = 0; j < entries.size(); j++) {
for (int j2 = 0; j2 < entries.get(0).length; j2++) {
tblEntries.editCellAt(row, column, e);
}
}
where e should be an event that checks wheter the conditions for a link are satisfied or not and execute the formatting accordingly. However I don't really now what kind of event is needed to pass it to the function.
An other approach I saw in a different SO article was to use the prepareRenderer method to specify the conditions for rendering the content correctly. However apparently this seems to be only possible for own implementations of a JTable which I'd like to avoid as tblEntries.prepareRenderer() and applying a new TableCellRenderer or DefaultTableCellRenderer doesn't give me the function that I need to override according to above mentioned SO article.
So, what would be the best and most convenient way to tackle this problem down? Thanks in advance for your any adivce and help.
SOLUTION:
For anyone facing a similar problem I'll put my solution here. As suggested by #camickr the best solution is a custom DefaultTreeCellRenderer the problem in this specific scenario however is that it will also render the specific table-header (which obviously doesn't contain any links) in the link format. Hence I searched a bit further and found this website where I found a working code for customising where the renderer should be applied.
In the end I came up with this code:
String[][] rowData = new String[entries.size() + 1][entries.get(0).length + 1];
rowData[0] = columnNames;
int i = 1;
Iterator<String[]> iterator = entries.iterator();
while (iterator.hasNext()) {
rowData[i] = iterator.next();
i++;
}
tblEntries = new JTable(rowData, columnNames) {
#Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
if (row > 0 && column == 4) {
c = super.prepareRenderer(new LinkRenderer(), row, column);
}
return c;
}
};
For reference for the LinkRenderer see accepted answer below.
what I want to achieve is to have the colour of the link being blue at least and even better also underlined.
This is controlled by the renderer. The default renderer for the JTable is a JLabel.
You can easily create a custom renderer to display the text in blue:
DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
renderer.setForeground( Color.BLUE );
table.getColumnModel().getColumn(3).setCellRenderer( renderer );
Unfortunately underlining the text will be more difficult. Underlining text in a component can be achieved by setting a property of the Font which is easy enough to do for a JLabel:
JLabel label = new JLabel("Underlined label");
Font font = label.getFont();
Map<TextAttribute, Object> map = new HashMap<TextAttribute, Object>();
map.put(TextAttribute.FONT, font);
map.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
font = Font.getFont(map);
label.setFont(font);
However, you can't just set the Font for the renderer because when each cell is rendered the default renderer will reset the Font to be the Font used by the table.
So if you want to implement a custom renderer with a custom Font, you need to extend the DefaultTableCellRenderer and override the getTableCellRendererComponent(….) method. The code might be something like:
class LinkRenderer extends DefaultTableCellRenderer
{
private Font underlineFont;
public LinkRenderer()
{
super();
setForeground( Color.BLUE );
underlineFont = .getFont();
Map<TextAttribute, Object> map = new HashMap<TextAttribute, Object>();
map.put(TextAttribute.FONT, underlineFont);
map.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
underLinefont = Font.getFont(map);
}
#Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
setFont( underlineFont );
return this;
}
}
Read the section from the Swing tutorial on Renderers and Editors for more information.
So the other approach is to NOT use a custom renderer but instead you can add HTML to the table model. A JLabel can display simple HTML.
So the text you add to the model would be something like:
String text = "<html><u><font color=blue>the link goes here</font></ul></html>";

How to change the GridLine Width of a JTable in Java?

Like the title says, is there a simple way to change the width of the gridlines in JTable?
I found out, that there is a simple way to change the color of the showed gridlines in the Jtable but I could not find any methods to change the gridline width.
One of the ways is to override the prepareRenderer(...) method of JTable class, using BorderFactory to create custom border:
JTable table = new JTable( model ) {
public Component prepareRenderer( TableCellRenderer renderer, int row, int column) {
JComponent jc = (JComponent)super.prepareRenderer(renderer, row, column);
jc.setBorder(BorderFactory.createLineBorder(Color.BLACK, 3));
return jc;
}
};

JTable, don't understand how to set cell color on mouseclick

OK, I must be completely brainless but I can't seem to implement the code needed to set (permanently) the background color of the selected (clicked) cell in my JTable. I've read through most of the answers on this site but I'm still not getting it.
I'm using the preparedRenderer() method but I don't understand why it isn't working?
table.addMouseListener(
new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent m) {
row = table.getSelectedRow();
column = table.getSelectedColumn();
}
}
);
table = new JTable(data, columnNames) {
public Component prepareRenderer(TableCellRenderer rend, int r, int k) {
Component g = super.prepareRenderer(rend, row, column);
g.setBackground(Color.BLUE);
return g;
}
};
The way I'm understanding it is that prepareRenderer is taking a specific cell from the table as a Component and then allowing me to change the properties of that Component. But even if I write:
Component g = super.prepareRenderer(rend, 1, 1);
g.setBackground(Color.BLUE);
return g;
it just paints the whole table and not the cell at row=1, column=1???
I'm just not getting it...
it just paints the whole table and not the cell at row=1, column=1???
The prepareRenderer() method is called for every cell that gets repainted. This is done dynamically as the user selects a row or tabs to a new cell or clicks on a cell.
set (permanently) the background color of the selected (clicked) cell in my JTable.
Maybe you can create a Set of Point objects to represent the cells that you want to paint a different color. So when you click on the cell you create a Point object for the row/column and then add the Point to the set.
Then in the prepareRenderer(...) method you create a new Point representing the row/column you are about to renderer. If this Point is found in your Set then you change the background color.

JTable Clickable Column Sorting: Sorting sorts content of cells, but doesn't update cell formatting?

I have a sortable JTable set up to use a custom extension of the AbstractTableModel. However, some behavior of this table is what I expected, and I would love some advice on how to figure this out.
I have the JTable set up to be sortable using:
thisJTable.setAutoCreateRowSorter(true);
This allows me to sort the table by clicking on the column headers as expected.
However, I find that when I sort the table by clicking on the column headers, the formatting (background and foreground color) of my rows are not sorted as well.
I had set up those rows to be color-coded based on the values they contain. When I sort by column header the formatting at a given row NUMBER stays the same (although the content that was previously in that row moved).
The color of the row is set by overriding the default prepareRenderer call for the JTable:
thisTable = new JTable(thisModel){
//Set up custom rendering - Sets background color of row to correct value
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
CustTableModel thisModel = (CustTableModel) getModel();
c.setBackground(thisModel.getRowBackgroundColor(row));
c.setForeground(thisModel.getRowForeColor(row));
return c;
}
};
Is there a better/different way to approach this?
Should I be using a different method to do my rendering, a method which would update the rendering of the JTable on a sort?
Or do I want to look into writing my own sorting method?
Solution (Thanks mKorbel!)
I thought I would post my solution, since I had to play with this a bit since I wasn't sure if the new index would be passed to the prepareRenderer as well.
thisTable = new JTable(thisModel){
//Set up custom rendering - Sets background color of row to correct value
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
int viewIdx = row;
int modelIdx = convertRowIndexToModel(viewIdx);
Component c = super.prepareRenderer(renderer, row, column);
CustTableModel thisModel = (CustTableModel) getModel();
c.setBackground(thisModel.getRowBackgroundColor(modelIdx));
c.setForeground(thisModel.getRowForeColor(modelIdx));
return c;
}
};
you have to convert row index from View to the Model
int modelRow = convertRowIndexToModel(row);
You can enable table sorting by clicking on header using this
table.setAutoCreateRowSorter(true);
for more information visit this site http://www.codejava.net/java-se/swing/6-techniques-for-sorting-jtable-you-should-know

Categories

Resources