jTable 单元格背景颜色

Posted

技术标签:

【中文标题】jTable 单元格背景颜色【英文标题】:jTable Cell background color 【发布时间】:2015-11-29 02:41:58 【问题描述】:

我正在尝试使用渲染器为 jTable 的单元格着色,但它们工作不正常,因为它们滞后于表格并使其无法看到。这是我的代码:

            TableCellRenderer Tcr = jTable1.getCellRenderer(x, y);
            Component c = Tcr.getTableCellRendererComponent(jTable1, jTable1.getValueAt(x, y), false, false, x, y);


            if(x > 0 && x < (jTable1.getRowCount()-1) && y > 1 && y < (jTable1.getColumnCount()-1))
                if(!jTable1.getValueAt(x, y).equals(null) && !jTable1.getValueAt(x, y).equals("F") && !jTable1.getValueAt(x, y).equals(" "))
                    if(!jTable1.getValueAt(x, y).toString().contains("/P") && !jTable1.getValueAt(x, y).toString().equals("P"))                            
                        if(Double.parseDouble(jTable1.getValueAt(x, y).toString()) > 24)
                            setBackground(java.awt.Color.red);

                        
                    
                    
            

我没有将它放入渲染器类,因为它滞后,我已将它放入 cicle 的双倍中,特别是放入第二个 cicle。我希望它为超过 24 的单元格着色,就像现在一样,如果我写的话,它不起作用

c.setBackground(Color.red);

它为表格完全着色

编辑

按要求,我创建了一个描述我的问题的小示例,我不知道是否有特定方法可以发布可运行示例,但以下代码(在 netbeans 中)代表了完整的程序:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package fatturazione;

import ObjectModel.Timesheet;
import java.awt.Component;
import javax.swing.JLabel;
import javax.swing.table.TableCellRenderer;


/**
 *
 * @author xtphere
 */
public class Example extends javax.swing.JFrame 

    /**
     * Creates new form Main
     */
    public Example() 
        initComponents();
    

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() 

        jScrollPane1 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();
        CheckButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jTable1.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] 
                null, null, null, null,
                null, null, null, null,
                null, null, null, null,
                null, null, null, null
            ,
            new String [] 
                "Title 1", "Title 2", "Title 3", "Title 4"
            
        ));
        jScrollPane1.setViewportView(jTable1);

        CheckButton.setText("Check the table");
        CheckButton.addActionListener(new java.awt.event.ActionListener() 
            public void actionPerformed(java.awt.event.ActionEvent evt) 
                CheckButtonActionPerformed(evt);
            
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 375, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(CheckButton))
                .addContainerGap(15, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 275, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(CheckButton)
                .addGap(0, 35, Short.MAX_VALUE))
        );

        pack();
    // </editor-fold>                        

    private void CheckButtonActionPerformed(java.awt.event.ActionEvent evt)                                             
        // TODO add your handling code here:
        int x, y, i = 1;


        for(x = 0; x < jTable1.getRowCount(); x++)

            for(y = 0;  y < jTable1.getColumnCount(); y++)

                TableCellRenderer Tcr = jTable1.getCellRenderer(x, y);
                Component c = Tcr.getTableCellRendererComponent(jTable1, jTable1.getValueAt(x, y), false, false, x, y);

                if(jTable1.getValueAt(x, y) == null)
                
                    jTable1.setValueAt("P", x, y);
                

                if(jTable1.getValueAt(x, y) != null && !jTable1.getValueAt(x, y).equals("F") && !jTable1.getValueAt(x, y).equals(" "))
                        System.out.print(jTable1.getValueAt(x, y)+"\n");                          
                        if(!jTable1.getValueAt(x, y).toString().contains("/P") && !jTable1.getValueAt(x, y).toString().equals("P"))                            
                            System.out.print("prima del maggiore di 24");
                            if(Double.parseDouble(jTable1.getValueAt(x, y).toString()) > 24)
                                System.out.print("leggi il 25, almeno?");
                                c.setBackground(java.awt.Color.red);                                
                            
                        
                        


                      
         


                                               

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) 
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try 
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) 
                if ("Nimbus".equals(info.getName())) 
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                
            
         catch (ClassNotFoundException ex) 
            java.util.logging.Logger.getLogger(Example.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
         catch (InstantiationException ex) 
            java.util.logging.Logger.getLogger(Example.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
         catch (IllegalAccessException ex) 
            java.util.logging.Logger.getLogger(Example.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
         catch (javax.swing.UnsupportedLookAndFeelException ex) 
            java.util.logging.Logger.getLogger(Example.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        
        //</editor-fold>
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() 
            public void run() 
                new Example().setVisible(true);
            
        );
    

    // Variables declaration - do not modify                     
    private javax.swing.JButton CheckButton;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable jTable1;
    // End of variables declaration                   

【问题讨论】:

考虑提供一个runnable example 来证明您的问题。这不是代码转储,而是您正在做的事情的一个示例,它突出了您遇到的问题。这将导致更少的混乱和更好的响应 使用和扩展 DefaultTableCellRenderer 不会滞后。但是,它必须正确使用:单元格渲染器应返回可用于所有单元格的单个相同组件,并且工作量应最少。也许一个 TableModel 更像是为红色保存一个布尔值。 首先查看Concepts: Editors and Renderers 和Using Custom Renderers。你提供的代码不可能工作,因为你得到的组件实际上并没有附加到任何东西上,当渲染时,表格只是使用渲染器将输出“橡皮图章”到表格上,实际上没有生命桌子上的组件(编辑器除外,当处于活动状态时) 我已经看过自定义渲染器的东西了,因为很多人在我读过的其他问题中建议使用它,但是由于 CustomRenderer 似乎根本不起作用,我会使用 defaultrenderers 重试 【参考方案1】:

首先,变量名称不应以大写字符开头。您的一些变量是正确的,而另一些则不是。保持一致!!!

我尝试使用渲染器为 jTable 的单元格着色,但它们没有用,它们滞后于表格并使其无法看到。

仅仅因为你不理解这个概念并不会使它变得无用。问题在于您的代码,而不是渲染器的概念。

您发布的代码毫无意义。您不能设置单个单元格的颜色。颜色是在单元格是渲染器时确定的,这就是您需要使用渲染器的原因。

它完全为表格着色

是的,一旦您设置了渲染器的背景,以后所有的单元格都将使用该颜色。在渲染每个单元格之前,您需要将颜色重置为默认值

背景必须为红色,以防万一它是一个数字并且大于 24,

然后做一个积极的检查,忘记所有那些消极的检查。

使用上述所有建议,您可能会有类似的渲染器:

class ColorRenderer extends DefaultTableCellRenderer

    @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 (isSelected)
            setBackground( table.getSelectionBackground() );
        else
        
            setBackground( table.getBackground() );

            try
            
                int number = Integer.parseInt( value.toString() );

                if (number > 24)
                    setBackground( Color.RED );
            
            catch(Exception e) 
        

        return this;
    

【讨论】:

在我把 jtable.setDefaultRenderer(Object.class, new ColorRenderer());进入它工作的构造函数,谢谢,但为什么它用来滞后表??【参考方案2】:

在您的第一个代码示例中,您有一系列检查以将背景颜色设置为红色。在所有其他情况下,您应该将背景设置为默认背景颜色。您可以通过table.getBackground(); 查找此背景颜色。

【讨论】:

所有这些检查都是必需的,因为背景必须是红色的,以防万一它是一个数字并且它高于 24,但在我的表格中可以出现一个 P、一个 F、一个空格、一个数字通过 /P,当然还有一个 null 值,我尝试输入一些“其他”,但即便如此,整个表格也会变白 @Malignus 好吧,您的控制流应该以将颜色设置为红色或白色结束。也许有一个布尔值 b 默认为 false,并在需要将颜色设置为红色时将其设置为 true。最后做 c.setBackground( b ? red : table.getBackground());【参考方案3】:

查看讨论帖后,我得出了这个解决方案......

...不要尝试获取已渲染的Component 本身 - 告诉渲染器以您希望的方式绘制您想要的组件...

CellRenderer renderer = new DefaultCellRenderer()

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

        Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
        JLabel label = (JLabel)c;

        if (yourAlgorithmToDetectTheProperCell) //i can't insert your condition from above, it's overkill ^^
            label.setBackGround(Color.RED);
        
  
        return label;
    
;

table.setCellRenderer(renderer);

自卫队

【讨论】:

以上是关于jTable 单元格背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

JTable将单元格颜色设置为特定值

Java - Jtable - 不同颜色的单元格

JTable:单击按钮时更改单元格背景

更改单元格颜色而不更改其他单元格中的颜色(Jtable)

iOS UITableView:更改表格的背景颜色会覆盖单元格的背景颜色

更改单元格的背景颜色