package apps.common.table; @SuppressWarnings("serial") public class JZebraTable extends javax.swing.JTable { private boolean drawStripes = false; private final java.awt.Color rowColors[] = new java.awt.Color[2]; public JZebraTable() { } public JZebraTable(int numRows, int numColumns) { super(numRows, numColumns); } public JZebraTable(java.util.Vector<?> rowData, java.util.Vector<?> columnNames) { super(rowData, columnNames); } public JZebraTable(javax.swing.table.TableModel dataModel) { super(dataModel); } public JZebraTable(javax.swing.table.TableModel dataModel, javax.swing.table.TableColumnModel columnModel) { super(dataModel, columnModel); } public JZebraTable(javax.swing.table.TableModel dataModel, javax.swing.table.TableColumnModel columnModel, javax.swing.ListSelectionModel selectionModel) { super(dataModel, columnModel, selectionModel); } public JZebraTable(Object[][] rowData, Object[] columnNames) { super(rowData, columnNames); } /** Force the table to fill the viewport's height. */ @Override public boolean getScrollableTracksViewportHeight() { final java.awt.Component p = getParent(); if (!(p instanceof javax.swing.JViewport)) { return false; } return ((javax.swing.JViewport) p).getHeight() > getPreferredSize().height; } /** Add stripes between cells and behind non-opaque cells. */ @Override public void paintComponent(java.awt.Graphics g) { if (!(drawStripes = isOpaque())) { super.paintComponent(g); return; } // Paint zebra background stripes updateZebraColors(); final java.awt.Insets insets = getInsets(); final int w = getWidth() - insets.left - insets.right; final int h = getHeight() - insets.top - insets.bottom; final int x = insets.left; int y = insets.top; int rowHeight = 16; // A default for empty tables final int nItems = getRowCount(); for (int i = 0; i < nItems; i++, y += rowHeight) { rowHeight = getRowHeight(i); g.setColor(rowColors[i & 1]); g.fillRect(x, y, w, rowHeight); } // Use last row height for remainder of table area final int nRows = nItems + (insets.top + h - y) / rowHeight; for (int i = nItems; i < nRows; i++, y += rowHeight) { g.setColor(rowColors[i & 1]); g.fillRect(x, y, w, rowHeight); } final int remainder = insets.top + h - y; if (remainder > 0) { g.setColor(rowColors[nRows & 1]); g.fillRect(x, y, w, remainder); } // Paint component setOpaque(false); super.paintComponent(g); setOpaque(true); } /** Add background stripes behind edited cells. */ @Override public java.awt.Component prepareEditor(javax.swing.table.TableCellEditor editor, int row, int col) { final java.awt.Component c = super.prepareEditor(editor, row, col); if (drawStripes && !isCellSelected(row, col)) { c.setBackground(rowColors[row & 1]); } return c; } /** Add background stripes behind rendered cells. */ @Override public java.awt.Component prepareRenderer(javax.swing.table.TableCellRenderer renderer, int row, int col) { final java.awt.Component c = super.prepareRenderer(renderer, row, col); if (drawStripes && !isCellSelected(row, col)) { c.setBackground(rowColors[row & 1]); } return c; } /** Compute zebra background stripe colors. */ private void updateZebraColors() { if ((rowColors[0] = getBackground()) == null) { rowColors[0] = rowColors[1] = java.awt.Color.white; return; } final java.awt.Color sel = getSelectionBackground(); if (sel == null) { rowColors[1] = rowColors[0]; return; } final float[] bgHSB = java.awt.Color.RGBtoHSB(rowColors[0].getRed(), rowColors[0].getGreen(), rowColors[0].getBlue(), null); final float[] selHSB = java.awt.Color.RGBtoHSB(sel.getRed(), sel.getGreen(), sel.getBlue(), null); rowColors[1] = java.awt.Color.getHSBColor(((selHSB[1] == 0.0) || (selHSB[2] == 0.0)) ? bgHSB[0] : selHSB[0], 0.1f * selHSB[1] + 0.9f * bgHSB[1], bgHSB[2] + ((bgHSB[2] < 0.5f) ? 0.05f : -0.05f)); } }