Используя другой цвет фона для четных и нечетных строк наиболее часто используемый прием для улучшения удобочитаемости больших таблиц.
Я хочу использовать этот эффект в JTable Swing. Я начал путем создания пользовательского рендерера таблицы, но это может только использоваться для рисования фактических ячеек, и я также хочу добавить дорожки к "белой" части таблицы, где не могло бы быть никаких ячеек. Я могу разделить JTable на подклассы и переопределить paintComponent (), но я предпочел бы опцию, где я могу просто изменить рендеринг таблицы.
Существует ли лучший способ сделать это?
Править: Согласно ответам до сих пор это, кажется, невозможно, не расширяя JTable. Однако, когда я переопределяю JTable.paintComponent (), он также только красит область, где существуют строки. Как я могу нарисовать остальных?
Используйте getCellRect (getRowCount () - 1, 0, true) .y
, чтобы получить верхнюю координату y пустого пространства, а затем нарисуйте несколько прямоугольников и ( Сетка-) Линии с paintComponent (Графика 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 );
}
}
Этот пример можно расширить до:
Используйте концепции рендеринга строки таблицы , которые проще, чем иметь дело с отдельными рендерерами.
Этот подход работает только для визуализированных ячеек. Если вы хотите рисовать за пределами таблицы, вам нужно будет переопределить метод paintComponent (), чтобы добавить пользовательское рисование.
Вы также можете использовать пользовательский 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");
}
}
}
Edit : я упустил тот факт, что вы уже пробовали это, и что вам нужно расширить этот цвет на пространство без ячеек. Насколько мне известно, это невозможно с текущей реализацией JTable или JXTable. Хайлайтеры из JXTable в основном сложные рендереры, они по-прежнему обслуживают только ячейки.
Чтобы расширить пространство, я вижу только следующие возможности:
Либо используйте JXTable, либо, если вы супер-ленивый (или супер-нехватка времени :-)), вы можете просто использовать "Nimbus" look-and-feel, JTable выглядит там ободранным по умолчанию :)
JXtable, предоставляемый swingx, позволяет реализовать такой рендеринг. Посмотрите на http://swinglabs.org/docs/components/JXTable/tutorial.jsp?step=3#RowHighlighting