[Nifty] Nifty 1.3 and Dropdown

Hello,



I’m trying to use Nifty 1.3 and I have some issues.



I add a screenController that managed Dropdown controls.

Until now, I had to specify that my ScreenController implements DropdownNotify.



[java]

public class CharacterJobsController implements ScreenController, DropDownControlNotify

[…]

DropDownControl = jobListing = screen.findControl( “jobListing”, DropDownControl.class );

[…]

jobListing.addNotify( this );

[…]

@Override

public void dropDownSelectionChanged( DropDownControl control )

{

if( control == jobListing )

loadDataForSelectedJob();

else […]

}

[/java]



For what I have understood, now I don’t need to specify the interface

[java]

public class CharacterJobsController implements ScreenController

[…]

@SuppressWarnings(“unchecked”)

DropDown<String> jobListing = screen.findNiftyControl(“jobListing”, DropDown.class);

[…]



@NiftyEventSubscriber(id=“dropDown”)

public void onDropDownSelectionChanged(final String id, final DropDownSelectionChangedEvent<String> event)

{

if( event == jobListing )

loadDataForSelectedJob();

else […]

}

[/java]

This new methods is really easier to read. Thanks



I just have one orr two question about the new Dropdown API :


  • I didn’t find a getSelectedIndex() method. Is this a wanted miss ?

    I suppose this works ( I still havn’t been able to compile my project so I didn’t verify ) :

    [java]

    int jobIndex = jobListing.getItems().indexOf( jobListing.getSelection() );

    [/java]


  • The method onDropDownSelectionChanged takes a DropDownSelectionChangedEvent. The previous method took the DropdownControl directly.

    Is there a way to retrieve the dropdown control that triggered the event from the DropDownSelectionChangedEvent class ?

    For now, I simply assumed that the DropDownSelectionChangedEvent is an interface of the same object .

    ( But like for the previous one. It compiles, but I still can’t check if my hypothesis is correct )

    [java]

    @NiftyEventSubscriber(id=“dropDown”)

    public void onDropDownSelectionChanged(final String id, final DropDownSelectionChangedEvent<String> event)

    {

    if( event == jobListing )

    loadDataForSelectedJob();

    else […]

    }

    [/java]





    Thanks in advance ! This version 1.3 is really promising.



    Edit :

    I just read the post : “ActionListener” for a nitfy checkbox?

    It seems my solution won’t work for the second question.



    In fact, I have two dropdown in my screen : “jobListing” and “jobPageListing”



    This line is wrong then :

    [java]

    @NiftyEventSubscriber(id=“dropDown”)

    [/java]

    It should be something like

    [java]

    @SuppressWarnings(“unchecked”)

    @NiftyEventSubscriber(id=“jobListing”)

    @NiftyEventSubscriber(id=“jobPageListing”)

    public void onDropDownSelectionChanged(final String id, final DropDownSelectionChangedEvent<String> event)

    {

    DropDown<String> control = screen.findNiftyControl( id, DropDown.class );

    if( control == jobListing )

    loadDataForSelectedJob();

    else if( control == jobPageListing )

    {

    loadSkills();

    updateJobDescription();

    }

    }

    [/java]

    I don’t really know how this annotation system works. Can you give me a tip?
  1. Yes, there currently is no getSelectedIndex() method. The idea is that you would store “whatever object you want” directly in the DropDown so that you could retrieve the current selected “whatever object you want” by calling getSelection().



    We could easily add a getSelectedIndex() method tho. Is that really required/wanted/needed?


  2. There currently is no way to retrieve the DropDown control directly from the DropDownSelectionChangedEvent. Assuming that the DropDownSelectionChangedEvent is the actual DropDown won’t work!



    We assumed that you would look up the dropdown with the id you’re given but transmitting the actual DropDown control in the DropDownSelectionChangedEvent would absolutly be possible too. You want that? :smiley:


  3. The Nifty 1.3 annotations will make writting event handlers for things like onChangeEvents a breeze. All you need to do is to annotate a method with a matching method signature with @NiftyEventSubscriber(id=“elementId”) and Nifty will automagically call this method when the specified (matching) event is created by the control with the id “elementId”.



    You can attach the same event handler to multiple elements with the @NiftyEventSubscriber(pattern="") syntax.



    Here is an example straight out of the new “nifty-default-controls-examples” project:



    [xml] /**
  • This is an example how we could use a regular expression to select the elements we’re interested in.
  • In this example all of our CheckBox Nifty Ids end with "CheckBox" and - in this example - all Checkboxes
  • influence the SelectionMode of the ListBox. All CheckBoxes really do the same here so we can take
  • this shortcut of handling all CheckBoxes equal.

    *
  • And we can demonstrate the @NiftyEventSubscriber annotation in pattern mode :slight_smile:

    */

    @NiftyEventSubscriber(pattern=".*CheckBox")

    public void onAllCheckBoxChanged(final String id, final CheckBoxStateChangedEvent event) {

    listBox.changeSelectionMode(getSelectionMode(), forceSelectionCheckBox.isChecked());

    }[/xml]



    The prefered way would be to have individual event handlers for individual controls tho. This will remove the somewhat ugly if / else if construct from your second example :slight_smile: “real programmers don’t use if”



    Please Note:

    The annotations will only automatically work on ScreenControllers.

    You can use them on other kind of classes but you’ll need to call “Nifty.processAnnotations(myInstance)” to enable them.
  1. I will find it usefull, even if I think I can manage without it.



    Here is an example of how I create on of my screens :

    I have a list of characters

    [java]

    Vector<Character> characterList;

    [/java]



    And my screeen is divided into two colums.

    Column 1 : The names of the character ( from characterList )

    Column 2 : The description of the selected character.



    I populate colum 1 like that :

    [java]

    for( int i = 0; i < characterList.size(); i++ )

    dropdown.addItem( characterList.get( i ).getName() );

    [/java]

    And when I change selection on the dropdown, I retrieved the corresponding Character fron the selection index.

    [java]

    int index = dropdown.getSelectedIndex();

    Character character = characterList.get( index );

    [/java]

    So i want say it’s something I can’t live without, but still something usefull :slight_smile:



    2&3. Good !

    I just needed to now this pattern keyword, Thanks !

The method Nifty.processAnnotations seems to be gone from the latest Nifty. What is the correct way to do it now?

Not sure when this has happend but it is called now:



[java]public void subscribeAnnotations(final Object object);

public void unsubscribeAnnotations(final Object object);[/java]



Please note the following SVN commit, that describes all of the ways on how you can subscribe for events. Too bad this information hasn’t found it’s way into the wiki yet :confused:



@public

Nifty does now track all EventBus subscribers a bit differently which should fix the issue with missing unsubscribe calls for popup elements. The following ways are now supported:


  • NiftyEvent annotations are automatically subscribed/unsubscribed for all ScreenControllers as well as all Controllers (this means you just need to annotate stuff with the appropriate @NiftyEventSubscriber in ScreenControllers/Controllers and there is nothing else to call)
  • if you manually subscribe to events via a call to the nifty.subscribe() method then these subscribers are automatically unsubscribed when the screen the event is attached too ends or the element the event is attached too is removed from a screen (this should now work too for popups, when they are being closed)
  • everything else that you subscribe manually you will need to unsubscribe manually too
  • you can call nifty.subscribeAnnotations(final Object object) and nifty.unsubscribeAnnotations(final Object object) on any object to enable the Nifty EventBus annotations for your own Objects (when these methods are not part of a ScreenController or Controller) you just need to make sure that you call unsubscribeAnnotations manually too