java - setmodel - JTable con fondo rayado
setmodel java (5)
Usar un color de fondo diferente para las filas pares e impares es un truco comúnmente utilizado para mejorar la legibilidad de tablas grandes.
Quiero usar este efecto en Swing''s JTable. Empecé creando un renderizador de tabla personalizado, pero esto solo se puede usar para pintar las celdas reales, y también quiero agregar rayas a la parte "blanca" de la tabla donde no podría haber celdas. Puedo subclasificar a JTable y reemplazar paintComponent (), pero preferiría una opción donde simplemente pueda cambiar la representación de la tabla.
¿Hay una mejor manera de hacer esto?
Editar: Según las respuestas hasta ahora, esto parece ser imposible sin extender JTable. Sin embargo, cuando anulo JTable.paintComponent () también solo pinta el área donde hay filas. ¿Cómo puedo pintar el resto?
La tabla JX proporcionada por swingx le permite implementar dicha representación. Consulte http://swinglabs.org/docs/components/JXTable/tutorial.jsp?step=3#RowHighlighting.
O use JXTable o si es súper perezoso (o súper cortocircuito en el tiempo :-)) puede usar el aspecto "Nimbus", JTable se ve despojado por defecto :)
También puede usar un TableCellRenderer personalizado que seleccionará el color por usted, con una parte de código como este dentro:
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");
}
}
}
Editar : me perdí el hecho de que ya lo intentaste, y que necesitas extender este color al espacio sin células. Que yo sepa, esto no es posible con la implementación actual de JTable o JXTable. Los resaltadores de JXTable son en su mayoría procesadores sofisticados, todavía atienden solo a las células.
Para ampliar el espacio, las únicas posibilidades que veo son:
- dibuja tú mismo, en tu propio componente.
- "hackear" de una manera agregando una última columna falsa, con un JTableHeader personalizado que no mostraría el último encabezado de columna (y un representador que evita la cuadrícula para esta última columna). Además, el modo de cambio de tamaño de la tabla debe ser AUTO_RESIZE_LAST_COLUMN, en este caso. Esta es una gran cantidad de condiciones para que funcione, y no estoy seguro de que funcione de todos modos.
Use los conceptos de Renderización de filas de tablas que es más fácil que tratar con renderizadores individuales.
Este enfoque solo funciona para las celdas renderizadas. Si desea pintar fuera de los límites de la tabla, deberá anular el método paintComponent () para agregar una pintura personalizada.
Usa getCellRect( getRowCount() - 1, 0, true ).y
para obtener la coordenada y superior del espacio vacío, y luego pinta algunos rectángulos y líneas paintComponent( Graphics g )
) con paintComponent( Graphics g )
.
Para que sea mucho más fácil para ti, aquí hay una solución larga (pero completa) ;-)
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 );
}
}
Este ejemplo podría extenderse a:
- arregla la pseudo-cuadrícula pintada para RowHeights variable (estoy usando la altura más baja usada en cualquier fila)
- explique al usuario por qué no sucede nada si hace clic en el espacio vacío para editar las celdas (mediante la información sobre herramientas)
- agregue una fila adicional al modelo de tabla si el usuario hace clic en el espacio vacío (nooo! no Excel, por favor!)
- use el espacio vacío para dibujar un reflejo de la tabla (incluidos todos los datos renderizados (¿para qué? ;-))