简体   繁体   English

如何在JTable中用不同的颜色绘制特定的列?

[英]How do I to paint a specific column with different colors in JTable?

I have a JTable and I want to paint a column with different colors depending value of cell. 我有一个JTable,我想根据单元格的值用不同的颜色绘制一列。 To make it I am trying to create a ´TableCellRender´ but cannot make it works, the values seems hidding after ´setDefaultRenderer´. 为此,我试图创建一个“ TableCellRender”,但无法使其正常工作,“ setDefaultRenderer”之后的值似乎是隐藏的。

How could I do it works ? 我该如何运作?

trying

TableModel 表格模型

public class PartidasTableModel extends AbstractTableModel{
    private List<Partida> lista;
    private String[] colunas = {"Data ", "Casa x Visitante ", "Banca Inicial ", "Banca Final ", "Saldo ",  "Green/Red "};
    private ControlaDatas cDatas = new ControlaDatas(); 


    public PartidasTableModel(){
       this.lista = new ArrayList<Partida>();
    }

    public PartidasTableModel(List<Partida> lista){
        this();
        this.lista.addAll(lista);
    }

    @Override
    public int getRowCount() {
        return this.lista.size();
    }

    @Override
    public int getColumnCount() {
        return this.colunas.length;
    }

    //private String[] colunas = {"Data ", "Casa x Visitante ", "Banca Inicial ", "Banca Final ", "Saldo ",  "Green/Red "};
    public String getColumnName(int column){
        if(colunas[column] == "Data "){
            return "Data ";
        }else if(colunas[column] == "Casa x Visitante "){
            return "Casa x Visitante ";
        }else if(colunas[column] == "Banca Inicial "){
            return "Banca Inicial ";
        }else if(colunas[column] == "Banca Final "){
            return "Banca Final ";
        }else if(colunas[column] == "Saldo "){
            return "Saldo ";
        }else if(colunas[column] == "Green/Red "){
            return "Green/Red ";
        }
        return "";
    }

    //private String[] colunas = {"Data ", "Casa x Visitante ", "Banca Inicial ", "Banca Final ", "Saldo ",  "Green/Red "};
    public Class getColumnClass(int column){
        if(colunas[column] == "Data "){
            return String.class;
        }if(colunas[column] == "Casa x Visitante "){
            return String.class;
        }else if(colunas[column] == "Banca Inicial "){
            return String.class;
        }else if(colunas[column] == "Banca Final "){
            return String.class;
        }else if(colunas[column] == "Saldo "){
            return String.class;
        }else if(colunas[column] == "Green/Red "){
            return String.class;
        }
        return String.class;
    }

    //private String[] colunas = {"Conta ", "Vencto. ", "Capital R$ ", "Juros R$ "};
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Partida e = (Partida)lista.get(rowIndex);
        switch(columnIndex){
            case 0: return cDatas.getDataFormatada(e.getDtLancamento());
            case 1: return e.getTimeCasa() + " x " + e.getTimeVisitante();
            case 2: return FormataValorMonetario.getValorFormatado(e.getValorInicialBanca()); 
            case 3: return FormataValorMonetario.getValorFormatado(e.getValorFinalBanca()); 
            case 4: return FormataValorMonetario.getValorFormatado(e.getSaldo());  
            case 5: return isGreenOrRed(e.getGreenRed());
            default: return new String();
        }
    }

    private String isGreenOrRed(int value){
        if(value == 1){
            return "GREEN";
        }
        if (value == 2){
            return "RED";
        }
        return "";
    }

    /** retorna o objeto */
    public Partida getObject(int row){
        return lista.get(row);
    }

    /** remove registro da tabela */
    public void removeRow(int row){
        this.lista.remove(row);
        fireTableDataChanged();
    }

    /** altera a tabela */
    public void changeTabela(List<Partida> novaLista){
        this.lista = novaLista;
        fireTableDataChanged();
    }

}

TableCellRenderer TableCellRenderer

public class PartidaCustomRenderer implements TableCellRenderer{
    private JLabel label;

    public PartidaCustomRenderer() {
        label = new JLabel();
        label.setOpaque(true);
    }



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

        Object obj = table.getValueAt(row, 5);//
        String redGreen = (String)obj;
        //pinta red/green        
        if(column == 5 && redGreen == "RED"){                      
            label.setBackground(Color.red);
        }else if(column == 5 && redGreen == "GREEN"){
            label.setBackground(Color.green);
        }



        return label;
    }

    private int getAlinhamento(int coluna){
        switch (coluna) {  
           case 0:  
               return SwingConstants.CENTER;  
           case 1:  
               return SwingConstants.LEFT;  
           case 2:  
           default:  
               return SwingConstants.RIGHT;  
       }  
    }
}

Using 使用

public class ViewPartidas extends javax.swing.JDialog {
    private PartidaDAO dao = new PartidaDAO();
    private List<Partida> lista = new ArrayList<Partida>();
    private PartidasTableModel model;

    public ViewPartidas(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
        init();
    }

     private void init(){
        //table  
        lista = dao.findAll(Partida.FIND_ALL, Partida.class);
        model = new PartidasTableModel(lista);
        tabela.setModel(model); 
        tabela.setDefaultRenderer(Object.class, new PartidaCustomRenderer());
        tabela.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        tabela.setAutoCreateColumnsFromModel(false); 
        tabela.getTableHeader().setFont(new Font("Tahoma" , Font.BOLD, 11));
        tabela.getTableHeader().setReorderingAllowed(false);  
        tabela.setFont(new Font("Tahoma", Font.BOLD, 10));

    }

}

Since your renderer is now acting as the default render for all the columns, you need to take into consideration how to handle them as well... 由于您的渲染器现在充当所有列的默认渲染器,因此您还需要考虑如何处理它们。

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

    Object obj = table.getValueAt(row, 5);//
    String redGreen = (String)obj;
    //pinta red/green        
    if(column == 5 && redGreen == "RED"){                      
        label.setBackground(Color.red);
    }else if(column == 5 && redGreen == "GREEN"){
        label.setBackground(Color.green);
    }
    // No default fall through functionality
    // for the other columns


    return label;
}

This is complicated to achieve successfully. 成功实现这一点很复杂。 A better solution would be to set the render to the column you want to use it on... 更好的解决方案是将渲染设置为要在其上使用的列...

tabela.getColumnModel().getColumn(5).setCellRenderer(new PartidaCustomRenderer());

I would also recommend using DefaultTableCellRenderer as it is optimised for JTable and is based on JLabel 我还建议使用DefaultTableCellRenderer因为它已针对JTable优化并且基于JLabel

public class PartidaCustomRenderer extends DefaultTableCellRenderer {

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

        super.getTableCellRendererComponent(table, null, isSelected, hasFocus, row, column);

        String text = (String)value;
        if (column == 5 && text.equals("RED")) {
            setBackground(Color.red);
        } else if (column == 5 && text.equals("GREEN")) {
            setBackground(Color.green);
        }

        return this;
    }

    private int getAlinhamento(int coluna) {
        switch (coluna) {
            case 0:
                return SwingConstants.CENTER;
            case 1:
                return SwingConstants.LEFT;
            case 2:
            default:
                return SwingConstants.RIGHT;
        }
    }
}

From this tutorial: 从本教程中:

https://tips4java.wordpress.com/2010/01/24/table-row-rendering/ https://tips4java.wordpress.com/2010/01/24/table-row-rendering/

We get this code: 我们得到以下代码:

JTable table = new JTable( model ) {
  public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
    Component c = super.prepareRenderer(renderer, row, column);

    //  Alternate row color
    if (!isRowSelected(row)) {
      c.setBackground(row % 2 == 0 ? getBackground() : Color.LIGHT_GRAY);
    }
    return c;
  }
};

Which should be easy to adapt to columns instead of rows, or a particular column instead of alternating columns. 应该容易适应列而不是行,或者适合特定列而不是交替列。

So to break this down, you're making your own subclass of JTable, and then overriding the prepareRenderer method. 因此,要分解这种情况,您需要创建自己的JTable子类,然后覆盖prepareRenderer方法。 You still delegate to the superclass' implementation, but then you take the component it gave you and make specific changes based on the row and column. 您仍然可以委派给超类的实现,但是然后使用它给您的组件,并根据行和列进行特定的更改。

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

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