【问题标题】:Coloring jTable row为 jTable 行着色
【发布时间】:2012-06-23 13:00:52
【问题描述】:

我想为 jTable 中的特定行着色..我通过使用此代码对列进行了着色,

private class CustomCellRenderer extends DefaultTableCellRenderer {

/* (non-Javadoc)
 * @see    
javax.swing.table.DefaultTableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
 */

    @Override
public Component  getTableCellRendererComponent(JTable table, Object value,boolean isSelected, boolean hasFocus, int row, int column) {

  Component rendererComp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus,row, column);

//Set foreground color
// rendererComp.setForeground(Color.red);
//Set background color
  rendererComp .setBackground(Color.pink);

 return rendererComp ;
 }

}

我调用上面的代码使用,

 jTable1.getColumnModel().getColumn(3).setCellRenderer(new CustomCellRenderer());

但是我想对 jTable 中的行做同样的事情。在行的情况下没有 getColumnModel() 或 getColumn() 。那么这样做的替代方法是什么?我正在使用 Java Swing 在 Netbeans 中进行操作。

【问题讨论】:

    标签: java swing jtable tablecellrenderer


    【解决方案1】:

    这似乎是一种非常肮脏的处理方式。如果您使用布局管理器为您的容器使用gridLayout,那将是一个更好的主意(我认为它必须是一个JFrame)。您可以添加单独的组件(JPanels、Jbuttons 或任何其他 JComponent)并使用 paint()/repaint() 方法处理它们的外观。

    编辑

    您可以更改 getTableCellRendererComponent(....) 方法以使用嵌套的 if-else 语句或根据 int 行、int 列(即作为参数提供)。

    这会容易得多

    【讨论】:

    • 我看不出这有多脏。相反,使用 JTable 显示 TableData 实际上是一种很好的做法。人们经常使用复杂的布局和面板来显示 TableData。
    • 使用 JTable 很好,但你应该实现接口 TableCellRenderer 而不是继承整个类
    • 这样做有什么意义?使用 DefaultTableCellRenderer,您还可以自动获得适当的 L&F 相关颜色(不同 L&F/平台的背景选择颜色不同)。除非渲染实际上不是 JLabel 而是更复杂的东西,否则我不明白为什么不重用已经存在的东西。
    【解决方案2】:

    这是一个关于如何结合列颜色和行颜色的示例。您基本上在 TableCellRenderer 中执行测试以查看背景是否应该是一种颜色或另一种颜色。

    import java.awt.Color;
    import java.awt.Component;
    import java.util.Enumeration;
    import java.util.Vector;
    
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.SwingUtilities;
    import javax.swing.table.DefaultTableCellRenderer;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableCellRenderer;
    import javax.swing.table.TableColumn;
    
    public class TestTable {
    
        public class MyTableCellRenderer extends DefaultTableCellRenderer implements TableCellRenderer {
    
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                setBackground(null);
                super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                setText(String.valueOf(value));
                boolean interestingRow = row % 5 == 2;
                boolean secondColumn = column == 1;
                if (interestingRow && secondColumn) {
                    setBackground(Color.ORANGE);
                } else if (interestingRow) {
                    setBackground(Color.YELLOW);
                } else if (secondColumn) {
                    setBackground(Color.RED);
                }
                return this;
            }
    
        }
    
        private JFrame f;
        private JTable table;
    
        protected void initUI() {
            Vector<Vector<Object>> data = new Vector<Vector<Object>>();
            Vector<String> columNames = new Vector<String>();
            columNames.add("Col 0");
            columNames.add("Col 1");
            columNames.add("Col 2");
            for (int i = 0; i < 20; i++) {
                Vector<Object> v = new Vector<Object>();
                v.add(i % 3 == 0 ? "Hello" : "World");
                v.add("Some data in row " + (i + 1));
                v.add("Some other data in row " + (i + 1));
                data.add(v);
            }
            table = new JTable(new DefaultTableModel(data, columNames));
            Enumeration<TableColumn> en = table.getColumnModel().getColumns();
            while (en.hasMoreElements()) {
                TableColumn tc = en.nextElement();
                tc.setCellRenderer(new MyTableCellRenderer());
            }
            f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setLocationRelativeTo(null);
            f.add(new JScrollPane(table));
            f.pack();
            f.setVisible(true);
    
        }
    
        public static void main(String[] args) {
    
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new TestTable().initUI();
                }
            });
        }
    
    }
    

    【讨论】:

    • for(int i=0;i
    • @Tickua 我不确定我是否理解您的评论。在getTableCellRendereComponent 方法中,您可以访问您可能需要的所有信息:JTable、单元格的当前值、单元格在表格中的位置(行和列),以及当前行是否被选中如果当前单元格被聚焦。您还可以从表中访问您的 TableModel (table.getModel())。我认为从那里计算你想要的任何条件并设置适当的背景颜色应该很容易。
    • 我知道..但我的问题是如何通过指定我的第 i 行和第 1 列来调用方法 getTableCellRendereComponent()..我也尝试过这种方式..final CustomCellRenderer renderer =新的 CustomCellRenderer(); , renderer.getTableCellRendererComponent(jTable1, 1, true,true, i, 1);
    • @Tickua 您不自己调用 TableCellRenderer,而是让 JTable 为您做这件事。它会在第一次需要渲染时自动调用你的所有行,然后通过触发适当的 TableModel 事件,它最终会重新调用你的 TableCellRenderer。如果您对此仍有疑问,请考虑阅读this tutorial 或在 SO 上发布另一个问题。
    • 根据您的示例,行着色正在工作,但存在一个问题..您能帮帮我
    【解决方案3】:

    如果您想更改整行,而不管列类如何,请考虑覆盖prepareRenderer(),如here 所述。 TableCellRendererprepareRenderer() 方法对比 here

    【讨论】: