根据列值更改 JTable 行的背景颜色

Posted

技术标签:

【中文标题】根据列值更改 JTable 行的背景颜色【英文标题】:Change background color of JTable row based on column value 【发布时间】:2014-09-10 23:13:29 【问题描述】:

嗨,我是 java jtable cellrendered 的新手。我正在寻找一种适用于我的程序的方法,但我没有找到它。 这是我的 Jtable

Employee ID   |   Name     |   Status    |   Position
  00565651        Roger       Active        Manager
  00565652        Gina        Active        Crew
  00565652        Alex        Inactive      Crew
  00565652        Seph        Active        Manager    

数据来自 ms access 数据库,但我想更改状态列中值为“非活动”的行的背景/前景。我在互联网上找到了很多例子,但所有这些在我的程序中都是不可能的。有人能帮我吗? 这是我的模型

String[] columnNames = "Employee ID","Name", "Status", "Position";
DefaultTableModel model = new DefaultTableModel(columnNames, 0);

这是创建我的表以及我如何从数据库中获取数据的方式

public MyList()//my constructor
    frame();
    loadListFromDB();

public void frame()//
   //codes for frame setsize,titles etc...
   tblList = new JTable();
   tblList.getTableHeader().setPreferredSize(new Dimension(100, 40));
   tblList.getTableHeader().setFont(new Font("SansSerif", Font.BOLD, 25));
   tblList.setAutoCreateRowSorter(true);
   tblList.setModel(model);
   scrollPane.setViewportView(tblList);
   loadListFromDB();


public void loadListFromDB()
   String sql = "SELECT emp_id,lname,fname,positional_status from tblEmployee";
    try
        PreparedStatement ps = conn.prepareStatement(sql);
        ResultSet rs = ps.executeQuery();
        while (rs.next())
            Vector row = new Vector();
            for (int i = 1; i <= 4; i++)
                row.addElement( rs.getObject(i) );
            
            model.addRow(row);
        
    catch(Exception err)
        //for error code
    

我想如何以这种方式添加 tableredered?谁能举个简单的例子来改变行的颜色?在此先感谢..我的程序停在这个问题上。

【问题讨论】:

How do I set the JTable column and row color?的可能重复 但是数据只是从一开始就初始化了,我的数据来自数据库,我不知道如何根据你的例子把我的数据放在 string[][] 中。 您的问题不是将数据放入表中,而是更改行颜色。您应该查看示例的 TableCellRenderer 部分 - 并将渲染添加到您的表格中。 你也可以看看Table Row Rendering 数据源无关;这是另一个example。 【参考方案1】:

“我想更改状态列中值为“inactive”的行的背景/前景”

这实际上只是从表/模型中获取价值的问题。如果该行的状态为非活动状态,则为该行中的每个单元格设置背景/前景。由于渲染器是为每个单元格渲染的,那么基本上您需要获取[row][statusColumn] 的值,这将是每一行的状态值。类似的东西

table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer()
    @Override
    public Component getTableCellRendererComponent(JTable table,
            Object value, boolean isSelected, boolean hasFocus, int row, int col) 

        super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);

        String status = (String)table.getModel().getValueAt(row, STATUS_COL);
        if ("active".equals(status)) 
            setBackground(Color.BLACK);
            setForeground(Color.WHITE);
         else 
            setBackground(table.getBackground());
            setForeground(table.getForeground());
               
        return this;
       
);

这是一个简单的例子

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;

import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

public class TableRowDemo 

    private static final int STATUS_COL = 1;

    private static JTable getTable() 
        final String[] cols = "col 1", "status", "col 3";
        final String[][] data = 
                "data", "active", "data",
                "data", "inactive", "data",
                "data", "inactive", "data",
                "data", "active", "data"
        ;
        DefaultTableModel model = new DefaultTableModel(data, cols);
        return new JTable(model) 
            @Override
            public Dimension getPreferredScrollableViewportSize() 
                return new Dimension(350, 150);
            
        ;
    

    private static JTable getNewRenderedTable(final JTable table) 
        table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer()
            @Override
            public Component getTableCellRendererComponent(JTable table,
                    Object value, boolean isSelected, boolean hasFocus, int row, int col) 
                super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
                String status = (String)table.getModel().getValueAt(row, STATUS_COL);
                if ("active".equals(status)) 
                    setBackground(Color.BLACK);
                    setForeground(Color.WHITE);
                 else 
                    setBackground(table.getBackground());
                    setForeground(table.getForeground());
                       
                return this;
               
        );
        return table;
    

    public static void main(String[] args) 
        SwingUtilities.invokeLater(new Runnable()
            public void run() 
                JOptionPane.showMessageDialog(null, new JScrollPane(getNewRenderedTable(getTable())));
            
        );
    

另一个选项是@Override prepareRenderer 的表。它会给你同样的结果。

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;

import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

public class TableRowDemo 

    private static final int STATUS_COL = 1;

    private static JTable getTable() 
        final String[] cols = "col 1", "status", "col 3";
        final String[][] data = 
                "data", "active", "data",
                "data", "inactive", "data",
                "data", "inactive", "data",
                "data", "active", "data"
        ;
        DefaultTableModel model = new DefaultTableModel(data, cols);
        return new JTable(model) 
            @Override
            public Dimension getPreferredScrollableViewportSize() 
                return new Dimension(350, 150);
            
            @Override
            public Component prepareRenderer(TableCellRenderer renderer, int row, int col) 
                Component c = super.prepareRenderer(renderer, row, col);
                String status = (String)getValueAt(row, STATUS_COL);
                if ("active".equals(status)) 
                    c.setBackground(Color.BLACK);
                    c.setForeground(Color.WHITE);
                 else 
                    c.setBackground(super.getBackground());
                    c.setForeground(super.getForeground());
                
                return c;
            
        ;
    

    public static void main(String[] args) 
        SwingUtilities.invokeLater(new Runnable()
            public void run() 
                JOptionPane.showMessageDialog(null, new JScrollPane(getTable()));
            
        );
    

【讨论】:

我一直在寻找的好答案。我们可以同时更改表格的标题样式吗? @peeskillet 如何修改准备渲染器方法以更改列而不是行的背景颜色? @peeskillet 当我使用你的代码时,我的表的选择发生了变化;它被设置为选择行现在它选择一个单元格,所选单元格的颜色也发生了变化,不再是默认颜色 我在线程 "AWT-EventQueue-0" java.lang.NullPointerException 在获取行值的行中遇到异常,String entry = (String) table.getModel().getValueAt(row, 2),请提供任何帮助,谢谢。 getTableCellRendererComponent 方法中,我是否(a)简单地调用super.getTableCellRendererComponent,然后通过调用superthis 的方法来更改我的格式,然后返回this(就像这个答案一样)或(b)声明一个新的Component x = super.getTableCellRendererComponent,然后将格式更改为x并返回x

以上是关于根据列值更改 JTable 行的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

如何更改 JTable 的空白空间颜色?

更改 JTable 中行的背景颜色

JTable/setDefaultRenderer 多选行

使用 CSS,如何根据我悬停的单元格更改表格行的背景颜色?

ASP.NET Razor HTML - 根据值更改表格行的背景颜色

背景排序JTable后,特定值的颜色不会改变