Hide Table Columns easily
When you deal with large tables that provide a good number of columns, it is always nice if you can hide some of them. They should still be available in the TableModel, so this is clearly a task for the view.
It turns out, realizing a popup menu on the table header is quiet easy. We utilize the tables ColumnModel to change visible columns. Well, actually we do not just change the columns visibility but remove or readd it to the column model. In Epos, all this can be done using a simple utility method in the ComponentUtils. It creates a popup and adds the appropriate mouse listeners to the tables header.
Here is the utility code the creates the popup and adds the listener. Note that we evaluate and check for a popup click on both the pressed and the released mouse event. This is due to some platform specific differences.
public static void installColumnHider(final JTable table){
final TableColumnModel columnModel = table.getColumnModel();
final JPopupMenu menu = new JPopupMenu("Columns");
for (int i = 0; i < columnModel.getColumnCount(); i++) {
menu.add(new ColumnHiderItem(columnModel, i));
}
table.getTableHeader().addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e) {
evaluatePopup(e);
}
public void mouseReleased(MouseEvent e) {
evaluatePopup(e);
}
private void evaluatePopup(MouseEvent e) {
if(e.isPopupTrigger()){
menu.show(table.getTableHeader(), e.getX(), e.getY());
}
}
});
}
This is more or less boilerplate that creates the popup menu content and shows the popup when someone right clicks the table header. The actual magic (ok…this is no real magic) hides within the ColumnHiderItem. This is a JCheckBoxMenuItem that enables or disables a specific column.
private static class ColumnHiderItem extends JCheckBoxMenuItem implements ActionListener{
private TableColumn column;
private TableColumnModel columnModel;
private int index;
private ColumnHiderItem(TableColumnModel columnModel, int index) {
super(columnModel.getColumn(index).getHeaderValue().toString());
this.columnModel = columnModel;
this.index = index;
column = columnModel.getColumn(index);
addActionListener(this);
setSelected(true);
}
public void actionPerformed(ActionEvent e) {
if(isSelected()){
columnModel.addColumn(column);
if(columnModel.getColumnCount() > index){
columnModel.moveColumn(columnModel.getColumnCount()-1, index);
}
}else{
columnModel.removeColumn(column);
}
}
}
All it does is adding or removing a specific column from the tables column model. That’s all and the column model is just used by the view, so no modification of the actual table model needed here.