JAVAFX: обновить просмотр списка с изображением + текст - PullRequest
0 голосов
/ 28 августа 2018

Я пытаюсь создать простую шахматную игру с 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");
            }
        }
    });

1 Ответ

0 голосов
/ 28 августа 2018

Вы делаете слишком много в вашем 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;
    }
}

РЕЗУЛЬТАТЫ

Вот скриншот того, что производит это приложение:

Screenshot

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...