table.setVisibleColumns feature

Hello!

I’m found next feature of table.setVisibleColumns method.
Not sure, this feature is bug, but may be is usefull fo you:

I’m try to fill table and set visible columns:

    public void btnRefreshClick(Button.ClickEvent event)
    {
        System.out.println("btnRefreshClick()");
        table.removeAllItems();
        
        table.addContainerProperty("N", Integer.class, null);
        table.addContainerProperty("F1", String.class, null);
        table.addContainerProperty("F2", String.class, null);
        table.addContainerProperty("F3", String.class, null);
        table.addContainerProperty("ID", String.class, null);
        try
        {
            for (int i = 0; i < 10; i++)
            {
                table.addItem(new Object[] { new Integer(i + 1), "Title",
                        "Title2",
                        "Title3",
                        "ID"}, new Integer(i));
            }
            table.setVisibleColumns(new Object[] { "N", "F1", "F2", "F3"});
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

This code seems ok, but work fine only once!
With second call btnRefreshClick() clear table and leaves empty!
It seems like table.addItem() not work with second call on btnRefreshClick, but problem in …setVisibleColumns!
If I’m try to comment setVisibleColumns line - all work fine, table refresh sucessfull!

I’m found next workaround this issue:

  1. Set visible all columns
  2. table.addItems
  3. Set visible necessary columns
    public void btnRefreshClick(Button.ClickEvent event)
    {
        System.out.println("btnRefreshClick()");
        table.removeAllItems();
        
        table.addContainerProperty("N", Integer.class, null);
        table.addContainerProperty("F1", String.class, null);
        table.addContainerProperty("F2", String.class, null);
        table.addContainerProperty("F3", String.class, null);
        table.addContainerProperty("ID", String.class, null);
        table.setVisibleColumns(new Object[] { "N", "F1", "F2", "F3", "ID"}); // set visible all columns!!!
        try
        {
            for (int i = 0; i < 10; i++)
            {
                table.addItem(new Object[] { new Integer(i + 1), "Title",
                        "Title2",
                        "Title3",
                        "ID"}, new Integer(i));
            }
            table.setVisibleColumns(new Object[] { "N", "F1", "F2", "F3"});
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

I assume you are using an IndexedContainer (the default) for the table.

The first obvious issue here is that you are adding the container properties multiple times. Adding a container property that is already there should not result in the container having the same property many times, but it does interact with the list of visible properties.

In fact, it would be much cleaner and more efficient to both add the container properties and set the visible columns only once where you create/configure the table before adding any items to it, not in the button click listener. If you do want to change the container properties afterwards, first remove the old container properties.

If you add and remove container properties correctly, I believe setVisibleColumns() should not cause problems.

Ok, first time I’m try to do so!

// Init code in AbsoluteLayout buildMainLayout()

table.addContainerProperty("N", Integer.class, null);
table.addContainerProperty("F1", String.class, null);
table.addContainerProperty("F2", String.class, null);
table.addContainerProperty("F3", String.class, null);
table.addContainerProperty("ID", String.class, null);

table.setVisibleColumns(new Object[] { "N", "F1", "F2", "F3"});
btnRefreshClick(null);

...

    public void btnRefreshClick(Button.ClickEvent event)
    {
        System.out.println("btnRefreshClick()");
        table.removeAllItems();
        try
        {
        for (int i = 0; i < 10; i++)
            {
                table.addItem(new Object[] { new Integer(i + 1), "Title",
                        "Title2",
                        "Title3",
                        "ID"}, new Integer(i));
            }
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

But in this case - I’m get empty table without any rows!
I found - addItem must contain only visible columns like in my first post.

How to correctly set visible properties and add items?

Add the items to the container of the table - or even directly to the table - but not using the addItem(Object, Object) method. Using that method is not a good idea when modifying the visible columns list (nor when modifying the property set of the container on the fly) - the method is just there for convenience in the trivial cases.

The normal data API is to use getContainerProperty(…).setValue(…) instead, then you also have full control over what value goes to what property etc. You can of course create your own helper method that takes all the property values for a new item and sets them using the data API.

I’d like to know why adding items via addItem(Object, Object) “is not a good idea”. Even the docs tell us to do so on the 1st example:

https://vaadin.com/docs/v7/framework/components/components-table.html

So I simply followed the instructions and did it this way.

But if I add, let’s say, 5 container properties (via .addContainerProperty) prior to inserting any items and then try to hide, let’s say, the last 2 ones via a .setVisibleColumns(new Object{ “col1”, “col2”, “col3”} ) , and then I try to insert some items, all I get is a NPE.

Looking at the sources, one can see that the code is clearly buggy, or so it seems to me. When TreeTable.addItem() adds the new item via that method, it calls Table.addItem(), which iterates through the VISIBLE! columns and adds these visible
column names to a temporary list that then it’s compared against the number of total columns; and as it’s not the same, it will return… null!! – effectively not inserting the item as it skips the subsequent code.

Other containers don’t seem to have this odd behaviour when inserting new items when some columns are hidden, thus adding confusion. Also, instead of simple returning null, some other, more clear, information, like an exception telling us what actually happened would be much more useful.

Oh well.