How to set image to a scene background in JavaFX? - javafx

The title says it all, I guess.
How to set a .jpg (or any other supported image format) image to a Scene background?
I somewhat achieved this by using a HBox, an Image and an ImageView, like this:
String url = ...
HBox box= new HBox();
Image x = new Image(url);
ImageView iv = new ImageView(x);
box.getChildren().add(iv);
box.setVisible(true);
Then I add that box to the Scene first, and everything else afterwards.
I'm not complaining about that piece of code - it works for my purposes - but is there a proper way to set a background?

An ImagePattern can be used as fill of the Scene:
ImagePattern pattern = new ImagePattern(myImage);
scene.setFill(pattern);

Just call setBackground on the root node of the scene. For example:
Pane root = ... ; // probably some pane subclass...
String url = ... ;
Image img = new Image(url);
BackgroundImage bgImg = new BackgroundImage(img,
BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT,
BackgroundPosition.DEFAULT,
new BackgroundSize(BackgroundSize.AUTO, BackgroundSize.AUTO, false, false, true, false));
// put stuff in root as normal....
Scene scene = new Scene(root);
See the Javadocs for the parameters for the BackgroundImage constructor, etc.

Related

JavaFX 3D Background image

I'm trying to add a background image to my JavaFX 3D program, but it just translates the ImageView instead of setting it as the background. What am I missing?
I create the ImageView, and then add it to a separate Group object in the start method. The choiceLayout is another Group object.
Image image = new Image(Program.class.getResourceAsStream("picture.jpg"));
ImageView view = new ImageView(image);
view.setPreserveRatio(true);
view.getTransforms().add(new Translate(-image.getWidth() / 2, -image.getHeight() / 2, 800));
Group bg = new Group();
bg.getChildren().add(choiceLayout);
bg.getChildren().add(view);
Scene choiceScene = new Scene(bg, 1024, 768, true);

How add padding or margin for ImageView in JavaFX by using code (not FXML)

I want add white border around ImageView.
One solution is to wrap the images in a Button.
And I try use StackPane:
StackPane stackPaneforImageActivity = new StackPane();
Image activityImage = new Image(file.toURI().toString());
ImageView imv = new ImageView(activityImage);
newActivityHBox.getChildren().add(stackPaneforImageActivity);
stackPaneforImageActivity.getChildren().add(imv);
stackPaneforImageActivity.setPadding(new Insets(10));
stackPaneforImageActivity.setStyle("-fx-border-color:white;-fx-background-color: black;");
imv.setFitHeight(30);
imv.setFitWidth(30);
But
Are there other solutions?
But the image is outside the StackPane. Why?

Get Pane size without adding it to a scene (in JavaFX)?

If I create a Pane (with nodes inside it), how can I compute the width/height without rendering it on-screen?
I am trying to create a document (in memory) and send it to a printer. The problem is that I need to compute how many pages and to do that I need to get the dimensions of the document.
A quick example I'm experimenting with:
Label testLabel1 = new Label("TEST1");
Label testLabel2 = new Label("TEST no. 2");
GridPane testGl = new GridPane();
testGl.add( testLabel1, 1, 1 );
testGl.add( testLabel2, 2, 2 );
VBox testVBox = new VBox( testGl );
Pane testPane = new Pane( testVBox );
//I read that this might be required
testPane.applyCss();
testPane.layout();
//Also that a delay is needed for the fx tread to update testPane
// (but shouldn't this all be in the same thread since it is in the same function?
// It doesn't seem to help).
Platform.runLater( ()->{
System.out.println( ">>> "+ testPane.getBoundsInLocal().getWidth() );
});
All I ever output is >>> 0.0. Note that in the program I'm developing, I have multiple Panes inside a "container" Pane. Hence, the variable testPane.
Thank you.
You need to add the Pane to a Scene for the layouting to work. There is no need to display the Scene however and there is no need to keep the Pane in this scene:
Label testLabel1 = new Label("TEST1");
Label testLabel2 = new Label("TEST no. 2");
GridPane testGl = new GridPane();
testGl.add(testLabel1, 1, 1);
testGl.add(testLabel2, 2, 2);
VBox testVBox = new VBox(testGl);
Pane testPane = new Pane(testVBox);
// add testPane to some scene before layouting
Scene testScene = new Scene(testPane);
testPane.applyCss();
testPane.layout();
System.out.println(">>> " + testPane.getBoundsInLocal().getWidth());
// Pane could be removed from scene
Group replacement = new Group();
testScene.setRoot(replacement);
Note that if you want to remove the root from a Scene you have to replace it with a non-null node.

Set StackPane background image

I want to set background image autoresized with StackPane.
I tried this:
StackPane stackPane = new StackPane();
Image im = new Image(Dashboardpanel.class.getResource("/images/11.jpg").toExternalForm());
stackPane.setBackground(new Background(new BackgroundImage(im, BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.CENTER, BackgroundSize.DEFAULT)));
But the image is not auto-resized when I resize the StackPane. The image is repeated to fill the gap. How I can resize the image just as the Stackpane no matter how I extend the StackPane?
Don't use the default BackgroundSize, create a new BackgroundSize and use the contain and cover arguments of the BackgroundSize constructor.
For example (and I just wrote this by reading the javadoc, I didn't test it):
new BackgroundSize(BackgroundSize.AUTO, BackgroundSize.AUTO, false, false, false, true);
I advise using a CSS stylesheet for this kind of styling rather than coding the style in Java.

How can I copy an image from a stackPane and then add it to another stackpane?

I need to copy an image from a stackPane and then need to add that particular image to another stackpane with help of ClipBoard.
You can do it with SnapshotParameters and with a ImageView:
...
SnapshotParameters snapParams = new SnapshotParameters();
snapParams.setFill(Color.RED); // see documentation
// with your describtion YOURNODE is your stackpane...
imageview.setImage(YOURNODE.snapshot(snapParams, null));
Now you can add imageview to the other stackpane with:
otherStackpane.getChildren().add(imageview);

Resources