1

I have a simple JavaFX program that uses an image for the background on the main Pane. Currently I'm loading the image directly in my .css file:

.pane {
  -fx-background-image: url('map.png');
  -fx-background-size: 1000 800;
}

This works fine, but the quality of the image -fx-background-size generates is rather poor.

Instead I'd like to use java.awt.Image#getScaledInstance with Image.SCALE_SMOOTH (or the JavaFX equivalent), which generates an image of much higher quality.

Can I use getScaledInstance directly and somehow pass a Java awt image to my css file? Or inline it with setStyle?

I'm aware that since this image is only being resized once I could just resize the original image and import that, but I'd like to know if what I want to do is possible.

River
  • 8,585
  • 14
  • 54
  • 67

3 Answers3

2

All I needed to do was remove my CSS and simply do:

Pane root = new Pane();
ImageView background = new ImageView(new Image("map.png", 1000, 800, false, true));
root.getChildren().add(background);

This is because the JavaFX equivalent of java.awt.Image#getScaledInstance is just in the constructor for javafx.scene.image.Image.

While you can't use a java.awt.Image in place of a javafx.scene.image.Image, using this javafx.scene.image.Image constructor:

Image(String url, double width, double height, boolean preserveRatio, boolean smooth)

and passing true as the value for the smooth field will give a similar quality image as getScaledInstance using Image.SCALE_SMOOTH. Then (as @kylejmcintyre mentioned) you can pass the javafx.scene.image.Image to an ImageView object and add it to your root Pane.

River
  • 8,585
  • 14
  • 54
  • 67
1

You could use a StackPane as the root node on your Scene and then put an instance of ImageView at the bottom of the stack and put whatever you were previously using as your root on top of it with a transparent background color (defined in CSS or programmatically).

Obviously this circumvents CSS, but perhaps it will suffice and allow you to achieve the scaling you want.

River
  • 8,585
  • 14
  • 54
  • 67
kylejmcintyre
  • 1,898
  • 2
  • 17
  • 19
1

To ensure consistency when resizing the window/stage. This is what I did

Create a root node

BorderPane root = new BorderPane();

Get the primary-screen

Screen screen = Screen.getPrimary();

Set the visible bounds of your screen

Rectangle2D bounds = screen.getVisualBounds();
double width = bounds.getWidth();
double height = bounds.getHeight();

Set a background image with the same size as the size of the screen. When you resize the screen, the background image will be resized too since you've set the width and the height of the image as that of the current screen size.

BackgroundImage bImage = new BackgroundImage(new 
Image("url here",width,height,false,true),
    BackgroundRepeat.REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT,
      BackgroundSize.DEFAULT);

root.setBackground(new Background(bImage));

Test the program by displaying it

stage.setTitle("Title here);
stage.setScene(new Scene(root));
stage.show();

I hope it helped you. Keep Java alive

Patrick
  • 11
  • 1