Creating Nifty elements with no parent, for attaching/detaching later?

Hello all,

Working on an RTS like game, and I want to be able to dynamically put the available actions on the screen depending on what the player has selected. I have something that works, but it’s horribly inefficient and produces duplicate ID warnings whenever it changes.

My current code looks like this:
[java]
public void replaceActionButtons(){
availableEntityActions.clear();//this gets the actions available based on the player’s currently selected units
for(int i = 0; i<selected.size(); i++){
if(i==0){
availableEntityActions.addAll(selected.get(i).getAvailableActions());
} else {
availableEntityActions.retainAll(selected.get(i).getAvailableActions());
}
}
Nifty nifty = app.getNifty();
Screen s = nifty.getCurrentScreen();
Element layer = s.findElementByName(“actionPanel”);//remove all rows of buttons
for(Element e : layer.getElements()){
e.markForRemoval();
}
nifty.executeEndOfFrameElementActions();//force removal

    PanelCreator rowpc = new PanelCreator();//creator for the row panels
    rowpc.setWidth("100%");
    rowpc.setHeight("10%");
    rowpc.setChildLayout("horizontal");
    rowpc.setAlign("left");
    rowpc.setVAlign("top");
    
    int colsPerRow = 6;
    
    PanelCreator actpc = new PanelCreator();//creator for the panel for each button (will be the actual button)
    actpc.setWidth(100/colsPerRow + "%");
    actpc.setHeight("100%");
    actpc.setChildLayout("vertical");
    actpc.setAlign("center");
    actpc.setVAlign("top");
    actpc.setBackgroundColor("#000a");
    
    
    String worldActInteractFmt = "selectWorldAction(%s,%s)";//format strings for callback methods and image locations
    String entActInteractFmt = "selectEntAction(%s,%s)";
    String worldActImgFmt = "/Interface/actions/world/%s.png";
    String entActImgFmt = "/Interface/actions/entity/%s.png";
    
    
    ImageCreator ic = new ImageCreator();//creator for image
    ic.setWidth("100%");
    ic.setHeight("75%");
    
    TextCreator tc = new TextCreator("");//creator for the text
    tc.setStyle("nifty-label");
    tc.setColor("#00ff");
    tc.setWidth("100%");
    tc.setHeight("25%");
    
    
    
    int row = 0;
    int col = 0;
    int index = 0;
    Element rowE=null;
    for(WorldAction act : availableWorldActions){//world action buttons 
        if(index%colsPerRow==0){
            rowE = rowpc.create(nifty, s, layer);//create new row
            col=0;
            row++;
        }
        
        String actpcid = "row"+row+"col"+col;
        
        actpc.setId(actpcid);
        actpc.setInteractOnClick(String.format(worldActInteractFmt, act.getName(),actpcid));
        
        Element actE = actpc.create(nifty, s, rowE);//create button
        
        ic.setFilename(String.format(worldActImgFmt,act.getName()));
        ic.create(nifty, s, actE);//create image
        
        tc.setText(act.getName());
        tc.create(nifty, s, actE);//create text
        
        
        index++;
        col++;
    }
    for(EntityAction act : availableEntityActions){//same as above but for entity related actions
        if(index%colsPerRow==0){
            rowE = rowpc.create(nifty, s, layer);
            col=0;
            row++;
        }
        
        String actpcid = "row"+row+"col"+col;

        actpc.setId(actpcid);
        actpc.setInteractOnClick(String.format(entActInteractFmt, act.getName(),actpcid));
        
        Element actE = actpc.create(nifty, s, rowE);
        ic.setFilename(String.format(entActImgFmt,act.getName()));
        ic.create(nifty, s, actE);
        
        tc.setText(act.getName());
        tc.create(nifty, s, actE);
        
        
        index++;
        col++;
    }
}

[/java]

My question is, I’d like to pre-create all the buttons for every possible action in the game and just attach and detach them as needed, but I cannot find a way to create elements without providing a parent element in the docs. Is there a way to pre-generate these elements programmatically? eg:
[java]
//constructor
for all actions in game {
create button elements // How do I do THIS?
put button element in map from action id to Element
}

//in the replace buttons method
find actions that have been displayed but are no longer available
remove those actions from display // Mark for removal should work

find actions that have not been displayed but are now available
add those actions to display using elements from map created before // How do I do THIS?

[/java]
This scheme would prevent the new creation of elements over and over, and would alleviate the need for the executeEndOfFrameElementActions call. Is there a way to accomplish this that I’m not seeing in the docs?

Personally… I wouldn’t bother trying to pre generate them. In my game I have a good 60-120 elements that can be added on a given frame and it doesn’t appear to cause any problems so far. Yes, it is inefficient but especially in your case you only change the buttons on unit selection which for a game… isn’t that often.

I’m not sure why you are calling the executeEndOfFrameActions call either since I would assume that isn’t meant to be called by the user. I’m not sure why you are getting duplicate ID warnings, however, because I remove and then add elements with the same ID without hitting that warning.

If you are still dead set on trying to make this work… you could always add everything and then hide it. Then when you want to “Add” it you would just have to show / hide the applicable buttons.

The executeEndOfFrameActions is there so that the things i remove actually get removed, I was hoping it would stop the duplicate ID problem, it didn’t. I like the show/hide idea. I think I will go with that, however I would still like to know if there is a way to pre generate. I’m also curious why I’m getting the duplicate id warnings.