Here is how the screen looks (value column is hidden, but value header exists). ColumnHiding.jpg
Here is zipped up source to demostrate the issue. ColumnHiding.zip
On a secondary note, (and example code has some comments in regards to this).
The Grid is added to a VerticalLayoutContainer with VerticalLayoutData(-1,-1) This means that the grid should not resize if the parent is resized (if I understand this correctly). If the header text is present in the grid, then it behaves that way. However, if the header test is not set, then the table (header) will actually resize.
This is not a major issue, but may help show some of the resizing issues I'm currently experiencing, that I do not yet know if it is user error or a defect.
This is almost certainly due to the fact that by using the scheduler, you are in fact waiting until after the grid is rendered to execute the header hiding, while using a command that is meant to be called to set up the grid, not to modify it post render. The ColumnModel.setHidden method is designed to be used post-render, and is called when the user shows/hides columns from the UI.
If in your example you were to defer adding the grid to a parent until after the scheduleFinally was completed, I believe it would behave as expected. Set a breakpoint in your scheduler call, and one in GridView.render to see that your code is running post-render.
Edit: Sorry, I must have not read part of the message last time, specifically where the header is drawn, but nothing else is. The answer above is correct, in that the grid itself (and the headers) have been rendered, but leaves out the fact that by default, items are not rendered at the same time for performance reasons.
Item rendering is deferred through setLazyRowRender(int) - the default is 10ms, allowing the browser to draw the rest of the page, and return to finish the rows when it can schedule time. Setting this to 0 will make the grid finish all of its drawing at the same time, but it may take longer to do so than it normally would.
Using the scheduleFinally, as mentioned above, will move your scheduled call until just after the next few method invocations have finished, but before the event loop has finished and returned. In contrast, scheduleDeferred will move the calls to the next event loop, the next time the browser decides to do something.
If you want a setter to be called after the rows have finished drawing, even when deferred, listen for the ViewReadyEvent on the grid.