CheckBoxTableCellRenderer.java
01 /*
02  * CheckBoxTableCellRenderer.java
03  
04  * Copyright (c) 2011, The University of Sheffield. See the file COPYRIGHT.txt
05  * in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
06  
07  * This file is part of GATE (see http://gate.ac.uk/), and is free software,
08  * licenced under the GNU Library General Public License, Version 2, June 1991
09  * (in the distribution as file licence.html, and also available at
10  * http://gate.ac.uk/gate/licence.html).
11  
12  * Mark A. Greenwood, 27/11/2011
13  */
14 
15 package gate.swing;
16 
17 import java.awt.Color;
18 import java.awt.Component;
19 
20 import javax.swing.BorderFactory;
21 import javax.swing.JCheckBox;
22 import javax.swing.JTable;
23 import javax.swing.UIManager;
24 import javax.swing.border.Border;
25 import javax.swing.table.TableCellRenderer;
26 
27 /**
28  * A TableCellRenderer for JCheckBox that disables the checkbox when the cell
29  * isn't editable to make it clear that you can't click on it
30  
31  @author Mark A. Greenwood
32  */
33 @SuppressWarnings("serial")
34 public class CheckBoxTableCellRenderer extends JCheckBox implements
35                                                         TableCellRenderer {
36 
37   /**
38    * An empty border we use when the cell doesn't have focus
39    */
40   private static final Border NO_FOCUS = BorderFactory.createEmptyBorder(11,
41           11);
42 
43   public CheckBoxTableCellRenderer() {
44     super();
45 
46     // centre the checkbox within the cell
47     setHorizontalAlignment(JCheckBox.CENTER);
48 
49     // make sure we always paint the cell border
50     setBorderPainted(true);
51 
52     // make sure we always paint the background
53     setOpaque(true);
54   }
55 
56   @Override
57   public Component getTableCellRendererComponent(JTable table, Object value,
58           boolean isSelected, boolean hasFocus, int row, int column) {
59 
60     // this is needed for Nimbus which has alternative rows in different colours
61     // hopefully other L&Fs that also do this use the same UIManager key
62     Color alternate = UIManager.getColor("Table.alternateRowColor");
63 
64     // strangely the background color from Nimbus doesn't render properly unless
65     // we convert it in this way. I'm guessing the problem is to do with the
66     // DerivedColor class that nimbus uses
67     Color normal = new Color(table.getBackground().getRGB());
68 
69     if(isSelected) {
70       // if the cell is selected then set it's colors from the table
71       setForeground(table.getSelectionForeground());
72       setBackground(table.getSelectionBackground());
73     else {
74       // if the cell isn't selected set it's colors taking into account the
75       // possibility of alternating colors that Nimbus throws into the mix
76       setForeground(table.getForeground());
77       setBackground(alternate != null && row % == ? alternate : normal);
78     }
79 
80     // if the cell isn't editable then disable the checkbox to give some visual
81     // feedback to the user
82     setEnabled(table.isCellEditable(row, column));
83 
84     // make the checkbox reflect the underlying boolean data
85     setSelected(value != null && (Boolean)value);
86 
87     if(hasFocus) {
88       // if the cell has focus then draw the border set by the L&F
89       setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
90     else {
91       // if the cell doesn't have the focus then draw the empty border
92       setBorder(NO_FOCUS);
93     }
94 
95     // now return the checkbox for rendering into the table
96     return this;
97   }
98 }