对奇数行和偶数行使用不同的背景颜色是提高大表可读性的常用技巧。
我想在Swing的JTable中使用这个效果。我开始创建一个自定义表格渲染器,但这只能用于绘制实际单元格,我还想在表格的“白色”部分添加条纹,可能没有单元格。我可以子类化JTable并覆盖paintComponent(),但我更喜欢一个可以改变表格渲染的选项。
有更好的方法吗?
编辑:根据目前的答案,如果不延长JTable,这似乎是不可能的。但是,当我重写JTable.paintComponent()时,也只绘制有行的区域。我怎么画其余的?
答案 0 :(得分:4)
使用getCellRect( getRowCount() - 1, 0, true ).y
获取空白区域的顶部y坐标,然后使用paintComponent( Graphics g )
绘制一些矩形和(网格)线。
为了让您更轻松,这里有一个很长(但完整)的解决方案; - )
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
public class StripedEvenInWhitePartsTable extends JTable
{
public StripedEvenInWhitePartsTable( String[][] data, String[] fields )
{
super( data, fields );
setFillsViewportHeight( true ); //to show the empty space of the table
}
@Override
public void paintComponent( Graphics g )
{
super.paintComponent( g );
paintEmptyRows( g );
}
public void paintEmptyRows( Graphics g )
{
Graphics newGraphics = g.create();
newGraphics.setColor( UIManager.getColor( "Table.gridColor" ) );
Rectangle rectOfLastRow = getCellRect( getRowCount() - 1, 0, true );
int firstNonExistentRowY = rectOfLastRow.y; //the top Y-coordinate of the first empty tablerow
if ( getVisibleRect().height > firstNonExistentRowY ) //only paint the grid if empty space is visible
{
//fill the rows alternating and paint the row-lines:
int rowYToDraw = (firstNonExistentRowY - 1) + getRowHeight(); //minus 1 otherwise the first empty row is one pixel to high
int actualRow = getRowCount() - 1; //to continue the stripes from the area with table-data
while ( rowYToDraw < getHeight() )
{
if ( actualRow % 2 == 0 )
{
newGraphics.setColor( Color.ORANGE ); //change this to another color (Color.YELLOW, anyone?) to show that only the free space is painted
newGraphics.fillRect( 0, rowYToDraw, getWidth(), getRowHeight() );
newGraphics.setColor( UIManager.getColor( "Table.gridColor" ) );
}
newGraphics.drawLine( 0, rowYToDraw, getWidth(), rowYToDraw );
rowYToDraw += getRowHeight();
actualRow++;
}
//paint the column-lines:
int x = 0;
for ( int i = 0; i < getColumnCount(); i++ )
{
TableColumn column = getColumnModel().getColumn( i );
x += column.getWidth(); //add the column width to the x-coordinate
newGraphics.drawLine( x - 1, firstNonExistentRowY, x - 1, getHeight() );
}
newGraphics.dispose();
} //if empty space is visible
} //paintEmptyRows
public Component prepareRenderer( TableCellRenderer renderer, int row, int column )
{
Component c = super.prepareRenderer( renderer, row, column );
if ( !isRowSelected( row ) )
{
c.setBackground( row % 2 == 0 ? getBackground() : Color.ORANGE );
}
return c;
}
public static void main( String[] argv )
{
String data[][] = { { "A0", "B0", "C0" }, { "A1", "B1", "C1" }, { "A2", "B2", "C2" }, { "A3", "B3", "C3" }, { "A4", "B4", "C4" } };
String fields[] = { "A", "B", "C" };
JFrame frame = new JFrame( "a JTable with striped empty space" );
StripedEvenInWhitePartsTable table = new StripedEvenInWhitePartsTable( data, fields );
JScrollPane pane = new JScrollPane( table );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( pane );
frame.setSize( 400, 300 );
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
}
此示例可以扩展为:
答案 1 :(得分:2)
swingx提供的JXtable允许您实现此类渲染 看看http://swinglabs.org/docs/components/JXTable/tutorial.jsp?step=3#RowHighlighting
答案 2 :(得分:1)
您还可以使用自定义TableCellRenderer来为您挑选颜色,其中包含以下代码的一部分:
if (isSelected) //color remains the same while selected
{
lFgColor = table.getSelectionForeground();
lBgColor = table.getSelectionBackground();
}
else
{
lFgColor = table.getForeground();
if (row%2 != 0) //once out of two rows, change color
lBgColor = table.getBackground();
else
{
//New look and feels like nimbus declare this property, try to use it
lBgColor = UIManager.getColor("Table.alternateRowColor");
if (lBgColor == null) //If not, choose your own color
lBgColor = UIManager.getColor("Table.light");
}
}
}
编辑:我错过了您已尝试过的事实,并且您需要将此颜色扩展到没有单元格的空间。据我所知,目前JTable或JXTable的实现是不可能的。 JXTable的荧光笔主要是复杂的渲染器,它们仍然只适用于细胞。
为了扩大空间,我看到的唯一可能性是:
答案 3 :(得分:1)
使用Table Row Rendering概念比处理单个渲染器更容易。
此方法仅适用于渲染的单元格。如果要在表的边界外绘制,则需要覆盖paintComponent()方法以添加自定义绘制。
答案 4 :(得分:0)
要么使用JXTable,要么你是超级懒人(或超级时间短的:-)))你可以使用“Nimbus”外观,JTable看起来默认剥离:)