Nimbus和备用行颜色

我不明白Nimbus中的替代行着色是如何工作的。 看起来真的很疯狂! 我想在这里澄清一切。

对于演示,让我们说我们想要一个交替红色和粉红色行的JTable (我不关心哪个颜色是第一个)。

如果没有重新定义执行自己的“模2”的自定义cellRenderer ,并且没有覆盖JTable的任何方法,我想列出启动一个应用程序和使用Nimbus属性获得具有自定义备用行颜色的JTable之间的必要步骤。

以下是我希望遵循的步骤:

  1. 安装Nimbus PLAF
  2. 自定义“Table.background”nimbus属性
  3. 自定义“Table.alternateRowColor”nimbus属性
  4. 使用简单的数据/标头创建JTable
  5. 将jTable包装在JScrollPane中并将其添加到JFrame
  6. 显示JFrame

这里的源代码:


public class JTableAlternateRowColors implements Runnable { public static void main(String[] args) { SwingUtilities.invokeLater(new JTableAlternateRowColors()); } @Override public void run() { try { UIManager.setLookAndFeel(new NimbusLookAndFeel()); } catch (UnsupportedLookAndFeelException e) { e.printStackTrace(); } UIManager.getDefaults().put("Table.background", Color.RED); UIManager.getDefaults().put("Table.alternateRowColor", Color.PINK); final JFrame jFrame = new JFrame("Nimbus alternate row coloring"); jFrame.getContentPane().add(new JScrollPane(new JTable(new String[][] { {"one","two","three"}, {"one","two","three"}, {"one","two","three"} }, new String[]{"col1", "col2", "col3"} ))); jFrame.setSize(400, 300); jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); jFrame.setVisible(true); } } 

这是JDK6代码。 谁能告诉我这里出错了?


根据@ kleopatra的评论以及整个社区的贡献,这里是使用Nimbus属性获得备用行着色的方法

public class JTableAlternateRowColors实现Runnable {

 public static void main(String[] args) { SwingUtilities.invokeLater(new JTableAlternateRowColors()); } @Override public void run() { try { UIManager.setLookAndFeel(new NimbusLookAndFeel()); } catch (UnsupportedLookAndFeelException e) { e.printStackTrace(); } UIManager.put("Table.background", new ColorUIResource(Color.RED)); UIManager.put("Table.alternateRowColor", Color.PINK); UIManager.getLookAndFeelDefaults().put("Table:\"Table.cellRenderer\".background", new ColorUIResource(Color.RED)); final JFrame jFrame = new JFrame("Nimbus alternate row coloring"); final JTable jTable = new JTable(new String[][]{ {"one", "two", "three"}, {"one", "two", "three"}, {"one", "two", "three"} }, new String[]{"col1", "col2", "col3"}); jTable.setFillsViewportHeight(true); jFrame.getContentPane().add(new JScrollPane(jTable)); jFrame.setSize(400, 300); jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); jFrame.setVisible(true); } 

}

看起来像几个bug的干扰……

要更改默认表格背景和默认条带化,UIManager的预期(不仅是你的,我的)配置(对于所有尊重alternateRow属性的LAF也是如此)将是:

 UIManager.put("Table.background", Color.RED); UIManager.put("Table.alternateRowColor", Color.PINK); 

对金属和Nimbus都不起作用

  • 金属:没有条纹,桌子都是红色的
  • 在Nimbus中:条纹白色/粉红色,即表格背景被忽略

第一个的基本原因可以在DefaultTableCellRenderer中找到:

 Color background = unselectedBackground != null ? unselectedBackground : table.getBackground(); if (background == null || background instanceof javax.swing.plaf.UIResource) { Color alternateColor = DefaultLookup.getColor(this, ui, "Table.alternateRowColor"); if (alternateColor != null && row % 2 != 0) { background = alternateColor; } } 

它的逻辑是弯曲的:只有当桌子的背景是​​colorUIResource时才采用替代颜色,这是一个相当弱的区别。 无论如何,它引导我们下一次尝试:

 UIManager.put("Table.background", new ColorUIResource(Color.RED)); UIManager.put("Table.alternateRowColor", Color.PINK); 

这看起来很好(除了复选框渲染器的典型问题,但这是另一个错误的故事;-)对于金属,仍然没有运气Nimbus。

下一步是查找可能相关的Nimbus默认值 ,并应用(在设置LAF之后):

 UIManager.getLookAndFeelDefaults().put("Table:\"Table.cellRenderer\".background", new ColorUIResource(Color.RED)); 

编辑 (如评论中所述)

JXTable试图完全解决问题 – 它的条带化手段是从HighlighterFactory中检索到的Highlighter。 需要通过从lookAndFeelDefaults中删除alternateRowColor属性并使用新键“UIColorHighlighter.stripingBackground”添加它来弄脏Nimbus

使用Nimbus属性(+1到@Kleopatracertificate我错了:()你可以设置交替的行颜色

 UIManager.put("Table.alternateRowColor", Color.PINK); UIManager.getLookAndFeelDefaults().put("Table:\"Table.cellRenderer\".background", Color.RED); 

或者通过:

扩展JTable并覆盖prepareRenderer(TableCellRenderer renderer, int row, int column) ,以便为单元格绘制所需的颜色( REDPINK )。

这是一个简短的例子我希望它有所帮助。

额外function:它还会覆盖paintComponent(..) ,它将调用paintEmptyRows(Graphics g) ,它将为JScrollPane视口的整个高度和宽度绘制行,但这仅适用于MyTablesetFillsViewPortHeight设置为true的情况:

在此处输入图像描述

 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.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.WindowConstants; import javax.swing.plaf.nimbus.NimbusLookAndFeel; import javax.swing.table.TableCellRenderer; public class JTableAlternateRowColors { public JTableAlternateRowColors() { initComponents(); } public static void main(String[] args) { try { UIManager.setLookAndFeel(new NimbusLookAndFeel()); } catch (UnsupportedLookAndFeelException e) { e.printStackTrace(); } SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new JTableAlternateRowColors(); } }); } private void initComponents() { final JFrame jFrame = new JFrame("Nimbus alternate row coloring"); MyTable table = new MyTable(new String[][]{ {"one", "two", "three"}, {"one", "two", "three"}, {"one", "two", "three"} }, new String[]{"col1", "col2", "col3"}); table.setFillsViewportHeight(true);//will fill the empty spaces too if any table.setPreferredScrollableViewportSize(table.getPreferredSize()); JScrollPane jScrollPane = new JScrollPane(table); jFrame.getContentPane().add(jScrollPane); jFrame.pack(); jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); jFrame.setVisible(true); } } class MyTable extends JTable { public MyTable(String[][] data, String[] fields) { super(data, fields); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); if (getFillsViewportHeight()) { paintEmptyRows(g); } } /** * Paints the backgrounds of the implied empty rows when the table model is * insufficient to fill all the visible area available to us. We don't * involve cell renderers, because we have no data. */ protected void paintEmptyRows(Graphics g) { final int rowCount = getRowCount(); final Rectangle clip = g.getClipBounds(); if (rowCount * rowHeight < clip.height) { for (int i = rowCount; i <= clip.height / rowHeight; ++i) { g.setColor(colorForRow(i)); g.fillRect(clip.x, i * rowHeight, clip.width, rowHeight); } } } /** * Returns the appropriate background color for the given row. */ protected Color colorForRow(int row) { return (row % 2 == 0) ? Color.RED : Color.PINK; } /** * Shades alternate rows in different colors. */ @Override public Component prepareRenderer(TableCellRenderer renderer, int row, int column) { Component c = super.prepareRenderer(renderer, row, column); if (isCellSelected(row, column) == false) { c.setBackground(colorForRow(row)); c.setForeground(UIManager.getColor("Table.foreground")); } else { c.setBackground(UIManager.getColor("Table.selectionBackground")); c.setForeground(UIManager.getColor("Table.selectionForeground")); } return c; } } 

参考文献: