简体   繁体   English

动态更改JTable单元格的背景颜色

[英]Dynamically change the background color of a JTable cell

I want to change cell background color of JTable and want to fetch data from MySQL database. 我想更改JTable的单元格背景色,并想从MySQL数据库中获取数据。

I am using a data table in MySQL which has a status field. 我正在MySQL中使用一个具有状态字段的数据表。 If the status is 1 then cell background color should be red and if the status is 0 then it should change to red. 如果状态为1,则单元格背景色应为红色,如果状态为0,则应更改为红色。

id suggest a custom cell renderer to achieve what you want to. id建议使用自定义单元格渲染器来实现您想要的功能。

public class CellRenderer extends DefaultTableCellRenderer {

    private static final long serialVersionUID = 1L;

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

        if (column == /*your column number goes here*/) {
            this.setValue(table.getValueAt(row, column));
            this.setBackground(Color.RED);
        }
        return this;
    }
}

before you set the color, you can check the value if its 0 or 1 and then change the color if it is what you want 在设置颜色之前,您可以检查值是0还是1,然后根据需要更改颜色

How I created and filled/refilled a JTable with data from a database: 我如何用数据库中的数据创建和填充/重新填充JTable:

Table: 表:

private void createTable(Container pane) {
    Object[] namen = { "Datum", "Kategorie", "Essen", "Preise Intern", "Preise Extern" };
    model = new DefaultTableModel(namen, 0);
    table = new JTable(model) {

        public boolean isCellEditable(int x, int y) {
            return false;
        }
    };
    Dimension minimumSize = new Dimension(1000, 500);
    table.setPreferredScrollableViewportSize(minimumSize);
    TableRowSorter<DefaultTableModel> sorter = new TableRowSorter<DefaultTableModel>(model);
    table.setRowSorter(sorter);

    sorter.setComparator(3, Sorter.getComparator());
    sorter.setComparator(4, Sorter.getComparator());
    table.getColumnModel().getColumn(3).setCellRenderer(new CellRenderer()); //custom cell renderer
    table.getColumnModel().getColumn(4).setCellRenderer(new CellRenderer()); //custom cell renderer

    JScrollPane sp = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
}

and how i filled it: 以及我如何填充它:

void refreshTableContent(Vector<Gericht> v) {
    for (int i = table.getRowCount() - 1; i >= 0; i--) {
        model.removeRow(i);
    }
    fillTable(v);
}

void fillTable(Vector<Gericht> v) {
    for (int i = 0; i < v.size(); i++) {
        Gericht g = v.get(i);
        Vector<Object> vhelp = new Vector<>();
        vhelp.add(df.format(g.getDate()));
        vhelp.add(g.getClassification());
        vhelp.add(g.getName());
        vhelp.add(g.getPreisIntern());
        vhelp.add(g.getPreisExtern());
        model.addRow(vhelp);
    }
}

model is a DefaultTableModel on which you add and delete data. model是一个DefaultTableModel ,可以在上面添加和删除数据。 at every refill, i first delete all rows and then add them new. 在每次填充时,我首先删除所有行,然后将其添加为新行。 this is probably not the best solution but it works 这可能不是最好的解决方案,但它有效

the model is a meal in this case which has several fields. 在这种情况下,模型是一顿饭,它具有多个领域。 so i created a vector of my own object and then created a helping vector and stored the values of one meal in it. 所以我创建了自己的对象的向量,然后创建了一个帮助向量,并在其中存储了一顿饭的值。 then i added the vector as row to the JTable and the next meal was stored in the helping vector. 然后我将向量作为行添加到JTable中,下一顿饭存储在帮助向量中。

I hope you can understand what i did here 我希望你能理解我在这里所做的

//This is the code which I have used to change jtable cell background color dynamically
[green color indicates empty(free) cell and red color indicates occupied cells][1]
 int row, col, row1, column;
    TableCellRenderer renderer;
    private static final int STATUS_COL = 1;
String host = "jdbc:mysql://localhost/your_database";
        String username = "root";
        String password = "";
        Statement stmt = null;
try {
            Class.forName("com.mysql.jdbc.Driver");
            Connection connect = DriverManager.getConnection(host, username, password);
            stmt = connect.createStatement();
            String sql = "your query";
            ResultSet rs = stmt.executeQuery(sql);
            ResultSetMetaData meta = rs.getMetaData();
            Object[][] data = new Object[10][2];
            DefaultTableModel model = new DefaultTableModel(data, col);
            jTable1.setModel(DbUtils.resultSetToTableModel(rs));
            rs = stmt.executeQuery(sql);
 int rowCnt = 0;
              try{

       rs = stmt.executeQuery(sql);
       if(rs.last()){
           rowCnt = rs.getRow();
       } 
    } catch (Exception e){
       System.out.println("Error getting row count");
       e.printStackTrace();
    }

            int nCol = rs.getMetaData().getColumnCount();
            List<String[]> table = new ArrayList<>();
String[] row = new String[nCol];
for(int l=1; l<rowCnt; l++)
{
    for (int iCol = 1; iCol <= nCol; iCol++) {
                    Object obj = rs.getObject(iCol);
                    row[iCol - 1] = (obj == null) ? null : obj.toString();
jTable1.setDefaultRenderer(Object.class, new EntryCellRender());
 }
                table.add(row);
}
 } catch (Exception e) {
            System.out.println(e);
        }
    }
public class EntryCellRender extends DefaultTableCellRenderer {

    private final Color alt2 = Color.RED;
    private final Color alt1 = Color.GREEN;
    private final Color invalidStatus = Color.RED;

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        Component cr = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if ("".equals(table.getValueAt(row, col))) {
             setBackground(alt1);
           } else {
               setBackground(alt2);
           }

        return cr;
    }

    private Color colorAlternator(int row) {
        if ((row % 2) == 0) {
            return alt1;
        } else {
            return alt2;
        }
    }
}   

    enter code here

  [1]: https://i.stack.imgur.com/Fi4LF.png

As XtremeBaumer suggests, a custom cell renderer is a standard way to achieve what you want. 正如XtremeBaumer所建议的那样,自定义单元格渲染器是实现所需功能的标准方法。 Just remember that only one (1) instance of the cell renderer class is created and is used to render all the JTable cells. 只需记住,仅创建了一(1)个单元格渲染器类的实例,该实例用于渲染所有JTable单元格。
Good luck! 祝好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM