Ruslan  Gabbazov Ruslan Gabbazov - 4 months ago 20
Java Question

Wrong TableView header width when using TableView.CONSTRAINED_RESIZE_POLICY

It's actualy a known bug and steel opened a bug report for JavaFX, which you may found
here.

Description is:

When ColumnResizePolicy is setted to CONSTRAINED_RESIZE_POLICY and table have data that is not fit in available tableview's height (vertical scroll is visible) then headers have improper width - but only when TableView is not focused. When TableView get focus then headers are getting proper width.

The problem is, I really need to fix it somehow, but i can't find any workaround to do that.

I tried:

refresh()

and just "jumping" out and in

otherGUIObject.requestFocus();
tableView.requestFocus(); //or getSelectionModel().Select(0)
otherGUIObject.requestFocus();


also

tableView.setColumnResizePolicy(TableView.UNCONSTRAINED_RESIZE_POLICY);
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);


But nothing seems to work. Have someine any ideas?
Thanks!

Answer

You are on the correct track: you shall call requestFocus() on the TableView.

The problem with this snippet from your question

otherGUIObject.requestFocus();
tableView.requestFocus(); //or getSelectionModel().Select(0)    
otherGUIObject.requestFocus();

is that when you call requestFocus(), the focusedProperty of the Node is set to true as expected, but it does not mean, that the control is actually gets focused on the GUI (the layout gets updated), as it is only updated when the JavaFX application thread has time to update it. In the snippet you make three requestFocus calls in a row, and the first two of these calls will be optimized, therefore only the last one is executed (most probably).

The solution is to call requestLayout method on the TableView after the focus is requested to ensure that the focus is updated on the GUI also. After that you can set the focus on any other Node (in the example I have used focusOwnerProperty of Scene to get which Node is currently selected, then after the TableView was focused, I focus this Node again).

Example

// The current focus owner on the Scene
Node focusOwner = scene.getFocusOwner();

table.requestFocus();
table.requestLayout();

// Request focus on the currently focused Node
if(focusOwner != null)
    focusOwner.requestFocus();
else
    // request focus on any Node you want
    textField.requestFocus();
Comments