How to get buttons to overlap the image in JavaFX? - java

package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import java.awt.*;
public class Main extends Application {
Stage window;
Scene scene1, scene2;
Button button1, button2;
ImageView iv = new ImageView();
#Override
public void start(Stage primaryStage) throws Exception{
window = primaryStage;
Label label1 = new Label("First stage");
Button button1 = new Button("PLAY");
//Layout 1
VBox layout1 = new VBox(20);
scene1 = new Scene(layout1, 1280, 720);
layout1.getChildren().add(changeBackground("file:menuBackground.png"));
layout1.getChildren().addAll(label1, button1);
//defines dimensions of vbox so button and label can be centered
layout1.prefWidthProperty().bind(window.widthProperty());
layout1.prefHeightProperty().bind(window.heightProperty());
layout1.setAlignment(Pos.CENTER);
button1.setOnAction(event -> window.setScene(scene2));
//Button 2
Button button2 = new Button("This scene sucks, go back to scene 1");
button2.setOnAction(event -> window.setScene(scene1));
//Layout 2
StackPane layout2 = new StackPane();
layout2.getChildren().add(button2);
scene2 = new Scene(layout2, 1280, 720);
layout2.getChildren().add(changeBackground("file:gameBackground.png"));
window.setScene(scene1);
window.setTitle("Scramblo");
window.show();
}
public static void main(String[] args) {
launch(args);
}
public Node changeBackground(String imageFile){
ImageView iv = new ImageView();
Image image = new Image(imageFile);
iv.setImage(image);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double width = screenSize.getWidth();
double height = screenSize.getWidth();
iv.setFitHeight(height);
iv.setFitHeight(width);
iv.setPreserveRatio(true);
return iv;
}
}
So what I want is for the buttons to overlap the background images. I want to see the buttons and be able to interact with them with just having the background chillin' there. Right now when I add the background it completely removes the buttons/labels and anything else I put on there. I'm confused on how to go about this! Thanks!

Make layout1 a StackPane and not a VBox. Use a VBox as the container for label1 and button1 and add the VBox to layout1.
A StackPane places nodes added to it one on top of the other. The first node added is the lowest. Hence you want to first add the background image to the StackPane and then the button. That way the button appears on top of the image.
Similarly for layout2, because you first added button2 and after that added the image, the image sits on top of the button and therefore hides the button. You just need to swap them, i.e. add the image first and then add the button.
Note that the URL for the image, in your code, looks incorrect to me. I simply put the image in the same folder as the compiled Main.class file and used method getResource() to get the image file.
Also, I don't think it is a good idea to mix AWT and JavaFX. JavaFX has class Screen that will provide you with the screen dimensions.
Here is your code with my fixes. Compare it with your code to see the differences.
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.stage.Screen;
import javafx.stage.Stage;
import java.net.URL;
public class Main extends Application {
Stage window;
Scene scene1, scene2;
Button button1, button2;
ImageView iv = new ImageView();
#Override
public void start(Stage primaryStage) throws Exception {
Screen screen = Screen.getPrimary();
Rectangle2D screenBounds = screen.getBounds();
primaryStage.setWidth(screenBounds.getWidth());
primaryStage.setHeight(screenBounds.getHeight());
window = primaryStage;
Label label1 = new Label("First stage");
Button button1 = new Button("PLAY");
VBox vBox = new VBox(20);
vBox.getChildren().addAll(label1, button1);
vBox.setAlignment(Pos.CENTER);
// Layout 1
StackPane layout1 = new StackPane();
scene1 = new Scene(layout1, 1280, 720);
layout1.getChildren().addAll(changeBackground("snowymountains.png"), vBox);
// defines dimensions of vbox so button and label can be centered
layout1.prefWidthProperty().bind(window.widthProperty());
layout1.prefHeightProperty().bind(window.heightProperty());
layout1.setAlignment(Pos.CENTER);
button1.setOnAction(event -> window.setScene(scene2));
// Button 2
Button button2 = new Button("This scene sucks, go back to scene 1");
button2.setOnAction(event -> window.setScene(scene1));
// Layout 2
StackPane layout2 = new StackPane();
scene2 = new Scene(layout2, 1280, 720);
layout2.getChildren().addAll(changeBackground("gameBackground.jpg"), button2);
window.setScene(scene1);
window.setTitle("Scramblo");
window.show();
}
public static void main(String[] args) {
launch(args);
}
public Node changeBackground(String imageFile) {
URL url = getClass().getResource(imageFile);
ImageView iv = new ImageView();
Image image = new Image(url.toExternalForm());
iv.setImage(image);
iv.setFitHeight(window.getHeight());
iv.setFitHeight(window.getWidth());
iv.setPreserveRatio(true);
return iv;
}
}

Related

Javafx buttons not functioning properly, and pane not resizing

Currently the code below produces a BorderPane with a GridPane in the center and a HBox on the bottom to hold two buttons. The left-most pane in the GridPane contains the text "Name Here". Right now I only want the buttons to move the text "Name Here" up and down but they will not move the text.
I think it has something to do with the particular GridPane node, but I'm not sure. Additionally, I don't know why the left-most GridPane takes up more space relative to the right-most GridPane within the center of the BorderPane.
Any advice will be greatly appreciated, thank you!
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.geometry.Pos;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.Priority;
import javafx.scene.text.Text;
public class differentWindows extends Application {
protected Text name = new Text("Name Here");
protected BorderPane getPane() {
// HBox to hold the up and down buttons
HBox paneForButtons = new HBox(20);
Button btUp = new Button("Up");
Button btDown = new Button("Down");
paneForButtons.getChildren().addAll(btUp, btDown);
paneForButtons.setAlignment(Pos.BOTTOM_LEFT);
// Grid pane to go in center of the border pane, for the name and video
GridPane paneForTextNVideo = new GridPane();
paneForTextNVideo.setAlignment(Pos.CENTER);
paneForTextNVideo.setGridLinesVisible(true);
paneForTextNVideo.add(name, 0, 0);
Text temp = new Text("temp");
paneForTextNVideo.add(temp, 1, 0);
paneForTextNVideo.setHalignment(temp, HPos.CENTER);
paneForTextNVideo.setValignment(temp, VPos.CENTER);
paneForTextNVideo.setHgrow(temp, Priority.ALWAYS);
paneForTextNVideo.setVgrow(temp, Priority.ALWAYS);
paneForTextNVideo.setHalignment(name, HPos.CENTER);
paneForTextNVideo.setValignment(name, VPos.CENTER);
paneForTextNVideo.setHgrow(name, Priority.ALWAYS);
paneForTextNVideo.setVgrow(name, Priority.ALWAYS);
// Border pane to hold all windows
BorderPane pane = new BorderPane();
pane.setBottom(paneForButtons);
pane.setCenter(paneForTextNVideo);
btUp.setOnAction(e -> name.setY(name.getY() - 10));
btDown.setOnAction(e -> name.setY(name.getY() + 10));
return pane;
} // end of the getPane method
#Override
public void start(Stage primaryStage) {
Scene scene = new Scene(getPane(), 450, 200);
primaryStage.setTitle("Assignment #7");
primaryStage.setScene(scene);
primaryStage.show();
} // end of start method
public static void main(String[] args) {
Application.launch(args);
}
} // end of class
Try using setLayoutY instead of setY:
btUp.setOnAction(e -> name.setLayoutY(name.getLayoutY() - 10));
btDown.setOnAction(e -> name.setLayoutY(name.getLayoutY() + 10));
As a sidenote, the Node parent class also has a relocate method for easily changing both the X and Y coordinates:

Why does this mess up my program?

I've looked at all my notes and comments from old code but I don't understand why it doesn't work.
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import java.util.Stack;
import javafx.scene.layout.VBox;
public class Main extends Application{
Stage window;//makes window a stage
Scene scene1, scene2;//makes scene1 and scene2 into Scene's
public static void main(String []args) {
//launches the main
launch(args);
}
#Override//Overrides Application
public void start(Stage primaryStage) throws Exception {
window = primaryStage;//Makes window primary stage
Label label1 = new Label ("This is the first scene!");//Makes a label
Button button1 = new Button();//Declares button as a Button
button1.setText("Click me for Scene 2");//Sets the text of the button
button1.setOnAction(e -> window.setScene(scene2));
//This say, on the action, change the scene
VBox layout1 = new VBox(20);//Makes layout1 into a VBox
layout1.getChildren().addAll(label1, button1);//Adds the 'Children'
scene1 = new Scene(layout1, 500, 400);//Sets up layout1
Button button2 = new Button();//makes a second button
button2.setText("Click me for scene 1");//sets the text for button2
button2.setOnAction(e -> window.setScene(scene1));//When button 2 is click, it changes scene
StackPane layout2 = new StackPane();//Makes a new StackPane layout
layout2.getChildren().add(button2);//Adds button2 to the layout
scene2 = new Scene (layout2, 500, 400);//Gives arguemnts for Scene2
window.setScene(scene1);//Sets scene of the window stage
window.setTitle("This is a title");//Sets title
window.show();//Shows the window
}
}
Vs.
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import java.util.Stack;
import javafx.scene.layout.VBox;
public class Main extends Application{
Stage window;//makes window a stage
Scene scene1, scene2;//makes scene1 and scene2 into Scene's
public static void main(String []args) {
//launches the main
launch(args);
}
#Override//Overrides Application
public void start(Stage primaryStage) throws Exception {
window = primaryStage;//Makes window primary stage
Label label1 = new Label ("This is the first scene!");//Makes a label
Button button1 = new Button();//Declares button as a Button
button1.setText("Click me for Scene 2");//Sets the text of the button
button1.setOnAction(e -> window.setScene(scene2));
//This say, on the action, change the scene
VBox layout1 = new VBox(20);//Makes layout1 into a VBox
layout1.getChildren().addAll(label1, button1);//Adds the 'Children'
Scene scene1 = new Scene(layout1, 500, 400);//Sets up layout1
Button button2 = new Button();//makes a second button
button2.setText("Click me for scene 1");//sets the text for button2
button2.setOnAction(e -> window.setScene(scene1));//When button 2 is click, it changes scene
StackPane layout2 = new StackPane();//Makes a new StackPane layout
layout2.getChildren().add(button2);//Adds button2 to the layout
Scene scene2 = new Scene (layout2, 500, 400);//Gives arguemnts for Scene2
window.setScene(scene1);//Sets scene of the window stage
window.setTitle("This is a title");//Sets title
window.show();//Shows the window
}
}
The only thing I changed between the two was adding the word 'Scene':
scene1 = new Scene.... Works
vs
Scene scene2 = new Scene.... Doesn't work. Why is this?
The reason putting Scene before them doesn't work is because you've already declared them, but not initialised them, as Scenes in the line
Scene scene1, scene2
So you don't need to specify that again.
It'd be like making an integer int a then initialising it int a = 1. That doesn't make sense, because a has already been defined as an int.
And really, it's less of "it doesn't work" and more of "it doesn't make sense".
You are shadowing your member variables and leaving them as null in the second code.
In other words, there's only 2 instances of a Scene in the first code, and 4 in the other
When you do this, it uses Main.this.scene2, not the local instance .
button1.setOnAction(e -> window.setScene(scene2));
If you did need to use the local instance, you need to declare it final and initialize before the action listener was set.

Bookmarks and History Buttons not showing up in my Browser using JavaFX

I am making a web browser in JavaFX and I thought everything was good and dandy. I ran the application and now the History and Bookmarks buttons will not appear. I looked through the code and saw no errors. How do I fix this?
package javafxapplication3;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.application.Application;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebHistory;
public class CreateAsIGo2 extends Application{
public static void main(String[] args){
launch(args);
}
public void start(Stage primaryStage){
BorderPane ap = new BorderPane();
BorderPane ap2 = new BorderPane();
BorderPane ap3 = new BorderPane();
Scene scene = new Scene(ap, 700, 700);
Scene scene2 = new Scene(ap2, 700, 700);
Scene scene3 = new Scene(ap3, 700, 700);
VBox sp = new VBox();
VBox sp2 = new VBox();
VBox sp3 = new VBox();
Button HistoryButton = new Button("History");
Button BookmarksButton = new Button("Bookmarks");
Button RefreshButton = new Button("Refresh");
Button BackButton = new Button("Back");
Button BackToBrowser = new Button("Back to surfing the web");
Button ForwardButton = new Button("Forward");
TextField tf = new TextField();
tf.setPromptText("URL");
WebView browser = new WebView();
WebEngine webEngine = browser.getEngine();
webEngine.load("http://www.google.com");
webEngine.setJavaScriptEnabled(true);
WebHistory history = webEngine.getHistory();
HistoryButton.setOnAction(e -> primaryStage.setScene(scene2));
BookmarksButton.setOnAction(e -> primaryStage.setScene(scene3));
RefreshButton.setOnAction(e -> webEngine.reload());
BackButton.setOnAction(e -> webEngine.executeScript("history.back()"));
BackToBrowser.setOnAction(e -> primaryStage.setScene(scene));
ForwardButton.setOnAction(e -> webEngine.executeScript("history.forward()"));
tf.setOnKeyPressed((KeyEvent ke) -> {
KeyCode key = ke.getCode();
if(key == KeyCode.ENTER){
webEngine.load("http://" + tf.getText());
}
});
sp.getChildren().addAll(HistoryButton, BookmarksButton, RefreshButton, BackButton, ForwardButton);
sp2.getChildren().addAll(BookmarksButton, BackToBrowser);
sp3.getChildren().addAll(HistoryButton, BackToBrowser);
ap.setRight(sp);
ap2.setRight(sp2);
ap3.setRight(sp3);
ap.setTop(tf);
ap.setCenter(browser);
browser.setPrefSize(700, 700);
primaryStage.setTitle("JTG Browser Alpha");
primaryStage.setScene(scene);
primaryStage.show();
}
}
See the node documentation:
If a program adds a child node to a Parent (including Group, Region, etc) and that node is already a child of a different Parent or the root of a Scene, the node is automatically (and silently) removed from its former parent.
You are adding your HistoryButton (and other buttons) to different scenes and, when you do so, they are automatically removed from the previous scenes. You need to create new button instances if you want them visible in every scene.
Small aside: it is best to follow Java naming conventions, e.g. historyButton instead of HistoryButton.

How to set TextField at the top of the position?

HiEveryone,
I'm new in JavaFx and my TextField shows at the middle of the frame but not at the top's position. Where am i suppose to be wrong? pls help..
Have a look into this screenshot..
But i want to set that TextField at the top ..
Here is Source code:
package sample;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.scene.control.TextField;
public class Main extends Application {
#Override
public void start (Stage primaryStage){
primaryStage.setTitle("Modern web browser.");
WebView wv = new WebView();
WebEngine we = wv.getEngine();
we.load("http://www.google.com/");
TextField tf = new TextField("http://www.google.com/");
tf.setMaxHeight(Double.MIN_VALUE);
GridPane sp = new GridPane();
sp.getChildren().add(wv);
sp.getChildren().add(tf);
Scene scene = new Scene(sp, 600, 500);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Please help.. Thanks in Advanced!
EDITED
As #Nagesh Kumar answered me after using VBox getting this error:
Change your layout to VBox from GridPane as follows
VBox vbox = new VBox();
Now first add your TextField first so that it will be on top as follows
vbox.getChildren().add(tf);
then a WebView as follows
vbox.getChildren().add(wv);
Edit:
Yes you can try this
VBox vbox = new VBox(5);
5 pixel space between controls put in VBox

How to change float of this button?

HiEveryone,
I'm new Javafx and trying to change the float of this button as to Right side from the current Left side.. How to do that?
I'm using simply Pane as a container at the moment.
Have a look into this screenshot:
How to do that? ..pls help
Thanks in advance!
EDITED
Source code:
package sample;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.scene.control.TextField;
import javafx.scene.control.Button;
public class Main extends Application {
#Override
public void start (Stage primaryStage){
primaryStage.setTitle("Modern web browser made by Rajendra arora.");
WebView wv = new WebView();
wv.setLayoutX(0.0);
wv.setLayoutY(40.0);
wv.setPrefHeight(Double.MAX_EXPONENT);
wv.setPrefWidth(Double.MAX_EXPONENT);
WebEngine we = wv.getEngine();
we.load("http://www.google.com/");
Button btn=new Button("Go");
TextField tf = new TextField("http://www.google.com/");
tf.setLayoutX(1.0);
tf.setPrefWidth(Double.MAX_EXPONENT);
tf.setPrefHeight(25.0);
Pane sp = new Pane();
sp.getChildren().add(tf);
sp.getChildren().add(btn);
sp.getChildren().add(wv);
Scene scene = new Scene(sp, 600, 500);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Use a HBox to hold the textfield and button, later add it to the Pane
HBox hbox = new HBox();
hbox.getChildren().addAll(tf, btn);
Pane sp = new Pane();
sp.getChildren().add(hbox);
sp.getChildren().add(wv);

Categories

Resources