Reusing nifty popups / eventbus issues

I’m having some trouble trying to re-use a popup. I’ve created a configuration popup that the user can bring up by hitting the escape key. I want the user to be able to close and re-open the popup without having to switch screens (and it shouldn’t matter which screen they are on). I’ve defined the popup in the nifty xml outside of the screen definitions like so:

[xml]

<screen id=“screen1” …>

</screen>

<popup id=“settings” … controller=“test.MyController”>

</popup>

[/xml]

I’m opening and closing the popup like this:



private Element popup = nifty.createPopup(“settings”);

public void showPopup() {

if (! nifty.isActivePopup(popup)) {

nifty.showPopup(nifty.getCurrentScreen(), popup.getId(), null);

}

}



In test.MyController:



public void close() {

// nifty and element are from Controller.bind(nifty, screen, element, properties, attributes)

nifty.closePopup(element.getId());

}



I have several dropdown controls inside the popup panel and I’m listening to drop down events:



// I’m prefixing my patterns with the package and class name.

@NiftyEventSubscriber(pattern=“test.MyController.")

public void onDropDownSelectionChanged(final String id, final DropDownSelectionChangedEvent event) {

System.out.println("Changed: " + id);

}

private DropDown myDropDown1;

public void onStartScreen() {

myDropDown1 = element.findNiftyControl(“test.MyController.dropDown1”, DropDown.class);

myDropDown1.clear();

// rebuild the dropdown: myDropDown1.addItem() and myDropDown1.selectItemByIndex()

}



Nifty is adding another eventbus subscriber every time the popup is created but not removing the old one. I can tell this is happening by seeing the number of times “Changed: id” being output when I close/open the popup. Everytime I re-open it, I can more and more lines of “Changed: id”. All my efforts to unsubscribe manually have not warrented any results.

The following will remove the topic subscribers.



List list = nifty.getEventService().getSubscribersToTopic("test.MyController.
”);

for (Object o: list) {

nifty.unsubscribe(“test.MyController.", o);

}



However this list,



List list2 = nifty.getEventService().getSubscribers("test.MyController.
”);



will always grow even when I try to unsubscribe manually via:



for (Object o: list2) {

nifty.getEventService().unsubscribe(“test.MyController.*”, o);

}





Ultimately, what I’m trying to do is allow for the user to close and re-open the popup window. I’m also wanting to able re-build the dropdown menus without the selection changed events firing. I need to do this because the content of dropdown2 depends on the selected value of dropdown1.



Edit: I’m not sure if i’m opening and closing the popups wrong or if there’s a bug in nifty where the events aren’t being unsubscribed when the popup is closed. In either case, I’d like to be able to temporarily disable the event notifications when I need to rebuild the dropdowns.




  • User changes DropDown1

    – Event fires and calls OnSelectionChange()

    — Disable events

    — Clear DropDown2

    — Add new items to DropDown2

    — Select previously selected item in DropDown2 if the old selection exists in the new items,

    otherwise, default to the first item.

    – Enable events

yes, this looks like a bug!



Nifty automatically checks for NiftyEventSubscriber annotations when a popup is shown and automatically subscribes them. Therefore it should unsubscribe them when the popup is closed. I’ve took a quick look and it seems like this is indeed missing. I’ll see if I can fix this.



about your second issue: well, you can always unsubscribe from events if you don’t want them. just like you’re doing already.



uhm, on a second thought I think the nifty.unsubscribe() method is not quite right implemented by Nifty :slight_smile: it requires an elementId and not a pattern! and it will unsubscribe all (!) NiftyEventSubscriber annotated methods (and not only the one for the elementId the method is expecting). I’ll take a look at this issue as well.



this does not work as you expect it:



[java]nifty.unsubscribe(“test.MyController.*”, o);[/java]



because that nifty.unsubscribe() method does not expect a pattern for the id I think.



in the meantime you could try to unsubscribe directly using the EventBusService. but you should take a look at the way Nifty subscribes to events internally first (there is some trickery involved).



I think the methods Nifty provides should be a bit clearer how they work … I’ll try to fix that. thanks for pointing at these issues :slight_smile: