title: How to identify a direct click on a JCheckBox in a JTable?
body: <p>With a JCheckBox as an Editor in a JTable column, I would like to ignore mouseclicks in the space left and right of a CheckBox in a TableCell. </p>
  
  <p>I have found a discussion from 2011 on the Oracle forum, but the problem was not solved there: <a href="https://community.oracle.com/thread/2183210" rel="nofollow">https://community.oracle.com/thread/2183210</a> </p>
  
  <p>This is the hack I've realized so far, the interesting part begins at<code>class CheckBoxEditor</code>: </p>
  
  <pre><code>import java.awt.BorderLayout;
  import java.awt.Dimension;
  import java.awt.event.ComponentEvent;
  import java.awt.event.MouseEvent;
  import java.util.EventObject;
  import javax.swing.DefaultCellEditor;
  import javax.swing.JCheckBox;
  import javax.swing.JFrame;
  import javax.swing.JPanel;
  import javax.swing.JScrollPane;
  import javax.swing.JTable;
  import javax.swing.SwingUtilities;
  import javax.swing.table.DefaultTableModel;
  import javax.swing.table.TableColumn;
  
  /**
   * Trying to set the Checkbox only if clicked directly on the box of the CheckBox. And ignore clicks on the
   * remaining space of the TableCell.
   * 
   * @author bobndrew
   */
  public class JustCheckOnCheckboxTable extends JPanel
  {
    private static final int        CHECK_COL = 1;
    private static final Object[][] DATA      = { { "One", Boolean.TRUE }, { "Two", Boolean.FALSE },
        { "Three", Boolean.TRUE }, { "Four", Boolean.FALSE }, { "Five", Boolean.TRUE },
        { "Six", Boolean.FALSE }, { "Seven", Boolean.TRUE }, { "Eight", Boolean.FALSE },
        { "Nine", Boolean.TRUE }, { "Ten", Boolean.FALSE } };
    private static final String[]   COLUMNS   = { "Number", "CheckBox" };
    private final DataModel         dataModel = new DataModel( DATA, COLUMNS );
    private final JTable            table     = new JTable( dataModel );
  
    public JustCheckOnCheckboxTable()
    {
      super( new BorderLayout() );
      this.add( new JScrollPane( table ) );
      table.setRowHeight( table.getRowHeight() * 2 );
      table.setPreferredScrollableViewportSize( new Dimension( 250, 400 ) );
      TableColumn checkboxColumn = table.getColumnModel().getColumn( 1 );
      checkboxColumn.setCellEditor( new CheckBoxEditor() );
    }
  
    private class DataModel extends DefaultTableModel
    {
      public DataModel( Object[][] data, Object[] columnNames )
      {
        super( data, columnNames );
      }
  
      @Override
      public Class&lt;?&gt; getColumnClass( int columnIndex )
      {
        if ( columnIndex == 1 )
        {
          return getValueAt( 0, CHECK_COL ).getClass();
        }
        return super.getColumnClass( columnIndex );
      }
    }
  
  
    class CheckBoxEditor extends DefaultCellEditor
    {
      private final JCheckBox checkBox;
  
      public CheckBoxEditor()
      {
        super( new JCheckBox() );
        checkBox = (JCheckBox) getComponent();
        checkBox.setHorizontalAlignment( JCheckBox.CENTER );
        System.out.println( "the checkbox has no size:   " + checkBox.getSize() );
      }
  
      @Override
      public boolean shouldSelectCell( final EventObject anEvent )
      {
        System.out.println( "\nthe checkbox fills the TableCell:  " + checkBox.getSize() );
        //Throws NullPointerException:      System.out.println( checkBox.getIcon().getIconWidth() );
        System.out.println( "always JTable :-(   " + anEvent.getSource() );
  
        MouseEvent ev =
            SwingUtilities.convertMouseEvent( ((ComponentEvent) anEvent).getComponent(), (MouseEvent) anEvent,
            getComponent() );
        System.out.println( "Position clicked in TableCell:   " + ev.getPoint() );
        System.out.println( "always JCheckBox :-(   " + getComponent().getComponentAt( ev.getPoint() ) );
  
        Point middleOfTableCell = new Point( checkBox.getWidth() / 2, checkBox.getHeight() / 2 );
        System.out.println( "middleOfTableCell: " + middleOfTableCell );
  
        Dimension preferredSizeOfCheckBox = checkBox.getPreferredSize();
  
        int halfWidthOfClickArea = (int) (preferredSizeOfCheckBox.getWidth() / 2);
        int halfHeightOfClickArea = (int) (preferredSizeOfCheckBox.getHeight() / 2);
  
        if ( (middleOfTableCell.getX() - halfWidthOfClickArea &gt; ev.getX() || middleOfTableCell.getX() + halfWidthOfClickArea &lt; ev.getX()) 
          || (middleOfTableCell.getY() - halfHeightOfClickArea &gt; ev.getY() || middleOfTableCell.getY() + halfHeightOfClickArea &lt; ev.getY()) )
        {
          stopCellEditing();
        }
  
        return super.shouldSelectCell( anEvent );
      }
    }
  
  
    private static void createAndShowUI()
    {
      JFrame frame = new JFrame( "Direct click on CheckBox" );
      frame.add( new JustCheckOnCheckboxTable() );
      frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
      frame.pack();
      frame.setLocationRelativeTo( null );
      frame.setVisible( true );
    }
  
    public static void main( String[] args )
    {
      java.awt.EventQueue.invokeLater( new Runnable()
      {
        @Override
        public void run()
        {
          createAndShowUI();
        }
      } );
    }
  }
  </code></pre>
  
  <p>What I like about this solution: </p>
  
  <ul>
  <li>all TableCell behaviour is correct: selecting, MouseOver, EditModes, ...</li>
  </ul>
  
  <p>What I don't like about it: </p>
  
  <ul>
  <li>the hardcoded size of the JCheckBox (<code>int halfWidthOfClickArea</code>)
  <ul>
  <li>where can I get the dimensions of an unpainted component? </li>
  </ul></li>
  </ul>
  
  <p>Or are there better ways to achieve this Table and CheckBox-behaviour? </p>
  
  <p><strong>EDIT:</strong> </p>
  
  <p>I changed the sourcecode following the advice of camickr and added a vertical hitzone for tables with higher RowHeights.<br>
  But so far I forgot to mention the main reason for my question... ;-)<br>
  I'm calling <code>stopCellEditing()</code> in the method <code>shouldSelectCell(..)</code>. </p>
  
  <p><strong>Is it ok to decide there about more than the Cell-Selection?</strong> </p>