JavaFX WebView resize issue - java

How do I resize a web view correctly? The moment the window gets reduced to a smaller size it seems to push the WebView to the end of the frame, without actually resizing. How would I do this correctly allowing the window to be resized and the WebView to fit in the frame appropriately.
public class OuroborosViewer extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
stage.setTitle("Ouroboros");
Scene scene = new Scene(new VBox(), 1920, 1080);
scene.setFill(Color.OLDLACE);
MenuBar menuBar = new MenuBar();
Menu menuFile = new Menu("File");
Menu menuEdit = new Menu("Edit");
Menu menuView = new Menu("View");
menuBar.getMenus().addAll(menuFile, menuEdit, menuView);
((VBox) scene.getRoot()).getChildren().addAll(menuBar);
BorderPane borderPane = createTab(scene);
((VBox) scene.getRoot()).getChildren().add(borderPane);
scene.widthProperty().addListener(new WidthListener());
scene.heightProperty().addListener(new HeightListener());
// stage.getIcons().add(new Image("Ouroboros.svg"));
stage.setScene(scene);
try {
sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(OuroborosViewer.class.getName()).log(Level.SEVERE, null, ex);
}
stage.show();
}
private BorderPane createTab(Scene scene) {
TabPane tabPane = new TabPane();
BorderPane borderPane = new BorderPane();
Tab tab = new Tab();
tab.setText("Google");
//VBox hbox = new VBox(new BrowserToolbar(scene), new OuroborosBrowser(scene));
VBox vbox = new VBox();
BrowserToolbar toolbar = new BrowserToolbar(scene);
OuroborosBrowser ob = new OuroborosBrowser(scene);
VBox.setVgrow(toolbar, Priority.ALWAYS);
VBox.setVgrow(ob, Priority.ALWAYS);
vbox.getChildren().addAll(toolbar, ob);
vbox.autosize();
tabPane.getTabs().add(tab);
tab.setContent(vbox);
borderPane.setTop(tabPane);
return borderPane;
}
private static class WidthListener implements ChangeListener<Number> {
#Override
public void changed(ObservableValue<? extends Number> observableValue, Number oldSceneWidth, Number newSceneWidth) {
OuroborosBrowser.browsers[0].setPrefWidth(newSceneWidth.doubleValue());
BrowserToolbar.URLBars[0].setPrefWidth(newSceneWidth.doubleValue() - 115);
BrowserToolbar.toolBars[0].setPrefWidth(newSceneWidth.doubleValue());
}
}
private static class HeightListener implements ChangeListener<Number> {
#Override
public void changed(ObservableValue<? extends Number> observableValue, Number oldSceneHeight, Number newSceneHeight) {
if (oldSceneHeight != newSceneHeight) {
try {
OuroborosBrowser.browsers[0].setPrefHeight(newSceneHeight.doubleValue()
+ OuroborosBrowser.browsers[0].getScene().getRoot().getChildrenUnmodifiable()
.get(0).prefHeight(0));
} catch (Exception ex) {
}
}
}
}
}
class OuroborosBrowser extends Region {
public static int browserCounter = 0;
public static WebView[] browsers = new WebView[25];
private static WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
public OuroborosBrowser(Scene scene) {
browser.setPrefSize(scene.getWidth(), scene.getHeight());
webEngine.load("http://www.google.com/index.html");
getChildren().add(browser);
browsers[browserCounter] = browser;
browserCounter++;
}
}
public class BrowserToolbar extends Region {
public static TextField[] URLBars = new TextField[25];
public static ToolBar[] toolBars = new ToolBar[25];
public static int barCounter = 0;
public BrowserToolbar(Scene scene) {
Button backButton = new Button(" < ");
Button forwardButton = new Button(" > ");
TextField URLbar = new TextField();
URLbar.setPrefWidth(scene.getWidth() - 115);
URLBars[barCounter] = URLbar;
URLbar.setPrefWidth(2000);
final ToolBar toolbar = new ToolBar(
backButton, forwardButton, URLbar);
toolbar.setPrefWidth(2000);
toolBars[barCounter] = toolbar;
barCounter++;
HBox hb = new HBox();
hb.getChildren().add(toolbar);
hb.setPrefWidth(scene.getWidth());
hb.autosize();
getChildren().add(hb);
}
}
The area shaded in the image below is the area that keeps increasing as the frame height is reduced.
link to image

Related

How do I call back to the main node so I can switch to a different scene in javafx

so I am trying to switch to a different scene in javafx. I am working on a project where the user will select on a food category via a combobox, which will switch to a new scene that has all the recipes under that specific category.
The problem is I am able to load my MainMenuScene, but I am not sure how to switch to a different scene, which I think is because of how I have structured my code.
My code is structured where I can GUIAPP (which starts the entire GUI)
private static View myView;
private static Recipe myRecipe;
public GUIApp() {
myView = new View();
myRecipe = new Recipe();
}
public static View getView() {
return myView;
}
public static Recipe getRecipe() {
return myRecipe;
}
#Override
public void start(Stage primaryStage) throws Exception {
System.out.println("Starting app...");
myView.setStage(primaryStage);
}
public static void main(String [] args) {
myRecipe = new Recipe();
launch(args);
}
}
Then View, which sets the primary Stage (which is MainMenuScene)
private Stage myStage;
private Scene myMainMenuScene;
private Scene myMealScene;
public View() {
myMainMenuScene = new MainMenuScene(new BorderPane());
}
public Stage getStage() {
return myStage;
}
public Scene getMealScene() {
return myMealScene;
}
public void setStage(Stage primaryStage) {
myStage = primaryStage;
myStage.setScene(myMainMenuScene);
myStage.setTitle("Recipe Database");
myStage.setWidth(600);
myStage.setHeight(400);
Scene scene = myMainMenuScene;
myStage.setScene(scene);
myStage.show();
}
}
Here is MainMenuScene, where it calls the recipe code I had previously made
private BorderPane myRoot;
private String f, t;
Label label = new Label();
public MainMenuScene(Parent root) {
super(root);
myRoot = (BorderPane) root;
BorderPane titleBox = new BorderPane();
titleBox.setStyle("-fx-font: 24 arial;");
myRoot.setTop(titleBox);
Text title = new Text("Recipe Database Tool");
title.setFont(new Font(50));
titleBox.setCenter(title);
//VBox and HBox creation
VBox leftBox = new VBox();
VBox rightBox = new VBox();
VBox centerBox = new VBox();
//Button search = new Button("Recipe Categories");
Button create = new Button("Create/Upload a New Recipe");
//Creates a combobox that gets the category name from Recipe
ComboBox<String> search = new ComboBox<String>();
search.getItems().addAll(GUIApp.getRecipe().getCategory());
search.setOnAction((e) -> {
search.getSelectionModel().selectFirst();
});
/*
****//Create a button that switches to MealScene when a category is selected
Button select = new Button("Select");
select.setOnAction((e) -> {
View.getStage().setScene(View.getMealScene());****
});
*/
//myRoot for each Box
myRoot.setLeft(leftBox);
myRoot.setRight(rightBox);
myRoot.setCenter(centerBox);
//adding the search categories button to the left box
leftBox.setAlignment(Pos.CENTER);
leftBox.setSpacing(30);
leftBox.getChildren().add(search);
//adding the create a new recipe to the right box
rightBox.setAlignment(Pos.CENTER);
rightBox.setSpacing(30);
rightBox.getChildren().add(create);
}
}
I tried calling the button by using View, but I am getting an error that I am not sure how to fix.
Here's the error: It's asking for View.getStage() to make getStage a static method in View, which I don't want to do and View.getMealScene to also become static
Please let me know! I would love to learn how to prevent this in the future

how to change real time node information in javafx?

I'm trying to change the value of a string that is in another method with an event in a button, but when clicking nothing happens.
public class Test extends Application{
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
Objeto1 root = new Objeto1();
Scene scene = new Scene(root.first());
stage.setScene(scene);
stage.show();
}
}
Objeto1
public class Objeto1 {
String tmp ="hola";
public Objeto1() {
}
public VBox first(){
VBox root = new VBox();
setTmp("hola");
HBox button = new HBox();
Button btn = new Button("cliclk");
btn.setOnAction(e->{
setTmp("");
});
button.getChildren().add(btn);
HBox a = form();
root.getChildren().addAll(button,a);
return root;
}
public HBox form(){
HBox root = new HBox();
Label lab = new Label(getTmp());
root.getChildren().add(lab);
return root;
}
public String getTmp() {
return tmp;
}
public void setTmp(String tmp) {
this.tmp = tmp;
}
}
I would like to click on the content of the string change and show in the label the change

how to switching scenes in javafx (NO FXML)

I ask for your understanding, I am a beginner;)
I'm trying to build a simple application using JavaFX. The problem is that when I open the window the first time it goes well, but if I want to change the scene it throws an error...
Exception in thread "JavaFX Application Thread"
java.lang.IllegalArgumentException:
AnchorPane#1809546[styleClass=root]is already set as root of another
scene#
Main class
public class Main extends Application{
//private Stage primaryStage;
#Override
public void start(Stage primaryStage) {
Login login = new Login();
Scene scene = login.okno();
primaryStage.setTitle("Komunikator sieciowy JAVA");
primaryStage.setScene(scene);
primaryStage.setResizable(false);
primaryStage.show();
}
//public Stage getPrimaryStage() {
// return this.primaryStage;
//}
public static void main(String[] args) {
launch(args);
}
}
Login
public class Login {
private GridPane grid;
private Scene scene;
private Text title;
private Label nick;
private Button wejdzBtn;
private TextField userName;
//private Alert oknoDlg;
public Login() {
grid = new GridPane();
grid.setAlignment (Pos.CENTER);
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(25,25,25,25));
scene = new Scene (grid, 300, 150);
utworzBtn();
utworzLogin();
utworzTekst();
utworzNick();
//oknoDialogowe();
}
//private void oknoDialogowe() {
//Alert oknoDlg = new Alert(Alert.AlertType.CONFIRMATION);
//oknoDlg.setTitle("Informacja");
//oknoDlg.setContentText("test");
// oknoDlg.setHeaderText(null);
//oknoDlg.showAndWait();
//}
private void utworzBtn() {
wejdzBtn = new Button("Zaloguj si\u0119");
HBox hbBtn = new HBox(10);
hbBtn.setAlignment (Pos.BOTTOM_RIGHT);
hbBtn.getChildren().add(wejdzBtn);
grid.add(hbBtn, 1, 2);
//wejdzBtn.setDisable(true);
wejdzBtn.setOnAction(e -> {
Messages mess = new Messages();
grid.getScene().setRoot(mess.messa());;
});
}
private void utworzLogin() {
nick = new Label("Nick:");
grid.add(nick, 0, 1);
}
private void utworzNick() {
userName = new TextField();
grid.add(userName,1,1);
// informacja w polu tekstowym
userName.setPromptText("Max 15 znak\u00f3w");
userName.setFocusTraversable(false);
//maksymalna ilość znaków
final int maxLength = 15;
userName.setOnKeyTyped(t -> {
if (userName.getText().length() > maxLength)
{
int pos = userName.getCaretPosition();
userName.setText(userName.getText(0, maxLength));
userName.positionCaret(pos);
}
});
}
private void utworzTekst() {
title = new Text ("Dzień dobry!");
title.setFont(Font.font("Calibri", FontWeight.NORMAL, 20));
grid.add(title, 0, 0, 2, 1);
}
public Scene okno() {
return scene;
}
}
and and a little another class that I'm trying to change with button from login.java
public class Messages {
private AnchorPane anchor;
private Scene scena;
//private Label nick;
private Button sendBtn;
private TextField poleDoWpisywania;
private TextArea poleDoWyswietlania, pobierzNick;
public Messages() {
anchor = new AnchorPane();
scena = new Scene(anchor, 700, 600);
pobierzNick();
poleDoWpisywania();
poleDoWyswietlania();
utworzPrzycisk();
}
private void utworzPrzycisk() {
sendBtn = new Button("Wy\u015Blij");
sendBtn.setDisable(true);
}
private void pobierzNick(){
pobierzNick = new TextArea();
pobierzNick.setEditable(false);
pobierzNick.setWrapText(true);
}
private void poleDoWpisywania() {
poleDoWpisywania = new TextField();
}
private void poleDoWyswietlania() {
poleDoWyswietlania = new TextArea();
poleDoWyswietlania.setEditable(false);
poleDoWyswietlania.setWrapText(true);
}
public Pane messa() {
return anchor;
}
}
could I ask you to show the right way to fix the bug?
JavaFX defines a scene graph which is a tree data structure that has a single root node. For your application (i.e. the code you posted), the root node is the primaryStage (this is the parameter in method start() in class Main). The primaryStage can have several Scenes. Each Scene must have its own root node.
The error message you are getting means that a Scene's root cannot also be the root of another Scene. In other words anchor is the root for scena in class Messages which means it can't be set as the root for scene in class Login.
Apart from that, if you want to change Scene's you need to call method setScene() of class Stage. Here is your Login class and Messages class with changes that solve the run-time error you are getting and perform the scene change when the user clicks on wejdzBtn button.
Login.java
(I only changed the lambda expression in method utworzBtn().)
public class Login {
private GridPane grid;
private Scene scene;
private Text title;
private Label nick;
private Button wejdzBtn;
private TextField userName;
public Login() {
grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(25,25,25,25));
scene = new Scene(grid, 300, 150);
utworzBtn();
utworzLogin();
utworzTekst();
utworzNick();
}
private void utworzBtn() {
wejdzBtn = new Button("Zaloguj si\u0119");
HBox hbBtn = new HBox(10);
hbBtn.setAlignment (Pos.BOTTOM_RIGHT);
hbBtn.getChildren().add(wejdzBtn);
grid.add(hbBtn, 1, 2);
wejdzBtn.setOnAction(e -> {
Messages mess = new Messages();
Window w = scene.getWindow();
if (w instanceof Stage) {
Stage s = (Stage) w;
s.setScene(mess.getScena());
}
});
}
private void utworzLogin() {
nick = new Label("Nick:");
grid.add(nick, 0, 1);
}
private void utworzNick() {
userName = new TextField();
grid.add(userName,1,1);
userName.setPromptText("Max 15 znak\u00f3w");
userName.setFocusTraversable(false);
final int maxLength = 15;
userName.setOnKeyTyped(t -> {
if (userName.getText().length() > maxLength)
{
int pos = userName.getCaretPosition();
userName.setText(userName.getText(0, maxLength));
userName.positionCaret(pos);
}
});
}
private void utworzTekst() {
title = new Text ("Dzień dobry!");
title.setFont(Font.font("Calibri", FontWeight.NORMAL, 20));
grid.add(title, 0, 0, 2, 1);
}
public Scene okno() {
return scene;
}
}
Messages.java
(I added method getScena().)
public class Messages {
private AnchorPane anchor;
private Scene scena;
private Button sendBtn;
private TextField poleDoWpisywania;
private TextArea poleDoWyswietlania, pobierzNick;
public Messages() {
anchor = new AnchorPane();
scena = new Scene(anchor, 700, 600);
pobierzNick();
poleDoWpisywania();
poleDoWyswietlania();
utworzPrzycisk();
}
private void utworzPrzycisk() {
sendBtn = new Button("Wy\u015Blij");
sendBtn.setDisable(true);
}
private void pobierzNick() {
pobierzNick = new TextArea();
pobierzNick.setEditable(false);
pobierzNick.setWrapText(true);
}
private void poleDoWpisywania() {
poleDoWpisywania = new TextField();
}
private void poleDoWyswietlania() {
poleDoWyswietlania = new TextArea();
poleDoWyswietlania.setEditable(false);
poleDoWyswietlania.setWrapText(true);
}
public Scene getScena() {
return scena;
}
public Pane messa() {
return anchor;
}
}
Thanks a lot Abra, I've been thinking about it for the last 6 hours and haven't noticed this problem. I have also removed
public Pane messa ();
return anchor;
I do not need it ;)

How do you call graphics class from main class in JavaFX?

I'm a really new programmer so idk if this question sounds really stupid but..
This is my main:
package culminating;
import javafx.application.Application;
& all other necessary imports...
public class CulminatingMAIN extends Application {
//Set Global variables
int count = 0;
String name;
String gender = "Boy";
Label testLabel = new Label(gender + " has been selected");
#Override
public void start(Stage primaryStage) throws Exception {
/**
* ************************ SCENE 1 WORK *************************
*/
TextField nameTextField = new TextField();
nameTextField.setMaxWidth(100);
Label nameLabel = new Label("Please enter your name.");
Label genderLabel = new Label();
Label titleLabel = new Label("Math Adventure!");
titleLabel.setFont(Font.font("Arial", FontWeight.BOLD, 30));
Rectangle titleRectangle = new Rectangle();
titleRectangle.setFill(Color.TOMATO);
titleRectangle.setWidth(280);
titleRectangle.setHeight(60);
titleRectangle.setStroke(Color.BLACK);
titleRectangle.setStrokeWidth(2.0);
StackPane root = new StackPane(titleRectangle, titleLabel);
//Set VBox properties
VBox vbox1 = new VBox(25);
vbox1.setAlignment(Pos.TOP_CENTER);
vbox1.setPadding(new Insets(60, 0, 0, 0));
vbox1.setStyle("-fx-background-color: lightskyblue");
HBox genderBtnBox = new HBox(25);
genderBtnBox.setAlignment(Pos.CENTER);
//Set Scene 1 buttons
Button enterNameBtn = new Button("Enter");
Button goToScene2Btn = new Button("Continue");
//Set Radio Button functionality here
final ToggleGroup genderGroup = new ToggleGroup();
RadioButton rb1 = new RadioButton("Boy");
rb1.setToggleGroup(genderGroup);
rb1.setUserData("Boy");
rb1.setSelected(true);
RadioButton rb2 = new RadioButton("Girl");
rb2.setToggleGroup(genderGroup);
rb2.setUserData("Girl");
//Add panes, labels and buttons to the VBox
vbox1.getChildren().addAll(root, nameLabel, nameTextField, enterNameBtn, genderLabel, genderBtnBox);
Scene scene = new Scene(vbox1, 500, 500);
primaryStage.setScene(scene);
primaryStage.setTitle("Culminating Project");
primaryStage.show();
/**
* ************************ SCENE 2 WORK *************************
*/
//THIS IS ROUGH WORK SO FAR
//Here, testing out new scene to see that it loads properly (and it does)
Circle testCircle = new Circle();
testCircle.setRadius(30);
testCircle.setFill(Color.YELLOW);
StackPane testPane = new StackPane(testCircle, testLabel);
Scene scene2 = new Scene(testPane, 500, 500);
/**
* ************************ EVENTS *************************
*/
//Stores user-entered name and prompts for user gender. Adds Continue button
enterNameBtn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
if ((count < 1) && (!nameTextField.getText().isEmpty())) {
name = nameTextField.getText();
genderLabel.setText("Hi " + name + "! Please select whether you are a boy or girl.");
genderBtnBox.getChildren().addAll(rb1, rb2);
vbox1.getChildren().add(goToScene2Btn);
count++;
}
}
});
//When pressed, changes the scene so that scene 2 is set instead
goToScene2Btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
primaryStage.setScene(scene2);
}
});
//Radio button selection is stored in gender variable
genderGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
#Override
public void changed(ObservableValue<? extends Toggle> ov,
Toggle old_toggle, Toggle new_toggle) {
if (genderGroup.getSelectedToggle() != null) {
gender = genderGroup.getSelectedToggle().getUserData().toString();
testLabel.setText(gender + " has been selected");
}
}
});
if (gender.equals("boy")){
{
}
}
else if (gender.equals("girl")){
{
}
}
}
public static void main(String[] args) {
launch(args);
}
}
Now I have another class called CharacterGraphic, which I want to call and make the graphic I created in it appear.
package culminating;
& all the other imports
public class CharacterGraphic extends Culminating_JavaFX {
public void start(Stage primaryStage) throws Exception {
String gender = "boy";
Pane pane = new Pane();
pane.setStyle("-fx-background-color: LIGHTBLUE");
pane.setPrefSize(200, 200);
Circle head = new Circle();
head.setRadius(50);
head.setCenterX(240);
head.setCenterY(120);
head.setFill(Color.BURLYWOOD);
etc etc (all other graphics i made)
How do I do this???? And where would I do this?? Any answers really, really appreciated!

Web Browser Link manipulation

public class WebWiewYahoo extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
VBox root = new VBox();
Button go = new Button("go");
final TextField address = new TextField("http://www.yahoo.com");
final WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
HBox toolBar1 = new HBox();
toolBar1.setAlignment(Pos.TOP_LEFT);
toolBar1.getChildren().addAll(address, go);
// load the web page
webEngine.load("http://www.yahoo.com");
root.getChildren().add(toolBar1);
root.getChildren().add(browser);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
}
//I want to manipulate link in browser.So that even on clicking any link at any point i could redirect it to yahoo.com.Please help.
You could try to do this :
webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
#Override
public void changed(ObservableValue<? extends State> paramObservableValue,
State oldState,
State newState) {
if (State.SCHEDULED == newState && !"http://www.yahoo.com/".equals(webEngine.getLocation())) {
webEngine.load("http://www.yahoo.com");
}
}
});

Categories