JavaFx: 如何在ListView中放置ImageView

6
我一直在寻找关于JavaFx ListView的线程,但很难找到一个简单而易于实现的解决方案,以将JavaFx ImageView放置在JavaFx ListView中。我正在尝试使用JavaFx框架创建聊天应用程序,在照片上应该看起来像这样。这不是重复的问题,因为其他线程对于像我这样的初学者来说太模糊了。我尝试过类似于这样的东西,但我完全是新手,提前感谢您的帮助!ListView with imageview inside
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);
    }
}`

这段程序相关的内容可以翻译为:listCell.setGraphic(row); 其中 "row" 是一个 HBox 或 GridPane。 - Martin Pfeffer
可能是JavaFX ListView中的图像的重复问题。 - ItachiUchiha
2个回答

22
您不需要每次想在ListView中设置图像时都创建一个新的HBox。您可以直接使用ListView的setCellFactory()方法来实现相同的结果。
这个例子只是答案Image in JavaFX ListView的扩展,并包含了一个Minimal, Complete, and Verifiable example,可以进行尝试和测试。如果您想了解这是如何工作的,建议您先浏览链接的问题。 更新 - 如何调整图像大小 要调整图像大小以适应所需大小,请使用ImageView的fitWidth()fitHeight()方法。还有其他方法,例如setSmooth()setPreserveRatio()也可能很方便。 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);
    }
}

输出

在这里输入图片描述


非常感谢,这正是我所需要的。我需要学习如何做,然后将其与我正在进行的当前项目一起实现。感谢在这里帮助我的人们,我希望你们继续帮助其他人! - Justine Mackay
我在想,当我将图像加载到我的计算机而不是网络上时,如果我将其更改为以下内容,Image image = new Image(Main.class.getResourceAsStream("bell.jpg")); 图像大小真的很大,我想知道如何将其调整为更小的尺寸。 - Justine Mackay
1
你可以使用ImageView来完成。在ImageView上使用fitWidth()fitHeight()方法。还有其他方法,如setSmooth()setPreserveRatio()可供使用。 - ItachiUchiha
@JustineMackay 你可以从任何地方加载图像。我使用了网络链接,因为它们可以在任何机器上复制和尝试,而如果我使用本地链接,您将不得不更改代码才能看到其效果 :) - ItachiUchiha
我已经尝试过了,我认为这可能与我的互联网连接有关,当我重新加载时它无法接受。对此很抱歉 >,< - Justine Mackay
显示剩余4条评论

1

除了我的评论,我还将展示一些代码,这对我很有效:

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);
    }

请注意:我不是JavaFX的专家,所以我不确定这是否是最佳实践。

谢谢你的帮助!我不是JavaFx专家,但我正在努力提高自己的编程水平。你能否更新上面的代码并提供完整的代码?我不知道如何使用新代码实现它。 - Justine Mackay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接