Issue
I'm trying to use a gridpane with a background image (an image with defined edges, not a continuous texture) . The image needs to stretch with the gridpane when resizing the app. However, it doesn't seem to work properly.
Depending on wether "contain" or "cover" are set true/false in the BackgroundSize arguments the following happens:
Either: the image scales with its own aspect ratio, meaning it doesn't keep the ratio of the gridpane (tested this by putting a boarder around the gridpane).
Or: the image covers the gripane at all times, but either the right side or the bottom of the image looks cut-off at either the right side or the bottom edge of the gridpane, depending on how the window is resized.
I was told there is an option to "stretch" the background to a pane. But I can't seem to find this option anywhere.
With CSS -fx-background-size: stretch;
is does the stretching perfectly, but unfortunately, CSS doesn't like .pngs with alpha sections.
@FXML
private GridPane gridView;
@FXML
private void initialize() {
BackgroundSize backgroundSize = new BackgroundSize(0.6, 0.8, true, true, true, true);
BackgroundImage image = new BackgroundImage(new Image("example_image.png"),
BackgroundRepeat.NO_REPEAT,
BackgroundRepeat.NO_REPEAT,
BackgroundPosition.CENTER,
backgroundSize
);
gridView.setBackground(new Background(image));
Solution
If you want the image to stretch to fill the pane completely in both directions, scaling independently (i.e. without preserving aspect ratio) in each, use
BackgroundSize backgroundSize = new BackgroundSize(1, 1, true, true, false, false);
Setting the second and third parameters to true ensures that the first two are interpreted as "percentages" (or more accurately, proportions), so this will force the background image to be 100% of the width and height of the pane. The last two are contain
and cover
, either of which preserves the images aspect ratio. See the documentation.
Here is a complete example:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class BackgroundImageStretch extends Application {
public static void main(String[] args) {launch(args);}
@Override
public void start(Stage stage) {
BackgroundSize backgroundSize = new BackgroundSize(1, 1, true, true, false, false);
BackgroundImage image = new BackgroundImage(createImage(),
BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT,
BackgroundPosition.CENTER,backgroundSize);
Pane root = new Pane();
root.setBackground(new Background(image));
Scene scene = new Scene(root, 400, 400);
stage.setScene(scene);
stage.show();
}
private Image createImage() {
WritableImage img = new WritableImage(400, 400);
PixelWriter pw = img.getPixelWriter();
for (int x = 0 ; x < 400; x++) {
for (int y = 0 ; y < 400 ; y++) {
Color color = x < 5 || x > 394 || y < 5 || y > 394 ? Color.YELLOW : Color.LIGHTBLUE ;
pw.setColor(x, y, color);
}
}
return img ;
}
}
Answered By - James_D
Answer Checked By - Willingham (JavaFixing Volunteer)