2013-02-26 205 views
2

下面是我的JTable的图片。我的问题是每隔一行的蓝色背景不在第4列。我的表模型和单元格渲染器也在下面。JTable单元格渲染器跳过布尔列

enter image description here

表模型:

public class MyTableModel extends DefaultTableModel { 
    public int getColumnCount() { 
     return columnNames.length; 
    } 

    public String getColumnName(int column) { 
     return columnNames[column]; 
    } 

    public int getRowCount() { 
     return data.length; 
    } 

    public Object getValueAt(int row, int column) { 
     return data[row][column]; 
    } 

    public Class getColumnClass(int column) { 
     return (getValueAt(0, column).getClass()); 
    } 

    public void setValueAt(Object value, int row, int column) { 
     data[row][column] = value; 
    } 

    public boolean isCellEditable(int row, int column) { 
     return (column == 3); 
    } 
    } 

单元格渲染:

private class CalendarRenderer extends DefaultTableCellRenderer { 
    private static final long serialVersionUID = 1L; 

    public Component getTableCellRendererComponent(JTable table, Object value, boolean selected, boolean focused, int row, int column) { 
     super.getTableCellRendererComponent(table, value, selected, focused, row, column); 

     setBackground(new Color(0xFFFFFF)); 

     if (row % 2 == 1) { 
     setBackground(new Color(0xE8F2FE)); //light blue 
     } 

     setBorder(null); 
     setForeground(Color.black); 
     return this; 
    } 
    } 
+0

'Boolean'的默认编辑器是'JCheckBox'单元编辑器,这实际上工作正常。 – MadProgrammer 2013-02-26 04:07:38

+0

Java何时不能“正确”工作?我想知道如何让第四栏也有蓝色背景。 – 2013-02-26 04:08:49

+1

您将需要提供自己的'布尔''TableCellRenderer' – MadProgrammer 2013-02-26 04:09:45

回答

8

Boolean为 “默认” 细胞渲染器是一个复选框。如果你想改变这个单元格渲染的方式,你将不得不提供你自己的TableCellRenderer,它实现了你自己的逻辑。

enter image description here

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.EventQueue; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.JCheckBox; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
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.table.AbstractTableModel; 
import javax.swing.table.TableCellRenderer; 

public class TestTableCellRenderer { 

    public static void main(String[] args) { 
     new TestTableCellRenderer(); 
    } 

    public TestTableCellRenderer() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JTable table = new JTable(); 
       table.setModel(new TableModel()); 
       table.setDefaultRenderer(Boolean.class, new BooleanCellRenderer()); 

       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 class TableModel extends AbstractTableModel { 

     private List<Boolean> values = new ArrayList<>(25); 

     public TableModel() { 
      for (int index = 0; index < 25; index++) { 
       values.add((((int) Math.round(Math.random() * 1)) == 0 ? false : true)); 
      } 
     } 

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

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

     @Override 
     public Object getValueAt(int rowIndex, int columnIndex) { 
      return values.get(rowIndex); 
     } 

     @Override 
     public Class<?> getColumnClass(int columnIndex) { 
      return Boolean.class; 
     } 
    } 

    public static class BooleanCellRenderer extends JCheckBox implements TableCellRenderer { 

     private static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1); 

     public BooleanCellRenderer() { 
      setLayout(new GridBagLayout()); 
      setMargin(new Insets(0, 0, 0, 0)); 
      setHorizontalAlignment(JLabel.CENTER); 
     } 

     @Override 
     public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
      if (value instanceof Boolean) { 
       setSelected((Boolean) value); 
      } 
      if (!isSelected) { 
       setBackground(new Color(0xFFFFFF)); 
       if (row % 2 == 1) { 
        setBackground(new Color(0xE8F2FE)); //light blue 
       } 
       setForeground(Color.black); 
      } else { 
       setForeground(table.getSelectionForeground()); 
       setBackground(table.getSelectionBackground()); 
      } 
      if (hasFocus) { 
       setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); 
      } else { 
       setBorder(noFocusBorder); 
      } 
      return this; 
     } 
    } 
} 
+0

完美,谢谢! – 2013-02-26 04:35:22

+0

这对我不起作用......我仍然获得非交替的背景颜色,当我选择一个复选框时,它将列入列中的所有框。任何想法,如果这可能是无效的更新版本的秋千? – 2016-03-03 20:16:10

+0

@AdamHughes那么,由于代码示例演示了一个可行的解决方案,我建议的任何东西都是猜测。 5月,考虑用你正在使用的代码问一个问题 – MadProgrammer 2016-03-03 20:39:30

3

对于不要求你保持创建自定义渲染每次有不同的数据列的时间的解决方案见Table Row Rendering

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; 
    } 
}; 
+0

非常好的解决方案!!!!! – Andreas 2017-07-19 09:45:32