[Solved] Lemur ListBox clicks not registering

I’ve begun using Lemur ListBoxes for some things in my game. I ran into an unexpected problem though: It seems that, especially on smaller screens (smaller listboxes as they’re scaled), it often does not register the click. As in, the things in the command method are not called.
Any ideas on why this might be happening and how to fix it? (My guess is that it might check if you clicked the text and not anywhere on the column?)

One possible cause is that you’ve scaled down the Z and that the layers are no longer distinct from one another… so you are getting BitmapText clicks instead of background clicks or background panel clicks instead of item clicks or something.

Some debugging would be required to know for sure… like register some CursorListeners and see what’s actually coming through in the geometry versus when it’s working.

Preferred Z size is always 0. Is that a problem?

Definitely.

Setting it to 1 doesn’t change anything. :frowning:

No, of course not.

The problem is that all of the things “in” the GUI element think they should be 0… which is why the preferred size is calculating z at 0. So it’s all flattened and the collision picking stuff can’t figure out what you’ve clicked on.

Forcing the preferred size of the outer element to something is only hiding the problem. The issue is that your elements themselves are all flat for some reason. Some kind of non-standard configuration of them or something because normally things like QuadBackgroundComponent, etc. all default to have some z size.

Nevermind, turns out I’m stupid.
I also had it at the same height as the background. Setting the Z position to 1 fixed it.
(I’m using a standard ListBox btw.)
Thanks for the help.

1 Like

xD!

I get this problem a lot.

Sorry for reopening this, but the problem has cropped up again (it seems that I never really fixed it).
Anyway, clicks only register sometimes.
Here’s my listbox creation code:

ListBox usedChassisParts = new ListBox();
usedChassisParts.setName("usedChassisParts");
usedChassisParts.setPreferredSize(new Vector3f(program.getSettingVariables().WIDTH / 6, program.getSettingVariables().HEIGHT / 4f, 1));
usedChassisParts.setLocalTranslation(usedChassisParts.getPreferredSize().x * 0.2f, program.getSettingVariables().HEIGHT / 1.25f, 1);
botWorkshopNode.attachChild(usedChassisParts);

WIDTH and HEIGHT are the width and height of the window in pixels, and the botWorkshopNode is just a node I attach to the GuiNode.

Here’s how I fill the listbox:

ListBox lUsedChassisParts = (ListBox) botWorkshopNode.getChild("usedChassisParts");
lUsedChassisParts.getModel().clear();

if(lUsedChassisParts.getClickCommands() != null)
{
    lUsedChassisParts.getClickCommands().clear();
}
        
final int selectedChassisPart = program.getStateManager().getState(BotWorkshopState.class).getSelectedChassisPart();
        
for(int i = 0; i < config.getChassisParts().length; i++)
{
    //Workaround because the variable passed to the listbox needs to be final
    final int i2 = i;
    final String string = BotPartList.getInstance().getLocalizedNameForChassisPart(config.getChassisParts()[i], langFile) + " (" +
                    config.getWeightInContainer(i2) + "/" + BotPartList.getInstance().getChassisPartById(config.getChassisParts()[i2]).getWeight() + ")";
    lUsedChassisParts.getModel().add(string);
    lUsedChassisParts.addClickCommands(new Command<ListBox>()
    {
        @Override
        public void execute(ListBox source)
        {
            if(source.getSelectionModel().getSelection() == source.getModel().indexOf(string))
            {
                program.getStateManager().getState(BotWorkshopState.class).setSelectedChassisPart(i2);
                program.getStateManager().getState(BotWorkshopState.class).updatePartLists();
            }
        }
    });
}

Any idea what could be causing this?

Why do you add so many click commands? It seems to me that one would do.

…or even just watch the selection model for when it changes and then setSelectedChassis() and updatePartLists().

1 Like

Actually, that whole chain of logic is really strange to me.

To me it looks like:
“construct a string for i’s chassis”
“add that string to the model”
“if the index of that string is the same as the selection then it’s the one”

…but isn’t that just that same as checking to see if the selection is i2?

And anyway, wouldn’t it be easier just to add the chassis objects to a list and use that as your model?

ListBox<Chassis> instead of ListBox<String>?

1 Like

So, what I’m doing is the following (In hopes of explaining it better):
First, I get the localized name for the chassis part (which is just an int).
Then I add it to the model as it was my understanding that that is how you use listboxes.
And lastly, I add a command for each of the strings that then does things according to which item you selected.

I would be open to rewriting this whole thing though as I created it a good while ago and it probably could use that.

Anyway, I don’t think that this has much to do with my actual problem: As far as I know, the logic is working fine, but Lemur is sometimes not calling the methods, this happens even more often when I already have the object selected but click on it again.

But you are adding click commands to the list box… which might never get clicks if the item gets them first.

Better to just use the list box as its designed. Put your chassis objects in the list box and give it custom cell renderer to use the string you like.

Could you point me to an example of how the listbox is supposed to be used (with adding click commands)?
I’ll then rewrite my code accordingly.

A bit like this, and just watch the selected index.

https://github.com/jayfella/menu-menubackgrounds/blob/master/src/main/java/com/jayfella/menubackgrounds/menu/BackgroundChooserMenu.java#L73

1 Like

Thank you, that looks promising. Will report back when I have something done.
EDIT: I need to modify the list on-the-fly, I’ve been doing that with getModel().clear() and getModel().add(). Is that a problem?
EDIT 2: Also, I can’t compare i2 and the selection, as i2 is an index of another list and arraylists like sorting themselves for some reasen, so I prefer do it the indexOf() way, as the other one created problems back when I wrote this.

Except you use it to indexing into the model… and then compare to the model… and anyway, there is no reason to put strings in the model at all. ListBox is a container for anything. Not just strings.

Not sure that I understand what the problem with putting strings into the model is. The lists are mainly stored somewhere else because it makes sense to have them there. So I might just as well put strings into the model.

But then you have to translate on the way in. Translate on the way out. Translate each selection… what a pain.

Anyway, this is not really my problem.
You said the items might be getting the clicks before the listbox does. How would I stop that from happening?