Search code examples
javabuttonjavafxarraylistimageview

Setting ImageViews as button background failing


Context: I'm creating a puzzle game as part of a project, I've finished the logic and just want to set backgrounds to my buttons.

The code using for creating BackgroundImages I found on here and while it sets the background every button receives the first element in the ImageView List.

Here is the result showing each button receiving element 0 in the ImageView List and below I displayed all 4 of the elements just to check I populated the ImageView List correctly.

Image showing result

List<Button> pieces = new ArrayList<>();
List<ImageView> images = new ArrayList<>();
VBox layout = new VBox();
HBox original = new HBox();
Image image = new Image("jalter.png");  
HBox imagesList = new HBox();   



for(int i = 0; i < 4; i++) { 
  pieces.add(new Button(String.valueOf(i+1)));
  pieces.get(i).setPrefSize(150,150);  

  images.add(new ImageView(image));  
  images.get(i).setViewport(new Rectangle2D(
  getX(toGridXY(i)) * 150,
  getY(toGridXY(i)) * 150,
  150,
  150));    

  BackgroundImage backgroundImage = new                     
  BackgroundImage
  (images.get(i).getImage(), 
  BackgroundRepeat.NO_REPEAT, 
  BackgroundRepeat.NO_REPEAT, 
  BackgroundPosition.DEFAULT, 
  BackgroundSize.DEFAULT);  
  Background background = new 
  Background(backgroundImage);      
  pieces.get(i).setBackground(background);      
}

Solution

  • You're setting the background of each one to a background with exactly the same image. ImageView.getImage() is just going to return the original image you passed; it's not going to crop that image to the viewport of the image view.

    Instead, you can create a new Image using the pixelReader of the original image, and providing a cropping region in the constructor of WritableImage:

    for(int i = 0; i < 4; i++) { 
      Button button = new Button(String.valueOf(i+1));
      pieces.add(button);
      button.setPrefSize(150,150);  
    
      Image croppedImage = new WritableImage(image.getPixelReader(),
        getX(toGridXY(i)) * 150,
        getY(toGridXY(i)) * 150,
        150,
        150);
    
      BackgroundImage backgroundImage = new BackgroundImage(
        croppedImage,
        BackgroundRepeat.NO_REPEAT, 
        BackgroundRepeat.NO_REPEAT, 
        BackgroundPosition.DEFAULT, 
        BackgroundSize.DEFAULT);  
      Background background = new Background(backgroundImage);      
      button.setBackground(background);      
    }