java AbstractTableModel 2每行不同的颜色

我想提高我的jtable的可读性,下面是MyTableModel.java类,如何使每个行中有2种不同的颜色显示在这张图片中 。 应该具体的方法是,我可以为每一行提供不同的颜色,以提高用户的可读性。

public class MyTableModel extends AbstractTableModel{ String [] columnNames; Vector<Vector> data; public DataAccessObject ObjDb = new DataAccessObject (); public MyTableModel(String [] coln , Vector<Vector> data) { columnNames = coln; this.data =data; } @Override public int getColumnCount() { return columnNames.length; } @Override public int getRowCount() { return data.size(); } @Override public String getColumnName(int col) { return columnNames[col]; } public Object getValueAt(int row, int col) { return data.get(row).get(col); } public Class getColumnClass(int c) { return getValueAt(0, c).getClass(); } public boolean isCellEditable(int row, int col) { if (col <= 0) { return true; } else { return true; } } public void setValueAt(Object value, int row, int col) { data.get(row).set(col, value); fireTableCellUpdated(row, col); } private class RowListener implements ListSelectionListener { public void valueChanged(ListSelectionEvent event) { if (event.getValueIsAdjusting()) { return; } // output.append("ROW SELECTION EVENT. "); // outputSelection(); } } private class ColumnListener implements ListSelectionListener { public void valueChanged(ListSelectionEvent event) { if (event.getValueIsAdjusting()) { return; } // output.append("COLUMN SELECTION EVENT. "); // outputSelection(); } } } 

Netbeans自动创建了我的jtable,其变量名称我设置为mytable然后我在下面定义prepareRenderer时遇到问题,我是否会错过这里的步骤? 我想做
每行有不同的颜色这是我的示例代码如下。

  mytable.prepareRenderer(TableCellRenderer renderer, int row, int column) { Component c = super.prepareRenderer(renderer, row, column); // Alternate row color if (!isRowSelected(row)) c.setBackground(row % 2 == 0 ? getBackground() : Color.LIGHT_GRAY); return c; } }; 

我也使用这个,但这设置5列我有7列剩下两个不是
最后点亮,当我点击白色的行时,文字颜色消失。

  mytable.setDefaultRenderer(Object.class, new TableCellRenderer() { private DefaultTableCellRenderer DEFAULT_RENDERER = new DefaultTableCellRenderer(); @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component c = DEFAULT_RENDERER.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); System.out.println(column); if (row % 2 == 0) { c.setBackground(Color.WHITE); } else { c.setBackground(Color.LIGHT_GRAY); } return c; } }); 

你可以…

使用SwingLabs中的 JXTable ,SwingX库 ,它具有可以执行此操作的function……如果您可以使用第三方库,这将是我的首选解决方案…

你可以…

使用Nimbus外观和感觉这样做……但是这使您无法使用其他外观(如系统的外观和感觉)

你可以…

创建自己的自定义TableCellRenderer系列,根据当前行为其背景着色…这可能是您需要的每个单元格渲染器,需要能够执行此操作…

你可以…

覆盖JTableprepareCellRenderer方法并根据行强制设置单元格渲染器的背景…我不是这个解决方案的粉丝,因为它强制设计选择到渲染器上,这可能不符合它的要求(覆盖单元格渲染器可能需要的值)并将您锁定到表的特定实现中…

你可以…

创建一个JViewport ,它能够与JTable交谈,并在桌子底下呈现糖果剥离,但桌子和渲染器需要透明……我已经完成了这个,它……复杂……但允许我继续糖果剥离视口的全长(超出桌子的可渲染区域)……

更新了JViewport示例

这是我前一段时间为一个项目实现的一个概念的例子(它实际上是由一个interface管理的,所以我也可以包含JListJTextArea ,但这是另一个问题)……

基本上,它使得出现在JTable下面的JViewport负责渲染实际的糖果剥离。

但为什么?” 你问…因为它不会影响表格或单元格渲染器。 这样做的唯一要求是表和单元格渲染器都是透明的(除非必须这样)。

这意味着,您不需要在渲染器中放置糖果剥离逻辑,这意味着您不需要覆盖您创建的每个表的prepareRenderer单元格渲染器的要求……

它远非完美,但展示了基本理念……

CandyStripped

好的,但为什么要这么麻烦? 嗯,基本上,这种方法可以让你画画超出桌子绘制的区域……

CandyStripping

 import java.awt.Color; import java.awt.Component; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JViewport; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; public class CandyStrippedTable { public static void main(String[] args) { new CandyStrippedTable(); } public CandyStrippedTable() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } Object[] columns = new Object[10]; for (int col = 0; col < columns.length; col++) { columns[col] = (char) (65 + col); } Object[][] data = new Object[10][10]; for (int row = 0; row < data.length; row++) { for (int col = 0; col < data[row].length; col++) { data[row][col] = row + "x" + col; } } DefaultTableModel model = new DefaultTableModel(data, columns); JTable table = new JTable(model); table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); setOpaque(isSelected); return this; } }); table.setFillsViewportHeight(true); table.setOpaque(false); JScrollPane sp = new JScrollPane(); sp.setViewport(new CandyStrippedViewPort(new Color(255, 0, 0, 128))); sp.setViewportView(table); JFrame frame = new JFrame("Test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(sp); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class CandyStrippedViewPort extends JViewport { private Color candyStrippedColor; public CandyStrippedViewPort(Color color) { candyStrippedColor = color; } public Color getCandyStrippedColor() { return candyStrippedColor; } public void setCandyStrippedColor(Color candyStrippedColor) { this.candyStrippedColor = candyStrippedColor; repaint(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); g2d.setColor(getCandyStrippedColor()); Component view = getView(); if (view instanceof JTable) { JTable table = (JTable) view; Rectangle viewRect = getViewRect(); int y = 0; int row = 0; if (table.getRowCount() > 0) { row = table.rowAtPoint(viewRect.getLocation()); while (row < table.getRowCount()) { int rowHeight = table.getRowHeight(row); Rectangle cellRect = table.getCellRect(row, 0, true); if (row % 2 == 0) { g2d.fillRect(0, cellRect.y - viewRect.y, getWidth(), cellRect.height); } y = cellRect.y + cellRect.height; row++; } } int rowHeight = table.getRowHeight(); while (y < getHeight()) { if (row % 2 == 0) { g2d.fillRect(0, y, getWidth(), rowHeight); } row++; y += rowHeight; } } g2d.dispose(); } } } 

格式化单元格渲染器中的数字

你可以从......开始

 obj.table.setDefaultRenderer(Double.class, new DefaultTableCellRenderer() { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (value instanceof Number) { value = NumberFormat.getNumberInstance().format(value); } super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); setOpaque(isSelected); return this; } }); 

如果由于某种原因,默认格式适合,你可以做类似......

 obj.table.setDefaultRenderer(Double.class, new DefaultTableCellRenderer() { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (value instanceof Number) { NumberFormat ni = NumberFormat.getNumberInstance(); ni.setMaximumFractionDigits(2) value = ni.format(value); } super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); setOpaque(isSelected); return this; } }); 

代替

请参阅Camick制作的Table Row Rendering 。 它会解决你的问题。

您可以使用他的方法createAlternating来渲染行的颜色。

  private JComponent createAlternating(DefaultTableModel model) { JTable table = new JTable( model ) { public Component prepareRenderer(TableCellRenderer renderer, int row, int column) { Component c = super.prepareRenderer(renderer, row, column); // Alternate row color if (!isRowSelected(row)) c.setBackground(row % 2 == 0 ? getBackground() : Color.LIGHT_GRAY); return c; } }; table.setPreferredScrollableViewportSize(table.getPreferredSize()); table.changeSelection(0, 0, false, false); return new JScrollPane( table ); } 

很久以前,我遇到了同样的问题。

在这种情况下,我使用swingX库中的JXTable而不是JTable。 这个组件有一个很好的方法:

 addHighlighter(HighlighterFactory.createSimpleStriping()); 

祝你好运