【问题标题】:JavaFX show image near string in listview [closed]JavaFX在列表视图中显示字符串附近的图像[关闭]
【发布时间】:2016-04-04 18:03:50
【问题描述】:

我想在列表视图中的字符串附近显示一条消息我试图查找它但我无法理解它我从网站http://docs.oracle.com/javafx/2/ui_controls/list-view.htm 在示例 11-4 创建一个单元工厂我尝试转换它到 imageview 并且确实有效,但问题是我没有看到字符串,图像不在字符串附近并且图像太大应该有办法调整它的大小所以有人可以帮我在字符串附近显示图像列表显示?这是我尝试转换的代码:

第 1 部分

static class ColorRectCell extends ListCell<String> {
        Image fileimg = new Image(getClass().getResourceAsStream("file.png"));
        @Override
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            ImageView rect = new ImageView();
            if (item != null) {
                rect.setImage(fileimg);
                setGraphic(rect);
            }
        }
    }

第 2 部分

FileExplorerFormSlaveFileListView.setCellFactory(new Callback<ListView<String>, 
                ListCell<String>>() {

                    public ListCell<String> call(ListView<String> list) {
                        return new ColorRectCell();
                    }
                }
            );

我希望有人可以帮助我,这对我来说非常重要。谢谢。如果你不明白我在问什么,请告诉我,我会尝试格式化我不擅长解释问题的问题。

【问题讨论】:

  • 你能贴一张你得到的图片,并更清楚地解释它与你想要的有什么不同吗?如果您可以编辑问题中的文本以使其真正可读,这也会很有帮助。 (例如,您可以尝试使用标点符号并将其分成句子。)按照目前的措辞,阅读和理解您的要求非常困难。
  • 我希望它看起来像一个树视图,在列表视图中的字符串附近有一个图像

标签: java image listview javafx imageview


【解决方案1】:

CellsLabeled 节点,可以天生显示文本和图形,其中文本是任意图形节点的标签。因此,在您的单元格中,维护图形(ImageView)的呈现,并在 updateItem 实现中适当地设置图形和文本。

private ImageView imageView = new ImageView();

@Override
protected void updateItem(String item, boolean empty) {
    super.updateItem(item, empty);

    if (empty || item == null) {
        imageView.setImage(null);

        setGraphic(null);
        setText(null);
    } else {
        imageView.setImage(
                imageCollection.get(
                        item
                )
        );

        setText(constructLabel(SHORT_PREFIX, item, SUFFIX));
        setGraphic(imageView);
    }
}

示例应用程序

在这里,所有可能的图像都已预先加载并存储在缓存中,如果您有少量图像,这将可以正常工作。如果您有大量图像,您可能需要更复杂的 LRU 样式缓存用于在后台按需加载较新图像的图像,可能在后台加载过程运行时为图像使用占位符或进度指示器.

在示例应用程序中,图像在 Image 构造函数中调整大小,以使它们都具有相同的高度。此外,该实现适用于文件类型图标显示,因为对于任何给定文件类型只会创建单个图像,并且可以通过在不同单元格中使用的不同 ImageView 重复使用相同的图像。

import javafx.application.Application;
import javafx.collections.*;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.util.Map;
import java.util.stream.Collectors;

public class LabeledList extends Application {

    private static final double IMAGE_HEIGHT = 36;

    private static final String SHORT_PREFIX =
            "bird";

    private static final String LONG_PREFIX =
            "http://icons.iconarchive.com/icons/jozef89/origami-birds/72/" + SHORT_PREFIX;

    private static final String SUFFIX =
            "-icon.png";

    private static final ObservableList<String> birds = FXCollections.unmodifiableObservableList(
            FXCollections.observableArrayList(
                "-black",
                "-blue",
                "-red",
                "-red-2",
                "-yellow",
                "s-green",
                "s-green-2"
            )
    );

    private Map<String, Image> imageCollection;

    @Override
    public void start(Stage stage) throws Exception {
        imageCollection = birds.stream().collect(
                Collectors.toMap(
                        bird -> bird,
                        bird -> new Image(
                                        constructLabel(LONG_PREFIX, bird, SUFFIX),
                                        0,
                                        IMAGE_HEIGHT,
                                        true,
                                        true
                                )
                )
        );

        ListView<String> birdList = new ListView<>(birds);
        birdList.setCellFactory(param -> new BirdCell());
        birdList.setPrefWidth(230);
        birdList.setPrefHeight(200);

        VBox layout = new VBox(birdList);
        layout.setPadding(new Insets(10));

        stage.setScene(new Scene(layout));
        stage.show();
    }

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

    private class BirdCell extends ListCell<String> {
        private ImageView imageView = new ImageView();

        @Override
        protected void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);

            if (empty || item == null) {
                imageView.setImage(null);

                setGraphic(null);
                setText(null);
            } else {
                imageView.setImage(
                        imageCollection.get(
                                item
                        )
                );

                setText(constructLabel(SHORT_PREFIX, item, SUFFIX));
                setGraphic(imageView);
            }
        }
    }

    private String constructLabel(String prefix, String bird, String suffix) {
        return (prefix != null ? prefix : "")
                + bird
                + (suffix != null ? suffix : "");
    }

    // Iconset Homepage: http://jozef89.deviantart.com/art/Origami-Birds-400642253
    // License: CC Attribution-Noncommercial-No Derivate 3.0
    // Commercial usage: Not allowed    

}

【讨论】:

  • 如果我创建 HBox 的 ObserableList 并在该 HBox 中添加图像和文本会怎样?
  • @UnKnown 我不明白你的附加问题。也许创建一个新问题并在那里更彻底地解释您的问题。
  • 我正在创建 ListView 的 Image 和 Label 通过这个。 ObservableList&lt;HBox&gt; data = FXCollections.observableArrayList(); HBox hb = new HBox(); hb.getChildren().addAll(image,label); data.add(hb); ListView&lt;HBox&gt; list = new ListView&lt;&gt;(data); 没事吧?还是我应该覆盖 ListCell?
  • @UnKnown 不,这不好,您应该使用单元工厂而不是将节点用作 ListView 项。您应该创建一个新问题,而不是在 cmets 中提问,有人可以为您提供更详细的答案来解释为什么会这样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-18
  • 1970-01-01
相关资源
最近更新 更多