Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFx : How to put ImageView inside ListView

Tags:

java

javafx

I've been searching some threads about JavaFx ListView still it's hard to look for a simple yet easy solution for putting a JavaFx ImageView inside JavaFx ListView. I am trying to create a chat application using JavaFx framework. at the photo it should look like that.This is not duplicate because the other thread is vague for a beginner like me. ListView with imageview inside

I tried something like this. I'm totally noob to this thanks in advance!

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
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.VBox;
import javafx.stage.Stage;

public class Main extends Application {
     ImageView imageView = new ImageView();
     Image image = new Image(Main.class.getResourceAsStream("bell.jpg"));
    ListView<String> list = new ListView<String>();
    ObservableList<String> data = FXCollections.observableArrayList(
            "chocolate", "salmon", "gold", "coral", "darkorchid",
            "darkgoldenrod", "lightsalmon", "black", "rosybrown", "blue",
            "blueviolet", "brown");
   Image pic;

    @Override
    public void start(Stage stage) {
        VBox box = new VBox();
        Scene scene = new Scene(box, 200, 200);
        stage.setScene(scene);
        stage.setTitle("ListViewSample");
        box.getChildren().addAll(list);
        VBox.setVgrow(list, Priority.ALWAYS);
        list.setItems(data);

        list.setCellFactory(listView -> new ListCell<String>() {
            public void updateItem(String friend, boolean empty) {
                super.updateItem(friend, empty);
                if (empty) {
                    setText(null);
                    setGraphic(null);
                } else {

                    imageView.setImage(image);
                    setText(friend);
                    setGraphic(imageView);
                }
            }

        });

        stage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }
}`
like image 404
Justine Mackay Avatar asked Nov 08 '15 09:11

Justine Mackay


People also ask

How to populate list View in JavaFX?

You can populate the list by defining its items with the setItems method. You can also create a view for the items in the list by applying the setCellFactory method.

What is ImageView in JavaFX?

The ImageView is a Node used for painting images loaded with Image class. This class allows resizing the displayed image (with or without preserving the original aspect ratio) and specifying a viewport into the source image for restricting the pixels displayed by this ImageView .

What is a ListView in JavaFX?

A ListView displays a horizontal or vertical list of items from which the user may select, or with which the user may interact. A ListView is able to have its generic type set to represent the type of data in the backing model.


2 Answers

You do not need to create a new HBox every time you want to set an image inside a ListView. You can directly use the setCellFactory() of the ListView to achieve the same result.

This example is just an extension of the answer Image in JavaFX ListView and contains a Minimal, Complete, and Verifiable example which can be tried and tested. If you want to understand how this works, I suggest you to go through the linked question first.

Update - How to resize Images

To resize images to fit the size you want, make use of fitWidth() and fitHeight() methods of the ImageView. There are other methods like setSmooth() and setPreserveRatio() which can come in handy as well.

MCVE

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

public class ListViewWithImages 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 Image[] listOfImages = {IMAGE_RUBY, IMAGE_APPLE, IMAGE_VISTA, IMAGE_TWITTER};

    @Override
    public void start(Stage primaryStage) throws Exception {

        ListView<String> listView = new ListView<String>();
        ObservableList<String> items =FXCollections.observableArrayList (
                "RUBY", "APPLE", "VISTA", "TWITTER");
        listView.setItems(items);

        listView.setCellFactory(param -> new ListCell<String>() {
            private ImageView imageView = new ImageView();
            @Override
            public void updateItem(String name, boolean empty) {
                super.updateItem(name, empty);
                if (empty) {
                    setText(null);
                    setGraphic(null);
                } else {
                    if(name.equals("RUBY"))
                        imageView.setImage(listOfImages[0]);
                    else if(name.equals("APPLE"))
                        imageView.setImage(listOfImages[1]);
                    else if(name.equals("VISTA"))
                        imageView.setImage(listOfImages[2]);
                    else if(name.equals("TWITTER"))
                        imageView.setImage(listOfImages[3]);
                    setText(name);
                    setGraphic(imageView);
                }
            }
        });
        VBox box = new VBox(listView);
        box.setAlignment(Pos.CENTER);
        Scene scene = new Scene(box, 200, 200);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

OUTPUT

enter image description here

like image 171
ItachiUchiha Avatar answered Oct 03 '22 13:10

ItachiUchiha


In addition to my comment I will show here some code, that is working for me:

private void setListEntry(ListCell<Label> listCell, Label label) {

        Image img = loadLableIcon(label);

        GridPane row = new GridPane();
        row.setHgap(15);
        row.setVgap(15);

        ColumnConstraints col1 = new ColumnConstraints();
        col1.setPercentWidth(90);
        ColumnConstraints col2 = new ColumnConstraints();
        col2.setPercentWidth(10);

        ImageView icon = new ImageView(img);

        javafx.scene.control.Label name = new javafx.scene.control.Label(label.getName());
        name.setMinWidth(120d);

        javafx.scene.control.Label amount = new javafx.scene.control.Label("" + label.getSize());

        HBox iconAndName = new HBox(10);
        iconAndName.setAlignment(Pos.CENTER_LEFT);
        iconAndName.getChildren().addAll(icon, name);

        row.add(iconAndName, 0, 0);
        row.add(amount, 1, 0);

        row.getColumnConstraints().addAll(col1, col2);

        listCell.setGraphic(row);
    }

Please note: I'm not an expert in JavaFX, so I am not sure if it's best practise or not.

like image 32
Martin Pfeffer Avatar answered Oct 03 '22 12:10

Martin Pfeffer