0

I'm new to java and javafx so I am still learning. I can get the images to display on a horizontal line but I can't make it selectable. I'm not sure if I am using the wrong layout or if I am missing something in the code.

Code

  List<Image> movieImages= movieDetails.movieImages(jsonRequest);
    ObservableList<Image> movies = FXCollections.observableList(movieImages);
    for(int i=0; i < movies.size(); i++){
        ImageView imageView;
        imageView = new ImageView(movies.get(i));
        hboxFanart.getChildren().addAll(imageView);
    }

FMXL

<Tab closable="false" text="Fanart">
            <ScrollPane>
                <HBox fx:id="hboxFanart" spacing="10">
                </HBox>
            </ScrollPane>
</Tab>
James_D
  • 201,275
  • 16
  • 291
  • 322
David
  • 79
  • 1
  • 6

1 Answers1

2

I altered @ItachiUchiha answer from here

As @James_D suggests, try using a ListView. Set the ListView orientation to horizontal.

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class App extends Application
{

    private final Image IMAGE_RUBY = new Image("https://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo_64x64.png");
    private final Image IMAGE_APPLE = new Image("http://findicons.com/files/icons/832/social_and_web/64/apple.png");
    private final Image IMAGE_VISTA = new Image("http://antaki.ca/bloom/img/windows_64x64.png");
    private final Image IMAGE_TWITTER = new Image("http://files.softicons.com/download/social-media-icons/fresh-social-media-icons-by-creative-nerds/png/64x64/twitter-bird.png");

    private final Image[] listOfImages = {IMAGE_RUBY, IMAGE_APPLE, IMAGE_VISTA, IMAGE_TWITTER};

    @Override
    public void start(Stage primaryStage) throws Exception
    {
        Label lblCurrentlySelected = new Label();
        StackPane stackPane = new StackPane(lblCurrentlySelected);

        ListView<String> listView = new ListView();
        listView.setMaxHeight(100);
        ObservableList<String> items = FXCollections.observableArrayList(
                "RUBY", "APPLE", "VISTA", "TWITTER");
        listView.setItems(items);
        listView.setOrientation(Orientation.HORIZONTAL);
        listView.setCellFactory(param -> new ListCell<String>()
        {
            private final ImageView imageView = new ImageView();

            @Override
            public void updateItem(String name, boolean empty)
            {
                super.updateItem(name, empty);
                if (empty) {
                    setText(null);
                    setGraphic(null);
                }
                else {
                    switch (name) {
                        case "RUBY" ->
                            imageView.setImage(listOfImages[0]);
                        case "APPLE" ->
                            imageView.setImage(listOfImages[1]);
                        case "VISTA" ->
                            imageView.setImage(listOfImages[2]);
                        case "TWITTER" ->
                            imageView.setImage(listOfImages[3]);
                        default -> {
                        }
                    }
                    setText(name);
                    setGraphic(imageView);
                }
            }
        });
        listView.getSelectionModel().selectedItemProperty().addListener((ov, oldItem, newItem) -> {
            if (newItem != null) {
                System.out.println("Selected: " + newItem);
                lblCurrentlySelected.setText(newItem);
            }
        });

        VBox.setVgrow(stackPane, Priority.ALWAYS);
        VBox box = new VBox(listView, stackPane);
        box.setAlignment(Pos.CENTER);
        Scene scene = new Scene(box, 500, 500);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args)
    {
        launch(args);
    }
}

Some links seem to be broken, but the ideas behind this are the same.

Output enter image description here

Based on your comment, I created an example using a POJO. That's assuming I understand what you are asking. The POJO keeps up with the name and image. That eliminates the need to have the Switch-Statement.

Code

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class App extends Application
{

    private final Image IMAGE_RUBY = new Image("https://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo_64x64.png");
    private final Image IMAGE_APPLE = new Image("http://findicons.com/files/icons/832/social_and_web/64/apple.png");
    private final Image IMAGE_VISTA = new Image("http://antaki.ca/bloom/img/windows_64x64.png");
    private final Image IMAGE_TWITTER = new Image("http://files.softicons.com/download/social-media-icons/fresh-social-media-icons-by-creative-nerds/png/64x64/twitter-bird.png");

    //private final Image[] listOfImages = {IMAGE_RUBY, IMAGE_APPLE, IMAGE_VISTA, IMAGE_TWITTER};
    private final ObservableList<MyItem> listViewItems = FXCollections.observableArrayList();

    @Override
    public void start(Stage primaryStage) throws Exception
    {
        listViewItems.add(new MyItem("Ruby", IMAGE_RUBY));
        listViewItems.add(new MyItem("Apple", IMAGE_APPLE));
        listViewItems.add(new MyItem("Vista", IMAGE_VISTA));
        listViewItems.add(new MyItem("Twitter", IMAGE_TWITTER));

        Label lblCurrentlySelected = new Label();
        StackPane stackPane = new StackPane(lblCurrentlySelected);

        ListView<MyItem> listView = new ListView();
        listView.setMaxHeight(100);
        listView.setItems(listViewItems);
        listView.setOrientation(Orientation.HORIZONTAL);
        listView.setCellFactory(param -> {
            return new ListCell<MyItem>()
            {
                private final ImageView imageView = new ImageView();

                @Override
                public void updateItem(MyItem myItem, boolean empty)
                {
                    super.updateItem(myItem, empty);
                    if (empty || myItem == null) {
                        setText(null);
                        setGraphic(null);
                    }
                    else {
                        setText(myItem.getName());
                        imageView.setImage(myItem.getImage());
                        setGraphic(imageView);
                    }
                }
            };
        });
        listView.getSelectionModel().selectedItemProperty().addListener((ov, oldItem, newItem) -> {
            if (newItem != null) {
                System.out.println("Selected: " + newItem.getName());
                lblCurrentlySelected.setText(newItem.getName());
            }
        });

        VBox.setVgrow(stackPane, Priority.ALWAYS);
        VBox box = new VBox(listView, stackPane);
        box.setAlignment(Pos.CENTER);
        Scene scene = new Scene(box, 500, 500);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args)
    {
        launch(args);
    }
}

POJO

import javafx.scene.image.Image;

/**
 *
 * @author Sedrick(sedj601)
 */
public class MyItem
{

    private String name;
    private Image image;

    public MyItem(String name, Image image)
    {
        this.name = name;
        this.image = image;
    }

    public Image getImage()
    {
        return image;
    }

    public void setImage(Image image)
    {
        this.image = image;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }
}
SedJ601
  • 12,173
  • 3
  • 41
  • 59
  • 1
    Do I need to have the String items (ie. Ruby, Apple, Vista..)? I just want the images. The problem that I am having with the code is adding only the images to the ListView. All the examples that I have seen show text along with the image. Again, sorry for my lack of knowledge here. – David Jun 10 '22 at 13:52
  • You do not have to use `setText(name);` in `listView.setCellFactory`. Just use `setGraphic(imageView)`. – SedJ601 Jun 10 '22 at 14:41
  • I guess my question is do I require the list of text to trigger what image is displayed or can I just have the image without the list of text? – David Jun 10 '22 at 17:32
  • I guess I don't truly understand what you are asking. I will take a guess though. This is a `List`. I think this could have been done better as a `List`. If you have a `List`. You will not need the `Switch` statement in `updateItem`. Is that what you are asking about? – SedJ601 Jun 10 '22 at 17:58