在JTable中设置JCheckBox单元格的颜色

时间:2013-05-07 00:46:58

标签: java swing colors jtable jcheckbox

我有一个JCheckBox在JTable的最后一列中工作。但是当我将颜色设置为该列中的单元格时,它似乎会覆盖渲染的对象(JCheckBox)。

以下代码片段就是我要做的事情:

//Overriding these methods using the DefaultTableModel constructor works .
DefaultTableModel model = new DefaultTableModel(data, columnNames)
        {
        @Override
         public Class getColumnClass(int col) 
            {
            return getValueAt(1, col).getClass();
         }

         @Override
         public boolean isCellEditable(int rowIndex, int colIndex) 
            {
            return (colIndex == CHECK_COL);
         }
      };

JTable table = new JTable(model);

//Constructing and setting a render background and foreground color
DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
renderer.setBackground(Color.BLACK);
renderer.setForeground(new Color(255, 0, 255));

TableColumn column = table.getColumnModel().getColumn(4);
column.setCellRenderer(centerRenderer);

//Now the last column contains just Boolean values, rather than JCheckBox's when I try set the colors.

任何人都可以弄清楚我是如何克服这一点的吗? 谢谢。非常感谢

1 个答案:

答案 0 :(得分:8)

  1. DefaultTableCellRenderer基于JLabel,因此永远不会渲染JCheckBox
  2. foreground / background值可能会在渲染过程中被覆盖,这意味着它们会针对每个单元格进行更改,从而失去您提供的默认值。
  3. 您需要提供一个单元格渲染器......

    1. 基于JCheckBox
    2. 可以在需要时恢复所需的默认foreground / background值...
    3. 这是一个展示基本概念的基本例子......

      enter image description here

      import java.awt.BorderLayout;
      import java.awt.Color;
      import java.awt.Component;
      import java.awt.EventQueue;
      import javax.swing.JCheckBox;
      import javax.swing.JFrame;
      import javax.swing.JLabel;
      import javax.swing.JScrollPane;
      import javax.swing.JTable;
      import javax.swing.UIManager;
      import javax.swing.UnsupportedLookAndFeelException;
      import javax.swing.border.Border;
      import javax.swing.border.EmptyBorder;
      import javax.swing.plaf.UIResource;
      import javax.swing.table.AbstractTableModel;
      import javax.swing.table.TableCellRenderer;
      import javax.swing.table.TableModel;
      
      public class BooleanCellEditor {
      
          public static void main(String[] args) {
              new BooleanCellEditor();
          }
      
          public BooleanCellEditor() {
              EventQueue.invokeLater(new Runnable() {
                  @Override
                  public void run() {
                      try {
                          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                      } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                      }
      
                      TableModel model = new AbstractTableModel() {
                          @Override
                          public Class<?> getColumnClass(int columnIndex) {
                              return Boolean.class;
                          }
      
                          @Override
                          public int getRowCount() {
                              return 4;
                          }
      
                          @Override
                          public int getColumnCount() {
                              return 1;
                          }
      
                          @Override
                          public Object getValueAt(int rowIndex, int columnIndex) {
                              return true;
                          }
                      };
      
                      JTable table = new JTable(model);
                      table.setDefaultRenderer(Boolean.class, new BooleanRenderer());
      
                      JFrame frame = new JFrame("Testing");
                      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                      frame.setLayout(new BorderLayout());
                      frame.add(new JScrollPane(table));
                      frame.pack();
                      frame.setLocationRelativeTo(null);
                      frame.setVisible(true);
                  }
              });
          }
      
          public static class BooleanRenderer extends JCheckBox implements TableCellRenderer, UIResource {
      
              private static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
      
              public BooleanRenderer() {
                  super();
                  setHorizontalAlignment(JLabel.CENTER);
                  setBorderPainted(true);
                  setOpaque(true);
                  setText("Hello");
              }
      
              public Component getTableCellRendererComponent(JTable table, Object value,
                      boolean isSelected, boolean hasFocus, int row, int column) {
                  if (isSelected) {
                      setForeground(table.getSelectionForeground());
                      super.setBackground(table.getSelectionBackground());
                  } else {
                      setBackground(Color.BLACK);
                      setForeground(new Color(255, 0, 255));
                  }
                  setSelected((value != null && ((Boolean) value).booleanValue()));
      
                  if (hasFocus) {
                      setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
                  } else {
                      setBorder(noFocusBorder);
                  }
      
                  return this;
              }
          }
      }
      

      注意,我从BooleanRenderer内的默认实施中偷走了JTable;)