Pairing Labels with Images when building a UI In a prototype 4X space game that I am working on recently, I have two different scroll panes to show the ships and the stars of the player.  The ships are displayed in a vertical scroll pane on the right side of the screen, and the stars are displayed in a horizontal scroll pane running along the bottom. Here is a picture for the sake of clarity:



With the vertical scroll pane, displaying the labels along with the images is very straightforward. When iterating over the list of ships, a label is added for each ship, then a row, then the ship image.

The horizontal scroll pane presents a problem, however.  I want to have the label displayed above the corresponding image.  Accomplishing this is a bit more complicated than simply adding a row between each element in the table.

I thought about having two lists, iterating over the first list and getting the correct element from the second list based on the index.  Instead of doing this, I went with a Map&lt;Label, Image&gt;.  I'm not sure about this decision, and would love feedback on this approach.  It feels wrong to be using a Map here, because I will never be using it to look up the values based on the keys.

First, I have this method that creates the contents that will be used when building the scroll pane:

private void createContents() {
    this.contents = new HashMap&lt;Label, Image&gt;();

    for (Star star : this.game.getPlayerStars()) {

        Image starImage = new Image(this.libGDXGame.starTextures.get(star.type));
        starImage.addListener(new StarClickListener(star) {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                StarScrollPane.this.gameScreen.playerClickedStar(star);
            }
        });

        Label starLabel = new Label(star.type.name(), this.libGDXGame.skin);

        this.contents.put(starLabel, starImage);
    }
}


Then I have another method that actually creates the table and adds the contents to it like this:

    for (Label label : this.contents.keySet()) {
        this.starTable.add(label);
    }

    this.starTable.row();

    for (Image image : this.contents.values()) {
        this.starTable.add(image).width(width).height(height);
    }


By adding all of the labels to the table, then one row, then all of the images, they line up perfectly.
A HashMap does not guarantee any order whatsoever, so that is a bad idea to use.

Your Image and Label belongs together, so make a class where they actually do belong together.

public class StarView {
    private final Label label;
    private final Image colorImage;
    // constructor and stuff...
}

private void createContents() {
    this.contents = new ArrayList&lt;StarView&gt;();

    for (Star star : this.game.getPlayerStars()) {

        Image starImage = new Image(this.libGDXGame.starTextures.get(star.type));
        starImage.addListener(new StarClickListener(star) {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                StarScrollPane.this.gameScreen.playerClickedStar(star);
            }
        });

        Label starLabel = new Label(star.type.name(), this.libGDXGame.skin);

        this.contents.add(new StarView(starLabel, starImage));
    }

    for (StarView starView : this.contents) {
        this.starTable.add(starView.label);
    }

    this.starTable.row();

    for (StarView starView : this.contents) {
        this.starTable.add(starView.image).width(width).height(height);
    }
}


This could be combined with @Vogel's suggestion about changing the layout manager. Or you could make the StarView extend Actor and put it in a horizontal group.