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