JTable with striped background

前端 未结 5 1345
北恋
北恋 2021-02-06 06:14

Using a different background color for odd and even rows is a commonly used trick to improve readability of large tables.

I want to use this effect in Swing\'s JTable.

5条回答
  •  悲哀的现实
    2021-02-06 06:46

    Use getCellRect( getRowCount() - 1, 0, true ).y to get the top y-coordinate of the empty space, and then paint some Rectangles and (Grid-)Lines with paintComponent( Graphics g ).

    jtable with empty space grid

    To make it much easier for you, here's a long (but complete) solution ;-)

    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 );
      }
    
    }
    

    This example could be extended to:

    • fix the painted pseudogrid for variable RowHeights (I'm using the lowest height used in any row)
    • explain to the user why nothing happens if he clicks in the empty space to edit the cells (via tooltip)
    • add an extra row to the table model if the user clicks in the empty space (nooo! no Excel please!)
    • use the empty space to draw a reflection of the table (including all rendered data ( what for? ;-) )

提交回复
热议问题