在Java JTable中更改行的颜色

时间:2019-03-07 12:08:02

标签: java colors jtable row customization

我正在尝试更改Java JTable中行的颜色,但是遇到了一些问题。这是这种情况:我有一个表,其中包含一些要处理的数据,并且我希望在处理结束时(通过按钮开始),通过根据结果将行涂成绿色,黄色或红色来更新表的操作。每个处理的对象都有一个在处理后设置的变量“结果”。该表由Netbeans的图形编辑器创建(因此无法修改自动生成的代码)。我使用了这个TableModel:

public class QuotationsTableModel extends AbstractTableModel {

    private List<Quotation> quotationsList;

    public QuotationsTableModel(List<Quotation> quotationsList) {
        this.quotationsList= quotationsList;
    }

    @Override
    public int getRowCount() {
        if (quotationsList== null) {
            return 0;
        }
        return this.quotationsList.size();
    }

    @Override
    public int getColumnCount() {
        return 4;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        if (quotationsList== null) {
            return null;
        }
        Quotation quotation = quotationsList.get(rowIndex);
        if (columnIndex == 0) {
            return quotation.getQuotationNumber();
        }
        if (columnIndex == 1) {
            return quotation.getBillingType();
        }
        if (columnIndex == 2) {
            return quotation.getAdvance();
        }
        if (columnIndex == 3) {
            return quotation.getOutcome();
        }
        return null;
    }

    @Override
    public String getColumnName(int column) {
        if (column == 0) {
            return "Number";
        } else if (column == 1) {
            return "Billing type";
        } else if (column == 2) {
            return "Advance";
        } else if (column == 3) {
            return "Outcome";
        }
        return null;
    }

    public void updateTable() {
        this.fireTableDataChanged();
    }

我试图通过创建类来达到目标​​:

public class CustomTableRenderer extends DefaultTableCellRenderer {

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

        Component original = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        Color background = table.getBackground();
        //Color grid = Color.YELLOW;

        Color fg = null;
        Color bg = null;


        if (isSelected) {
            super.setForeground(fg == null ? table.getSelectionForeground()
                                           : fg);
            super.setBackground(bg == null ? table.getSelectionBackground()
                                           : bg);
        } else {
            if (column == 3) {
                String outcome = String.valueOf(value);
                if (outcome .equalsIgnoreCase("COMPLETED")){
                  background = Color.GREEN;
                } else if (outcome .equalsIgnoreCase("PARTIAL")) {
                    background = Color.YELLOW;
                } else if (outcome .equalsIgnoreCase("ERROR")) {
                    background = Color.RED;
                }
            }
        }
    original.setBackground(background);

    return original;
    }

然后致电:

QuotationsTableModel quotationsTableModel= new QuotationsTableModel(quotationsList);
this.quotationsTable.setModel(quotationsTableModel);
this.quotationsTable.setDefaultRenderer(Object.class, new CustomTableRenderer());

,但结果仅在选择行时才有颜色,此外,一旦选择了行,除结果外所有值都会消失。你能帮我吗?

我找到了一个可行的解决方案,也许它将对以后的人们有用:

import java.awt.Color;
import java.awt.Component;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

public class CustomTableCellRenderer extends DefaultTableCellRenderer {


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


        Component original = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        Color background = table.getBackground();

        if (isSelected) {            
            original.setBackground(javax.swing.UIManager.getDefaults().getColor("TextField.selectionBackground"));
            original.setForeground(javax.swing.UIManager.getDefaults().getColor("TextField.selectionForeground"));
            table.setRowSelectionInterval(row, row);            
        } else {
            original.setBackground(javax.swing.UIManager.getDefaults().getColor("TextField.highlight"));
            original.setForeground(Color.BLACK);        
            if (column == 3) {
                String outcome = String.valueOf(value);
                if (outcome.equalsIgnoreCase("COMPLETED")){
                  background = Color.GREEN;
                } else if (outcome.equalsIgnoreCase("PARTIAL")) {
                    background = Color.YELLOW;
                } else if (outcome.equalsIgnoreCase("ERROR")) {
                    background = Color.RED;
                }
                original.setBackground(background);
            }
        }

    return original;
    }
}

谢谢。

1 个答案:

答案 0 :(得分:0)

我使用您的QuotationsTableModelCustomTableRenderer类创建了以下示例程序。我看到的唯一问题是在CustomTableRenderer.getTableCellRendererComponent()方法中。

仅当未选择该行时,才更改“结果”列的颜色。因此,选择行时无法进行着色。为解决此问题,我删除了代码的if (isSelected) {部分。运行下面的示例,看看。

(将来发布问题时,请像下面的示例程序一样发布一个最小的可执行程序。这样其他人就可以更轻松地运行场景并查看问题。)

import javax.swing.*;
import javax.swing.table.*;
import java.awt.Color;
import java.awt.Component;
import java.util.ArrayList;
import java.util.List;

public class ColorTable {

  public static void main(String[] args) {
    List<Quotation> quotationsList = new ArrayList<>();
    quotationsList.add(new Quotation(111, "AA", 2500, "COMPLETED"));
    quotationsList.add(new Quotation(222, "BB", 4000, "PARTIAL"));
    quotationsList.add(new Quotation(333, "CC", 5000, "COMPLETED"));
    quotationsList.add(new Quotation(444, "DD", 1500, "SOME_OTHER_OUTCOME"));
    quotationsList.add(new Quotation(555, "EE", 3500, "ERROR"));
    QuotationsTableModel quotationsTableModel= new QuotationsTableModel(quotationsList);

    JTable quotationsTable = new JTable();
    quotationsTable.setModel(quotationsTableModel);
    quotationsTable.setDefaultRenderer(Object.class, new CustomTableRenderer());

    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(new JScrollPane(quotationsTable));
    frame.pack();
    frame.setVisible(true);
  }
}

class QuotationsTableModel extends AbstractTableModel {

  private List<Quotation> quotationsList;

  public QuotationsTableModel(List<Quotation> quotationsList) {
    this.quotationsList= quotationsList;
  }

  @Override
  public int getRowCount() {
    if (quotationsList== null) {
      return 0;
    }
    return this.quotationsList.size();
  }

  @Override
  public int getColumnCount() {
    return 4;
  }

  @Override
  public Object getValueAt(int rowIndex, int columnIndex) {
    if (quotationsList== null) {
      return null;
    }
    Quotation quotation = quotationsList.get(rowIndex);
    if (columnIndex == 0) {
      return quotation.getQuotationNumber();
    }
    if (columnIndex == 1) {
      return quotation.getBillingType();
    }
    if (columnIndex == 2) {
      return quotation.getAdvance();
    }
    if (columnIndex == 3) {
      return quotation.getOutcome();
    }
    return null;
  }

  @Override
  public String getColumnName(int column) {
    if (column == 0) {
      return "Number";
    } else if (column == 1) {
      return "Billing type";
    } else if (column == 2) {
      return "Advance";
    } else if (column == 3) {
      return "Outcome";
    }
    return null;
  }

  public void updateTable() {
    this.fireTableDataChanged();
  }
}

class CustomTableRenderer extends DefaultTableCellRenderer {

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

    Component original = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    Color background = table.getBackground();
    //Color grid = Color.YELLOW;

    if (column == 3) {
      String outcome = String.valueOf(value);
      if (outcome .equalsIgnoreCase("COMPLETED")){
        background = Color.GREEN;
      } else if (outcome .equalsIgnoreCase("PARTIAL")) {
        background = Color.YELLOW;
      } else if (outcome .equalsIgnoreCase("ERROR")) {
        background = Color.RED;
      }
    }
    original.setBackground(background);

    return original;
  }
}

class Quotation {
  private int quotationNumber;
  private String billingType;
  private int advance;
  private String outcome;

  Quotation(int quotationNumber, String billingType, int advance, String outcome) {
    this.quotationNumber = quotationNumber;
    this.billingType = billingType;
    this.advance = advance;
    this.outcome = outcome;
  }

  int getQuotationNumber() {
    return quotationNumber;
  }

  String getBillingType() {
    return billingType;
  }

  int getAdvance() {
    return advance;
  }

  String getOutcome() {
    return outcome;
  }
}

输出:

enter image description here