简体   繁体   English

JAVAFX:使用图像 + 文本更新列表视图

[英]JAVAFX: update a listview with image + text

I am trying to create a simple chess game with javafx.我正在尝试使用 javafx 创建一个简单的国际象棋游戏。 I have 2 listview filled with images and a counter near each image, which represent the counter of each piece that is removed from the chessboard.我有 2 个充满图像的列表视图和每个图像附近的计数器,它们代表从棋盘上移除的每个棋子的计数器。 Is there a way to update the counter of an image?有没有办法更新图像的计数器? This is the code I ued to create the starting list, with al the pieace with 0x counter.这是我用来创建起始列表的代码,所有的部分都带有 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");
            }
        }
    });

You are doing too much within your updateItem() method for the ListView .您在ListView updateItem()方法中做了太多事情。 You should instead use a proper data model object to populate the ListView .您应该改为使用适当的数据模型对象来填充ListView

You should be updating the underlying object instead of doing any kind of calculations and such within the CellFactory .您应该更新底层对象,而不是在CellFactory中进行任何类型的计算等。

Here is a quick sample application to demonstrate.这是一个快速的示例应用程序来演示。 You'll see I have created a separate class for a ChessPiece .你会看到我为ChessPiece创建了一个单独的类。 That object contains all the information you need to be displayed in the ListView .该对象包含您需要在ListView显示的所有信息。

Then, within our CellFactory , you just update the displayed item using the values from the ChessPiece .然后,在我们的CellFactory ,您只需使用ChessPiece的值更新显示的项目。

THE CODE编码

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

THE RESULTS结果

Here is a screenshot of what this application produces:这是此应用程序生成的屏幕截图:

截屏

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM