How to set image as background using JavaFX? - java

I'm trying to put an image as a background in a JavaFX scene, but my code isn't working.
Im trying to make a Battleship-game program in java eclipse but i'm stuck at a graphics problem.
public class WindowGUI extends Application{
Game game;
Image image;
public WindowGUI(Game game) {
this.game = game;
}
public static void main(String[] args) {
Game game = new Game();
new WindowGUI(game);
}
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("Battleship");
image = new Image ("C:\\Users\\amali\\git\\inf101.v19.sem2\\inf101.v19.sem2\\src\\window\\battleshipbackground.jpg");
ImageView background = new ImageView(image);
Button startButton = new Button("START");
BorderPane newStack = new BorderPane();
newStack.getChildren().add(startButton);
newStack.getChildren().add(background);
stage.setScene(new Scene(newStack, 1300, 860));
stage.show();
startButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
// START THE GAME
}
});
}
}
When I first tried to run it, it worked and a new window opened with a button in the center, but the bakcground was blank. When i try setting an image as background in the window, behing the 'start'-button, nothing happens..

A better way to do it is to use the Background class rather than trying to add an ImageView as a child of your BorderPane.
Image image = new Image("C:\\Users\\amali\\git\\inf101.v19.sem2\\inf101.v19.sem2\\src\\window\\battleshipbackground.jpg");
BackgroundSize size = new BackgroundSize(BackgroundSize.AUTO,
BackgroundSize.AUTO,
false,
false,
true,
false);
Background background = new Background(new BackgroundImage(image,
BackgroundRepeat.NO_REPEAT,
BackgroundRepeat.NO_REPEAT,
BackgroundPosition.CENTER,
size));
newStack.setBackground(background);

Use BackgroundImage class.
or try this
JavaFX How to set scene background image

Related

JavaFx: ImageView disappears after moving through the scene

I have a code written using javafx and java 11. As I showed in the below code snippet, when I move my ImageView to right of the scene, The ImageView disappears.
At first:
and then after moving it using arrow keys with the help of scene event listener:
then:
and finally:
I don't use fxml. Here is my demo which has the problem too.
public class HelloApplication extends Application {
public String fetchResource(String path) {
return Objects.requireNonNull(getClass().getResource(path)).toString();
}
#Override
public void start(Stage stage) throws IOException {
Rectangle r = new Rectangle(100, 100);
ImageView spaceShip = new ImageView(fetchResource("spaceShip.png"));
spaceShip.setFitHeight(100);
spaceShip.setFitWidth(100);
spaceShip.setX(0);
spaceShip.setY(0);
EventHandler<KeyEvent> keyListener = event -> {
if (event.getCode() == KeyCode.RIGHT) {
spaceShip.setX(spaceShip.getX() + 20);
}
};
Group game = new Group(spaceShip);
Scene scene = new Scene(game, 1840, 1080);
scene.setOnKeyPressed(keyListener);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
I should mention that I create a rectangle and check the scenario with that, And there was not any problem. I think there is some problem with ImageView.
I couldn't reproduce the issue with your code, but I could with SceneBuilder. You may get the desired result if you wrap the Group in a Pane (at least it works in SceneBuilder).
Group game = new Group(spaceShip);
Pane pane = new Pane(game);
Scene scene = new Scene(pane, 1840, 1080);
stage.setScene(scene);
stage.show();

Trying to create a scrolling background effect with imageViews in javafx

Im trying to create a scrolling background effect with two imageViews where one picture is on top of another picture and out of the window; then i try to scroll both down the window to create a scrolling effect by changing their y coordinates. I made a loop to do so and put a thread.sleep so it wouldnt do it too quickly. Then i reset the picutres positions and do the loop again. However, when i try to run the program, the window will never open. Taking out the loop obviously properly shows the window with the picutre.
public class TestBackground extends Application{
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("DRIFT STAGE");
Pane game = new Pane();
Scene gameScene = new Scene(game, 956, 740);
ImageView background = new ImageView(getClass().getResource("bg.png").toExternalForm());
game.getChildren().add(background);
ImageView background2 = new ImageView(getClass().getResource("bg.png").toExternalForm());
game.getChildren().add(background2);
background2.setY(-740);
//loop to scroll background vertically
for (int j = 0; j < 20; j++) {
for (double i = 1.0; i < 741.0; i++) {
background.setY(background.getY() + i);
background2.setY(background2.getY() + i);
try {
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
background.setY(0.0);
background2.setY(-740.0);
}
stage.setScene(gameScene);
stage.show();
}
public static void main(String[] args) { launch(args); }
}
Your loop is not the right thing to do. Use a Transition Animation on each ImageView. You want a TranslateTransition.
Something like this:
// Animation to scroll background vertically
TranslateTransition trans1 = new TranslateTransition(Duration.minutes(1), background);
trans1.setFromY(0);
trans1.setToY(740);
trans1.setCycleCount(20);
TranslateTransition trans2 = new TranslateTransition(Duration.minutes(1), background2);
trans2.setFromY(-740);
trans2.setToY(0);
trans2.setCycleCount(20);
ParallelTransition parTrans = new ParallelTransition(trans1, trans2);
parTrans.play();
If your intention is to have these images as a parallax background that scrolls "forever", set the transitions to cycle indefinitely
trans1.setCycleCount(Animation.INDEFINITE);
and use slightly different durations for each.
If you are using the same image, don't load it twice:
Image bgImg = new Image(getClass().getResource("bg.png").toExternalForm());
ImageView background = new ImageView(bgImg);
game.getChildren().add(background);
ImageView background2 = new ImageView(bgImg);
game.getChildren().add(background2);
Here's the whole start method with an added speed slider, just for fun:
#Override
public void start(Stage stage) {
stage.setTitle("DRIFT STAGE");
Pane game = new Pane();
Scene gameScene = new Scene(game, 956, 740);
Image bgImg = new Image(getClass().getResource("bg.png").toExternalForm());
ImageView background = new ImageView(bgImg);
ImageView background2 = new ImageView(bgImg);
Slider speedSlider = new Slider(0, 5, 1);
game.getChildren().addAll(background, background2, speedSlider);
// Animation to scroll background vertically
TranslateTransition trans1 = new TranslateTransition(Duration.seconds(10), background);
trans1.setFromY(0);
trans1.setToY(740);
trans1.setInterpolator(Interpolator.LINEAR);
trans1.setCycleCount(Animation.INDEFINITE);
TranslateTransition trans2 = new TranslateTransition(Duration.seconds(10), background2);
trans2.setFromY(-740);
trans2.setToY(0);
trans2.setCycleCount(Animation.INDEFINITE);
trans2.setInterpolator(Interpolator.LINEAR);
ParallelTransition parTrans = new ParallelTransition(trans1, trans2);
parTrans.rateProperty().bind(speedSlider.valueProperty());
parTrans.play();
stage.setScene(gameScene);
stage.show();
}

JavaFX bulk edit images

I'm trying to edit five images I have in a folder at once (using javafx motion blur), rather than select them one after the other. This is my code, I'm not exactly sure what I'm doing wrong but when I run it, only the last image in the folder gets edited. The others remain as they are.
public class IterateThrough extends Application {
private Desktop desktop = Desktop.getDesktop();
#Override
public void start(Stage primaryStage) throws IOException {
File dir = new File("filepath");
File [] directoryListing = dir.listFiles();
if (directoryListing != null) {
for (File file : directoryListing) {
if(file.getName().toLowerCase().endsWith(".jpeg")){
//desktop.open(file);
Image image = new Image(new FileInputStream(file));
//Setting the image view
ImageView imageView = new ImageView(image);
//setting the fit height and width of the image view
imageView.setFitHeight(600);
imageView.setFitWidth(500);
//Setting the preserve ratio of the image view
imageView.setPreserveRatio(true);
// instantiate Motion Blur class
MotionBlur motionBlur = new MotionBlur();
// set blur radius and blur angle
motionBlur.setRadius(15.0);
motionBlur.setAngle(110.0);
//set imageView effect
imageView.setEffect(motionBlur);
//Creating a Group object
Group root = new Group(imageView);
//Creating a scene object
Scene scene = new Scene(root, 600, 500);
//Setting title to the Stage
primaryStage.setTitle("Loading an image");
//Adding scene to the stage
primaryStage.setScene(scene);
//Displaying the contents of the stage
primaryStage.show();
}
}
}
}
public static void main(String[] args) {
launch(args);
}
}
first, you shouldn't just let the primaryStage show() in the for-each loop, because when the primaryStage first show(), the fx thread pause on that instruction, the remaining pictures will not be read and when you close the window, the loop won't continue to go on for remaining, it represents the end of the application.
so it's better to let the primaryStage show() outside the each-loop after all image has been read.
second, you shouldn't use the "Group" container to contains all images, better use VBox/HBox/FlowPane, make sure above image won't covers below's.
here's modified code for reference.
public class IterateThrough2 extends Application{
private Desktop desktop = Desktop.getDesktop();
#Override
public void start(Stage primaryStage) throws IOException{
File dir = new File("filepath");
File[] directoryListing = dir.listFiles();
FlowPane root = new FlowPane();
if(directoryListing != null){
for(File file : directoryListing){
if(file.getName().toLowerCase().endsWith(".jpeg")){
Image image = new Image(new FileInputStream(file));
ImageView imageView = new ImageView(image);
imageView.setFitHeight(600);
imageView.setFitWidth(500);
imageView.setPreserveRatio(true);
MotionBlur motionBlur = new MotionBlur();
motionBlur.setRadius(15.0);
motionBlur.setAngle(110.0);
imageView.setEffect(motionBlur);
root.getChildren().add(imageView);
}
}
}
Scene scene = new Scene(root, 600, 500);
primaryStage.setTitle("Loading an image");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args){
launch(args);
}
}

JavaFx Video Dimension OUT of screen

I recently found javafx 2.1 very useful for my project of making a video player but after a
success I faced a problem with the video size Dimensions. In other words, when I run the
program and video is playing normally I can't see the whole video because it's dimensions
are bigger than my screen resolution .What Can I do in the following code to resize the actual size of video in windows7 64bit:
public class HelloFx extends Application {
public static void main(String[] args){
launch(args);
}
#Override
public void start(final Stage stage) throws Exception {
stage.setTitle("Movie Player");
final BorderPane root = new BorderPane();
final Media media = new Media("file:///Users//user//Videos//Sintel.mp4");
final MediaPlayer player = new MediaPlayer(media);
final MediaView view = new MediaView(player);
// System.out.println("media.width: "+media.getWidth());
root.getChildren().add(view);
final Scene scene = new Scene(root, 400, 400, Color.BLACK);
stage.setScene(scene);
stage.show();
player.play();
player.setOnReady(new Runnable() {
#Override
public void run() {
int w = player.getMedia().getWidth();
int h = player.getMedia().getHeight();
stage.setMinWidth(w);
stage.setMinHeight(h);
}
});
//player.play();
}
}
The JavaFX 2 MediaView class has 2 functions which can help. They are .setFitHeight() and .setFitWidth() .
So, you could, instead of letting the media dictate the size of screen, let your stage set the size of the screen...
public void run() {
int w = stage.getWidth(); // player.getMedia().getWidth();
int h = stage.getHeight(); // player.getMedia().getHeight();
// stage.setMinWidth(w);
// stage.setMinHeight(h);
// make the video conform to the size of the stage now...
player.setFitWidth(w);
player.setFitHeight(h);
}
Then the video should fit inside of the stage. That above code is pretty crude, and you may want to "Scale" the video better, ie: find the ratio of the media width VS the stage width & media height VS stage height ... But that code above should get you started.

Drag and Drop event in Javafx 2.0

i am working with javafx 2.0 and netbean 7.1, I am facing an problem when doing a drag and drop on a image over a ImageView, .i kept image as a source(one image) and 2 target point(2 box as target point).when trying to drag an image first time, its working fine and after sources image is entered in to target box.and again trying to drag the image, following error is trown "java.lang.IllegalArgumentException: Wrong byte buffer size 18x15 [1080] != 0"
Once the image is moved to the destination object, i need to set the listener to change it as source, i feel that its throwing error in this place..
code am using
public class DragandDropEx extends Application {
/**
* #param args the command line arguments
*/
GridPane Board;
ImageView deactivateImageView = new ImageView();
ImageView newImageView = new ImageView();
final Rectangle target = new Rectangle(0, 0, 50, 50);
final Rectangle target2 = new Rectangle(0, 0, 50, 50);
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
target.setFill(Color.CHOCOLATE);
target2.setFill(Color.BLUE);
Image image = new Image(getClass().getResourceAsStream("triangle.png"));
getDeactivateImageView().setImage(image);
Board = new GridPane();
primaryStage.setTitle("Drag and Drop");
createSource(getDeactivateImageView());
target.setOnDragOver(new EventHandler<DragEvent>() {
#Override
public void handle(DragEvent events) {
events.acceptTransferModes(TransferMode.MOVE);
events.consume();
createTargetDrop(target,0,8);
}
});
target2.setOnDragOver(new EventHandler<DragEvent>() {
#Override
public void handle(DragEvent events) {
events.acceptTransferModes(TransferMode.MOVE);
events.consume();
createTargetDrop(target2,0,9);
}
});
Board.add(getDeactivateImageView(), 0, 1);
Board.add(target, 0, 8);
Board.add(target2, 0, 9);
StackPane root = new StackPane();
root.getChildren().add(Board);
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
private void createSource(final ImageView imageView) {
imageView.setOnDragDetected(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent events) {
Dragboard storeImage =imageView.startDragAndDrop(TransferMode.MOVE);
ClipboardContent content = new ClipboardContent();
content.putImage(imageView.getImage());
storeImage.setContent(content); **// here i am getting error**
events.consume();
}
});
}
private void createTargetDrop(final Rectangle target,final int xCordination,final int yCordination) {
target.setOnDragDropped(new EventHandler<DragEvent>() {
#Override
public void handle(DragEvent event) {
Dragboard db = event.getDragboard();
Image dragedImage = db.getImage();
getNewImageView().setImage(dragedImage);
getDeactivateImageView().setVisible(false);
setDeactivateImageView(getNewImageView());
Board.add(getDeactivateImageView(),xCordination,yCordination );
event.consume();
createSource(getDeactivateImageView()); // setting listener to new image
}
});
}
}
I guess its about references. I mean you are using same reference to different place. Maybe you should use clone of object. I did not look to code deeply but it looks like you are trying to add same object to different place.
Which JavaFX version do you use?
You may encounted issue, which were fixed in 2.1: http://javafx-jira.kenai.com/browse/RT-14348
If you were working with 2.0.x version you can try developers version of FX2.1: http://www.oracle.com/technetwork/java/javafx/downloads/devpreview-1429449.html
I would recommend JavaFX because it includes scenebuilder (a GUI) to create your GUI. You can drag and drop GUI elements and size them on a canvas. Then, this creates an FXML file that connects to a Java control file.
Check out scenebuilder here: http://www.oracle.com/technetwork/java/javase/downloads/javafxscenebuilder-info-2157684.html
There is a bit of a learning curve on connecting the FXML to Java code, but it is worth it if you want to graphically design your GUI.

Categories

Resources