If you reached this article, you most likely face one of these errors, and trying to get rid of one, get another: «variable used in lambda expression should be final or effectively final», «variable may be not initialized», «cannot assign a value to final variable».
For my explanation I will use vaadin’s Window.
public class SelectionWindow extends Window { private Button okButton = null; private BeanItemContainer container; private LegalEntity selected; public SelectionWindow(List items){ ... setClosable(false); container = new BeanItemContainer<>(Entity.class, items); grid = new Grid(container); grid.addSelectionListener(event -> { Object selectedObj = grid.getSelectedRow(); selected = (LegalEntity) selectedObj; if (okButton != null) { okButton.setEnabled(selected != null); } }); } // the only way to close the window public void setOkButtonListener(Button.ClickListener listener) { okButton.addClickListener(listener); } // this way we get selected item public Entity getSelected() { return selected; } } |
So, to pass params into the Window you just add arguments to the constructor. In my case I don’t need a private field List items. If I did, I would add:
private List items; |
and a line to constructor:
this.items = items; |
You can use setters as well.
Case 1. You just need to read selected value and to use right in the code of the listener.
SelectionWindow selectionWindow = new SelectionWindow(items); selectionWindow.setOkButtonListener(clickEvent -> { Entity selected = selectionWindow.getSelected(); populateFromSelection(selected); selectionWindow.close(); }); private void populateFromSingleSuggestion(LegalEntity legalEntity) { // react upon the new value } |
The point is that you know in the code when your Window gets closed. On this event you can read any field/state from it (you can add getters) and update your UI.
Case 2. You want to read a value and assign to a variable with a wider scope. Use atomic reference.
final AtomicReference reference = new AtomicReference<>(); selectionWindow.setOkButtonListener(clickEvent -> { reference.set(selectionWindow.getSelected()); selectionWindow.close(); }); |
Then get your item with reference.get().