ScreenFragment Events

This section describes the lifecycle events that can be handled in fragment controllers.

InitEvent

This event is sent when the fragment controller and all its declaratively defined components are created, and dependency injection is completed. Nested fragments are not initialized yet. Some visual components are not fully initialized, for example, buttons are not linked with actions. If the fragment is attached to the host screen declaratively in XML, this event is sent after InitEvent of the host controller. Otherwise, it is sent when the fragment is added to the host’s component tree.

AfterInitEvent

This event is sent when the fragment controller and all its declaratively defined components are created, dependency injection is completed, and all components have completed their internal initialization procedures. Nested screen fragments (if any) have sent their InitEvent and AfterInitEvent. In this event listener, you can create visual and data components and perform additional initialization if it depends on initialized nested fragments.

AttachEvent

This event is sent when the fragment is added to the host’s component tree. At this moment, the fragment is fully initialized, InitEvent and AfterInitEvent have been sent. In this event listener, you can access the host screen using getHostScreen() and getHostController() methods.

An example of listening to AttachEvent:

@UiController("sample_AddressFragment")
@UiDescriptor("address-fragment.xml")
public class AddressFragment extends ScreenFragment {
    private static final Logger log = LoggerFactory.getLogger(AddressFragment.class);

    @Subscribe
    private void onAttach(AttachEvent event) {
        Screen hostScreen = getHostScreen();
        FrameOwner hostController = getHostController();
        log.info("onAttach to screen {} with controller {}", hostScreen, hostController);
    }

DetachEvent

This event is sent when the fragment is programmatically removed from the host’s component tree. You cannot access the host screen in this event listener.

Listening to Host Screen Events

In a fragment controller, you can also subscribe to events of the host screen by specifying the PARENT_CONTROLLER value in the target attribute of the annotation, for example:

@Subscribe(target = Target.PARENT_CONTROLLER)
private void onBeforeShowHost(Screen.BeforeShowEvent event) {
    // ...
}

Any event can be handled this way including InitEntityEvent sent by entity editors.

Listening to Fragment Events in Host Screen

In a host screen controller, you can subscribe to the events sent in a fragment controller. Below is an example of handling a custom event sent by the fragment when the value of its component changes.

In the fragment controller, create the event class and a method for registering listeners of this event:

AddressFragment.java
public static class CountryChangeEvent extends EventObject { (1)

    private Country country;

    public CountryChangeEvent(Object source, Country value) {
        super(source);
        country = value;
    }

    public Country getCountry() {
        return country;
    }
}

public Subscription addChangeListener(Consumer<CountryChangeEvent> listener) {
    return getEventHub().subscribe(CountryChangeEvent.class, listener); (2)
}

@Subscribe("countryField")
public void onCountryFieldValueChange(HasValue.ValueChangeEvent<Country> event) {
    fireEvent(CountryChangeEvent.class, new CountryChangeEvent(this, event.getValue())); (3)
}
1 Create a custom event class by extending EventObject.
2 Create a method for registering listeners of the custom event.
3 Send the custom event using fireEvent() method.

Now you can declaratively subscribe to the custom fragment event in the host controller as follows:

HostScreen.java
@Autowired
private Notifications notifications;

@Subscribe(id = "addressFragment", target = Target.CONTROLLER) (1)
protected void onChange(AddressFragment.CountryChangeEvent event) {
    notifications.create()
            .withCaption("Changed country: " + event.getCountry())
            .show();
}
1 Use the fragment id and Target.CONTROLLER to subscribe to the fragment event.