JTable с чередуемым фоном

Используя другой цвет фона для четных и нечетных строк наиболее часто используемый прием для улучшения удобочитаемости больших таблиц.

Я хочу использовать этот эффект в JTable Swing. Я начал путем создания пользовательского рендерера таблицы, но это может только использоваться для рисования фактических ячеек, и я также хочу добавить дорожки к "белой" части таблицы, где не могло бы быть никаких ячеек. Я могу разделить JTable на подклассы и переопределить paintComponent (), но я предпочел бы опцию, где я могу просто изменить рендеринг таблицы.

Существует ли лучший способ сделать это?

Править: Согласно ответам до сих пор это, кажется, невозможно, не расширяя JTable. Однако, когда я переопределяю JTable.paintComponent (), он также только красит область, где существуют строки. Как я могу нарисовать остальных?

8
задан Kees Kist 8 July 2010 в 08:44
поделиться

5 ответов

Используйте getCellRect (getRowCount () - 1, 0, true) .y , чтобы получить верхнюю координату y пустого пространства, а затем нарисуйте несколько прямоугольников и ( Сетка-) Линии с paintComponent (Графика g) .

jtable with empty space grid

Чтобы упростить вам задачу, вот длинное (но полное) решение; -)

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

}

Этот пример можно расширить до:

  • исправить нарисованную псевдосетку для переменной RowHeights (я использую наименьшую высоту используется в любой строке)
  • объясняют пользователю, почему ничего не происходит, если он щелкает в пустом пространстве для редактирования ячеек (с помощью всплывающей подсказки)
  • добавляет дополнительную строку в модель таблицы, если пользователь щелкает в пустом пространстве ( нет, пожалуйста, без Excel!)
  • используйте пустое пространство, чтобы нарисовать отражение таблицы (включая все визуализированные данные (зачем? ;-))
4
ответ дан 5 December 2019 в 20:13
поделиться

Используйте концепции рендеринга строки таблицы , которые проще, чем иметь дело с отдельными рендерерами.

Этот подход работает только для визуализированных ячеек. Если вы хотите рисовать за пределами таблицы, вам нужно будет переопределить метод paintComponent (), чтобы добавить пользовательское рисование.

1
ответ дан 5 December 2019 в 20:13
поделиться

Вы также можете использовать пользовательский 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 в основном сложные рендереры, они по-прежнему обслуживают только ячейки.

Чтобы расширить пространство, я вижу только следующие возможности:

  • нарисуйте его самостоятельно, в своем собственном компоненте.
  • «взломать» способ, добавив поддельный последний столбец с настраиваемым JTableHeader, который не отображал бы заголовок последнего столбца (и средство визуализации, избегающее сетки для этого последнего столбца). Кроме того, в этом случае режим изменения размера таблицы должен быть AUTO_RESIZE_LAST_COLUMN. Это много условий, чтобы заставить его работать, и я не совсем уверен, что это сработает в любом случае.
1
ответ дан 5 December 2019 в 20:13
поделиться

Либо используйте JXTable, либо, если вы супер-ленивый (или супер-нехватка времени :-)), вы можете просто использовать "Nimbus" look-and-feel, JTable выглядит там ободранным по умолчанию :)

0
ответ дан 5 December 2019 в 20:13
поделиться

JXtable, предоставляемый swingx, позволяет реализовать такой рендеринг. Посмотрите на http://swinglabs.org/docs/components/JXTable/tutorial.jsp?step=3#RowHighlighting

2
ответ дан 5 December 2019 в 20:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: