Question

Is it possible to control whether a column should be available in a column control popup menu? I'm aware of toggling (Disable/enable using CheckBoxList) and gray-out the column. But I do not want column entry in popup menu as The column is must-have column in Jtable. I'm using the JXTable. Anyone that have any hints?

Was it helpful?

Solution

A TableColumnExt has a property hideable which effectly disables the hiding. It is still shown in the popup and you can toggle the checkbox (that's a bug, just filed - the menu item should be disabled ;), but at least the column isn't hidden. To work around the bug, you can implement a custom column control (as Robin correctly suggested) which doesn't add the checkbox, something like:

JXTable table = new JXTable(new AncientSwingTeam());
// here the hideable property is configured manually, 
// in production code you'll probably have a custom ColumnFactory
// doing it based on some data state 
table.getColumnExt(0).setHideable(false);
ColumnControlButton columnControl = new ColumnControlButton(table) {

    @Override
    protected ColumnVisibilityAction createColumnVisibilityAction(
            TableColumn column) {
        if (column instanceof TableColumnExt
                && !((TableColumnExt) column).isHideable())
            return null;
        return super.createColumnVisibilityAction(column);
    }

};
table.setColumnControl(columnControl);
table.setColumnControlVisible(true);

As to not including the menu item: when introducing the hideable property, we decided to go for keeping the item in the list but disable it because users might get confused not seeing all columns in the control. So once the bug will be fixed (just done, committed as of revision #4315), I would recommend to remove the custom column control again. Just my 2 euro-cents, though :-)

OTHER TIPS

ColumnControlButton#createColumnVisibilityAction looks like the method you are looking for. According to the documentation:

Creates and returns a ColumnVisibilityAction for the given TableColumn. The return value might be null, f.i. if the column should not be allowed to be toggled

you can return null for your case.

You should be able to plug this in by using the JXTable#setColumnControl method.

First way:

myTable().getColumnExt(_column_number_).setHideable(false);

This works smooth but has one UI drawback: text in menu is gray and thick is black - bad user experience.

So try to fix it, text will be gray and thick won't be here:

public class MyTable extends JXTable
{
    public MyTable(AbstractTableModel model)
    {
        //first two columns won't be hiddeable
        ColumnControlButton controlButton = new ColumnControlButton(this)
        {
            @Override
            protected ColumnControlPopup createColumnControlPopup()
            {
                return (new NFColumnControlPopup());
            }

            class NFColumnControlPopup extends DefaultColumnControlPopup
            {
                @Override
                public void addVisibilityActionItems(List<? extends AbstractActionExt> actions)
                {
                    for(int i = 0; i < actions.size(); i++)
                    {
                        AbstractActionExt action = actions.get(i);
                        JCheckBoxMenuItem chk = new JCheckBoxMenuItem(action);
                        //Disabling unwanted items but they will be still shown for smooth user experience
                        if(i == 0 || i == 1)
                        {
                            chk.setEnabled(false);
                            chk.setSelected(false);
                            //chk.setIcon(new ImageIcon(Icons.class.getResource("check.png")));
                        }
                        else
                        {
                            chk.setSelected(true);
                        }
                        chk.addItemListener(action);
                        super.addItem(chk);
                    }
                }
            }
        };
        this.setColumnControl(controlButton);
    }
}

and if you need to hide controls for "show horizontal scrollbar", "pack" and "pack all" add into code:

//remove items for horizontal scrollbar, pack and packall
this.getActionMap().remove("column.horizontalScroll");
this.getActionMap().remove("column.packAll");
this.getActionMap().remove("column.packSelected");

right after calling super(model)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top