Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

JCheckbox in JTable column header with column sorting

it99Jan 12 2010 — edited Jan 12 2010
I'm trying to have a checkBox in a JTable Column Header. The idea is if the checkbox is unchecked it will collapse the column to a small width. If the checkBox is checked it will go back to normal width.
I also want to independently be able to sort the column data by clicking next to the checkbox(not in the checkbox).
However if I click either in the checkbox or anwhere in that column's header it will both toggle the checkBox and sort the column. Is there anyway I can get those two to work separately.

Thank you very much!!

I included a full, runnable test versions of the code.
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Enumeration;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableRowSorter;
public class TableTest {
	
	private JTable table;
	 private JScrollPane tableScrollPane;	 
     String[] columnNames;
	public static void main(String[] args) {
		new TableTest();
	}
	public TableTest()
	{
		TestTableModel tableModel = new TestTableModel();
        table = new JTable(tableModel);
        TableRowSorter sorter = new TableRowSorter<TestTableModel>(tableModel);        
        table.setPreferredScrollableViewportSize(new Dimension(750, 250));
        table.setFillsViewportHeight(true);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        table.setAutoCreateRowSorter(true);
        table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        table.setRowSorter(sorter);
        TableColumn column = null;
		for (int i = 0; i < columnNames.length; i++)
        {
            column = table.getColumnModel().getColumn(i);
            column.setMinWidth(100);
        }
        MyItemListener myItemListener = new MyItemListener(); 
        Enumeration<TableColumn> enumeration = table.getColumnModel().getColumns(); 
        while (enumeration.hasMoreElements()) { 
            TableColumn aColumn = (TableColumn)enumeration.nextElement(); 
            aColumn.setHeaderRenderer(new CheckBoxHeader(myItemListener)); 
        } 
        tableScrollPane = new JScrollPane(table);
        JPanel panel = new JPanel(new GridLayout(1, 0));
        panel.add(tableScrollPane);
        JFrame  frame = new javax.swing.JFrame("Test");        
        frame.setContentPane(panel);              
        frame.pack();
        frame.setSize(new Dimension(200,200));
        frame.setPreferredSize(new Dimension(200,200));
        frame.setVisible(true);
	}	
    public class CheckBoxHeader extends JCheckBox implements TableCellRenderer,
    MouseListener 
    {
		protected CheckBoxHeader rendererComponent;
		protected int column;
		protected boolean mousePressed = false;		
		private boolean mouseListenerAdded=false;
		public CheckBoxHeader(ItemListener itemListener) {
			rendererComponent = this;
			rendererComponent.addItemListener(itemListener);
			setSelected(true);
		}
		public Component getTableCellRendererComponent(JTable table,
				Object value, boolean isSelected, boolean hasFocus, int row,
				int column) {
			if (table != null) {
				JTableHeader header = table.getTableHeader();
				if (header != null) {
					if(!mouseListenerAdded)
					{
						header.addMouseListener(rendererComponent);
						mouseListenerAdded=true;
					}
				}
			}
			setColumn(column);
			rendererComponent.setText((value == null) ? "" : value.toString());
			setBorder(UIManager.getBorder("TableHeader.cellBorder"));
			return rendererComponent;
		}
		protected void setColumn(int column) {
			column = column;
		}
		public int getColumn() {
			return column;
		}

		protected void handleClickEvent(MouseEvent e) {
			if (mousePressed) {				
				mousePressed = false;
				JTableHeader header = (JTableHeader) (e.getSource());
				JTable tableView = header.getTable();
				TableColumnModel columnModel = tableView.getColumnModel();
				int viewColumn = columnModel.getColumnIndexAtX(e.getX());
				int column = tableView.convertColumnIndexToModel(viewColumn);
				if (viewColumn == this.column && e.getClickCount() == 1
						&& column != -1) {
					doClick();
				}
			}
		}
		public void mouseClicked(MouseEvent e) {			
			handleClickEvent(e);
		}
		public void mousePressed(MouseEvent e) {
			mousePressed = true;
		}
		public void mouseReleased(MouseEvent e) {}

		public void mouseEntered(MouseEvent e) {}

		public void mouseExited(MouseEvent e) {}
}	
    class MyItemListener implements ItemListener {    	
        public void itemStateChanged(ItemEvent e) { 

            TableColumn column = table.getColumnModel().getColumn(
            		((CheckBoxHeader)(e.getItem())).getColumn());
            int width =100;
            if (e.getStateChange() != ItemEvent.SELECTED)
            {
            	width=15;
            }
        	column.setMinWidth(width);
        	column.setPreferredWidth(width); 
        } 
    }	
    class TestTableModel extends AbstractTableModel
    {
        private Object[][] data;
        public TestTableModel()
        {
        	columnNames = new String[1];
            columnNames[0] ="Col 1";
            data = new Object[5][1];
            data[0][0] = 0;
            data[1][0] = 1;
            data[2][0] = 2;
            data[3][0] = 3;
            data[4][0] = 4;
        }
        public int getColumnCount()
        {
            return columnNames.length;
        }
        public int getRowCount()
        {
            return data.length;
        }
        public String getColumnName(int col)
        {
            return columnNames[col];
        }
        public Object getValueAt(int rowIndex, int columnIndex)
        {
            return data[rowIndex][columnIndex];
        }
        public void setValueAt(Object o, int rowIndex, int columnIndex)
        {
            data[rowIndex][columnIndex] = o;
        }
    }
}
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Feb 9 2010
Added on Jan 12 2010
7 comments
2,371 views