Reputation: 61
I am trying to create a simple chess game with 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. 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.
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");
}
}
});
Upvotes: 0
Views: 1903
Reputation: 10253
You are doing too much within your updateItem()
method for the ListView
. You should instead use a proper data model object to populate the ListView
.
You should be updating the underlying object instead of doing any kind of calculations and such within the CellFactory
.
Here is a quick sample application to demonstrate. You'll see I have created a separate class for a ChessPiece
. That object contains all the information you need to be displayed in the ListView
.
Then, within our CellFactory
, you just update the displayed item using the values from the 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:
Upvotes: 4