package org.limewire.ui.swing.table;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import org.jdesktop.swingx.decorator.ColorHighlighter;
import org.jdesktop.swingx.decorator.CompoundHighlighter;
/**
* Paints the grid and background colors for empty rows if the the ViewPort
* is larger than the number of rows to display.
* <p>
* If vertical and or horizontal grid lines are turned off, the corresponding grid
* line for empty rows will not be painted either.
* <p>
* There's the assumption that to paint the alternating effect, a HighLighter is being
* used. It also assumes that the row highlighter is either off, or is only using an
* simple alternating color to paint with.
*/
public class StripedJXTable extends GlazedJXTable {
private boolean emptyRowsPainted = true;
public StripedJXTable() {
super();
}
public StripedJXTable(TableModel tableModel) {
super(tableModel);
}
public StripedJXTable(TableModel tableModel, TableColumnModel tableColumnModel) {
super(tableModel, tableColumnModel);
}
public StripedJXTable(int numRows, int numColumns) {
super(numRows, numColumns);
}
public void setEmptyRowsPainted(boolean painted){
emptyRowsPainted = painted;
}
/**
* The parent paints all the real rows then the remaining space is calculated
* and appropriately painted with grid lines and background colors. These
* rows are not selectable.
*/
@Override
public void paint(Graphics g) {
super.paint(g);
if(emptyRowsPainted)
paintEmptyRows(g);
}
/**
* Paints fake rows to fill the viewport.
*/
protected void paintEmptyRows(Graphics g) {
int rowCount = getRowCount();
Rectangle clip = g.getClipBounds();
int clipHeight = clip.y + clip.height;
int tableHeight = getVisibleRect().height;
int clipViewableRows = clipHeight / rowHeight;
int tableViewableRows = tableHeight / rowHeight;
int startDrawingAt = rowCount * rowHeight;
// paint rows and horizontal lines
if (startDrawingAt < tableHeight) {
if(clipViewableRows < tableViewableRows) {
// we need to call repaint in order to trigger things to properly paint.
// ideally, we would just change the clip and draw...
// but because tables are generally inside of a JViewport,
// we can't do that, because the viewport draws to a backbuffer
// and then blts the changes... so we need to tell the viewport
// that we need to do our drawing explicitly.
// it will recall this method with the proper clip,
// and we can paint!
repaint(clip.x, startDrawingAt, clip.width, tableHeight - startDrawingAt);
} else {
for (int i = rowCount; i <= clipViewableRows; ++i) {
g.setColor(getColorForRow(i));
g.fillRect(clip.x, i * rowHeight, clip.width, rowHeight);
// paint horizontal rows if they're shown
if(getShowHorizontalLines() && i > rowCount) {
g.setColor(gridColor);
g.drawLine(clip.x, i * rowHeight, clip.x + clip.width, i * rowHeight);
}
}
// paint vertical lines if they're shown
if (getShowVerticalLines()) {
g.setColor(gridColor);
TableColumnModel columnModel = getColumnModel();
int x = 0;
for (int i = 0; i < columnModel.getColumnCount(); ++i) {
TableColumn column = columnModel.getColumn(i);
x += column.getWidth();
g.drawLine(x - 1, rowCount * rowHeight, x - 1, rowCount * rowHeight + clipHeight);
}
}
}
}
}
/**
* Gets the background color for the row. This is assuming 1) there's no row highlighter or
* 2) there's only an alternate row highlighter. Anything else and the behaviour is unknown
* @param row row to paint
* @return Color to paint with
*/
protected Color getColorForRow(int row) {
return (row % 2 == 0) ? getHighlighterColor(0) : getHighlighterColor(1);
}
private Color getHighlighterColor(int index){
if(getHighlighters() == null || getHighlighters().length == 0)
return getBackground();
else if(getHighlighters()[0] instanceof CompoundHighlighter) {
if( ((CompoundHighlighter)getHighlighters()[0]).getHighlighters().length <= index)
return getBackground();
else
return ((ColorHighlighter)((CompoundHighlighter)getHighlighters()[0]).getHighlighters()[index]).getBackground();
}
else if(getHighlighters()[0] instanceof ColorHighlighter) {
if(getHighlighters().length <= index)
return getBackground();
else
return ((ColorHighlighter)getHighlighters()[index]).getBackground();
}
return getBackground();
}
}