【问题标题】:JAVAFX: update a listview with image + textJAVAFX:使用图像+文本更新列表视图
【发布时间】:2018-08-28 14:00:52
【问题描述】:

我正在尝试使用 javafx 创建一个简单的国际象棋游戏。 我有 2 个充满图像的列表视图和每个图像附近的计数器,它们代表从棋盘中移除的每块棋子的计数器。 有没有办法更新图像的计数器? 这是我用来创建起始列表的代码,其中包括 0x 计数器。

        lista2.setCellFactory(listview -> new ListCell<String>() {
        private ImageView imageView = new ImageView();
        @Override
        public void updateItem(final String item, final boolean empty) {
            Image img = null;
            super.updateItem(item, empty);
            if (empty) {
                setGraphic(null);
            } else {
                try(InputStream is = Files.newInputStream(Paths.get(GameView.RESFOLDER + item + GameView.FORMAT))){
                    img = new Image(is);                
                } catch(IOException e) {
                    System.out.println("Couldn't load image" + Paths.get(GameView.RESFOLDER + item + GameView.FORMAT));
                }        
                // true makes this load in background
                // see other constructors if you want to control the size, etc 
                imageView.setImage(img);
                setGraphic(imageView);
                setText("x0");
            }
        }
    });

【问题讨论】:

  • 例如,从棋盘中删除了一个皇后,我希望列表视图显示皇后图像并靠近那个“x1”而不是“x0”
  • 不使用ListView(String),而是创建一个数据模型对象,其中包含图像、片段名称和当前计数。然后只需更新该数据模型,而不是尝试在 updateItem() 中执行此操作。
  • 阅读我发布的链接并点击。

标签: java listview javafx


【解决方案1】:

您在 updateItem() 方法中为 ListView 做的太多了。您应该改为使用适当的数据模型对象来填充 ListView

您应该更新底层对象,而不是在CellFactory 中进行任何类型的计算等。

这是一个快速示例应用程序来演示。你会看到我为ChessPiece 创建了一个单独的类。该对象包含您需要在ListView 中显示的所有信息。

然后,在我们的CellFactory 中,您只需使用ChessPiece 中的值更新显示的项目。

代码

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

public class Main extends Application {

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

    @Override
    public void start(Stage primaryStage) {

        // Build a simple UI
        VBox root = new VBox(5);
        root.setPadding(new Insets(10));
        root.setAlignment(Pos.CENTER);

        // Create a list of Chess pieces
        ObservableList<ChessPiece> chessPieces = FXCollections.observableArrayList();

        // Add a sample Chess piece, a queen in this case
        chessPieces.add(new ChessPiece(
                "Queen",
                new ImageView("sample/listViewImages/queen.png"),
                0
        ));

        // Create the ListView
        ListView<ChessPiece> lvChessPieces = new ListView<>();

        // Setup the CellFactory
        lvChessPieces.setCellFactory(listView -> new ListCell<ChessPiece>() {
            @Override
            protected void updateItem(ChessPiece piece, boolean empty) {
                super.updateItem(piece, empty);

                if (empty) {
                    setGraphic(null);
                } else {

                    // Create a HBox to hold our displayed value
                    HBox hBox = new HBox(5);
                    hBox.setAlignment(Pos.CENTER);

                    // Add the values from our piece to the HBox
                    hBox.getChildren().addAll(
                            piece.getImage(),
                            new Label(piece.getName()),
                            new Label("x " + piece.getCount())
                    );

                    // Set the HBox as the display
                    setGraphic(hBox);
                }
            }
        });

        // Bind our list of pieces to the ListView
        lvChessPieces.setItems(chessPieces);

        // Create a button to add change the Queen count
        Button button = new Button("Add a Queen");
        button.setOnAction(e -> {
            // Get the queen from the list of Chess Pieces. For this sample we only have one piece in our List,
            // but in a real application, you'll need to build a method for retrieving the correct piece.
            ChessPiece queen = chessPieces.get(0);
            queen.setCount(queen.getCount() + 1);

            // Refresh the ListView to show the updated counts
            lvChessPieces.refresh();
        });

        root.getChildren().addAll(lvChessPieces, button);
        primaryStage.setScene(new Scene(root));

        primaryStage.show();
    }
}

/**
 * Defines a Chess piece, including it's name, image, and current count
 */
class ChessPiece {

    private final String name;
    private final ImageView image;
    private int count;

    public ChessPiece(String name, ImageView image, int count) {
        this.name = name;
        this.image = image;
        this.count = count;

        // Resize the image, if necessary
        this.image.setFitHeight(25);
        this.image.setFitWidth(20);

    }

    public String getName() {
        return name;
    }

    public ImageView getImage() {
        return image;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }
}

结果

这是此应用程序生成的屏幕截图:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多