Let Window scroll down in JavaFX - java

So I am trying to learn Java now that I know JavaScript and PHP. I am working in Netbeans with JavaFX and I am trying to create a program that creates 5 buttons. (This is modifying the code that comes with Netbeans when creating a new JavaFX Application.) If I change the y-argument of the scene to be less than the y of all of the buttons, it will not display the remaining buttons and it will not be able scroll down. This is what I have so far. How do I enable it to scroll down so all buttons can be seen? I know that I can just change the scene back to its old height but I want to learn about scrolling with JavaFX.
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import javax.swing.JScrollPane;
public class JavaFXApplication1 extends Application {
#Override
public void start(Stage primaryStage) {
GridPane root = new GridPane();
Button[] btn=new Button[5];
for(int i=0;i<5;i++){
btn[i] = new Button();
btn[i].setText(i+"");
GridPane.setRowIndex(btn[i],i);
root.getChildren().addAll(btn[i]);
btn[i].setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("This is a button");
}
});
}
Scene scene = new Scene(root, 300, 50);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Using ScrollPane to set root as:
ScrollPane sp = new ScrollPane();
sp.setContent(root);
Scene scene = new Scene(sp, 300, 50);

Related

How to display some values of javafx combo box before any click on it?

I use a combo that works nice. The only thing i would like to add is to diplay some items(~10) of this box by default at start . I tried to find this property but a hell to find this among all methods.
If somebody knows how to to that
I have the same question for Menubutton
Thanks
Just call show() on the ComboBox. Here is an example:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class ComboTest extends Application {
#Override
public void start(Stage stage) {
ComboBox<String> combo = new ComboBox<>();
for (int i = 1 ; i <= 20 ; i++) combo.getItems().add("Item "+i);
BorderPane root = new BorderPane();
root.setTop(combo);
Scene scene = new Scene(root, 650, 400);
stage.setScene(scene);
stage.show();
combo.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
The same thing works for MenuButton.

Binding label to bottom-center of scene - JavaFX

I am trying to figure out how to center and bind a label perfectly at the bottom of a scene. I have a simple test application here to show what I am working with and what my issue is.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class LabelTest extends Application {
#Override
public void start(Stage stage) throws Exception {
Pane root = new Pane();
Scene scene = new Scene(root, 400, 400);
Label label = new Label("Testing testing 1 2 3");
label.layoutXProperty().bind(scene.widthProperty().divide(2).subtract(label.getWidth() / 2)); //Should align label to horizontal center, but it is off
label.layoutYProperty().bind(scene.heightProperty().subtract(label.getHeight() + 35)); //Aligns the label to bottom of scene
root.getChildren().add(label);
stage.setScene(scene);
stage.show();
}
}
The logic behind my positioning makes sense to me, so I am not sure why it is not horizontally centered. I have included a screenshot below to show what the output looks like:
And below is more of what I am wanting it to look like (still off by a bit, but you get the point)
Thanks in advance to anyone who helps me out!
Let layout managers do the layout for you:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class LabelTest extends Application {
#Override
public void start(Stage stage) throws Exception {
Label label = new Label("Testing testing 1 2 3");
BorderPane root = new BorderPane();
//center label by
//BorderPane.setAlignment(label, Pos.CENTER);
//root.setBottom(label);
//OR
root.setBottom(new StackPane(label));
Scene scene = new Scene(root, 400, 400);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
The issue is you are taking the values of width/height at the time of binding. And at this instance it will be 0 as they are not yet rendered. You need bind those properties as well for computing.
label.layoutXProperty().bind(scene.widthProperty().divide(2).subtract(label.widthProperty().divide(2)));
label.layoutYProperty().bind(scene.heightProperty().subtract(label.heightProperty().add(35)));

JFXtras MonologFX - How to detect which button was pressed

I was testing the MonologFX from JFXtras (v8.0-r5), but I got stuck with it!
Can anyone tell me how to check what was the button in the dialog that was pressed by the user? I tried in many ways, but no luck at all.
package javafx_jfxtras_monologfx;
import javafx.application.Application;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.event.EventHandler;
import javafx.event.ActionEvent;
import jfxtras.labs.dialogs.MonologFX;
import jfxtras.labs.dialogs.MonologFXButton;
import jfxtras.labs.dialogs.MonologFX.Type;
public class JavaFX_JFXtras_MonologFX extends Application
{
#Override
public void start(Stage stage)
{
MonologFX m = new MonologFX();
m.setModal(true);
m.setType(Type.QUESTION);
m.setTitleText("JFXtras MonologFX");
m.setMessage("Do you want to continue?");
m.setPos(698, 450);
MonologFXButton mb1 = new MonologFXButton();
mb1.setType(MonologFXButton.Type.YES);
mb1.setLabel("Continue");
m.addButton(mb1);
MonologFXButton mb2 = new MonologFXButton();
mb2.setType(MonologFXButton.Type.NO);
mb2.setLabel("Exit");
m.addButton(mb2);
Button btn = new Button();
btn.setText("Click the Button");
btn.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent event)
{
System.out.println("Hello :)");
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
stage.setTitle("JavaFX - JFXtras MonologFX");
stage.setScene(scene);
stage.show();
m.show();
}
public static void main(String[] args)
{
launch(args);
}
}
But the controls in labs are experimental and Mark has not worked on this one for a long time. We don't take them out because someone may use them, but as of version 8u40 JavaFX has a dialog itself. https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/Dialog.html|

Application with BorderPane doesn't display simple button

very new to JavaFX I'm following a simple tutorial here
I created a new JavaFX project but it has a BorderPane as a default rather than a StackPane as the tutorial says, so I left it there.
The application only has a button on it and if I use the BorderPane the button isn't displayed.
If I change it to StackPane the button shows up.
Thinking that for some reason the BorderPane was clipping something off, I made the application windows full size, but I still couldn't see the button.
Here is the code with the BorderPane the one that doesn't display the button:
package application;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setTitle("This is a test!");
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
root.getChildren().add(btn);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Any idea?
Take a look at the docs about BorderPane:
BorderPane lays out children in top, left, right, bottom, and center
positions.
Therefore you need to use stuff like:
borderPane.setTop(toolbar);
borderPane.setCenter(appContent);
borderPane.setBottom(statusbar);
In your case root.getChildren().add(btn); should be for example root.setCenter(btn);.

Switching scenes don't retain maximized screen in JavaFX

My configuration:
I need to switch between scenes via the same stage
I need to keep a maximized stage that fills the whole screen
My issue:
although I set my stage to be maximized primaryStage.setMaximized(true);it adopts its size to the size of the scenes afterwards.
What I tried until now:
I tried using primaryStage.getScene().setRoot(<the root node of scene>). While it worked to keep the stage maximized, yet after each change of scene the focus on the previously focused gui control is lost (after switch only the first gui control in the scene hierarchy is focused). I really need scenes, so that any gui control that was focused still be will focused after the stage changes its scene.
I need your assistance:
I really need your assistance in keeping the stage maximized during changing scenes.
Here is my example code:
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class NewFXMain extends Application {
#Override
public void start(Stage primaryStage) {
// init buttons
Button btn1 = new Button("switch to next scene >>");
Button btn2 = new Button("<< switch to previous scene");
// first scene
StackPane root1 = new StackPane();
root1.getChildren().add(btn1);
Scene scene1 = new Scene(root1, 300, 250);
// second scene
StackPane root2 = new StackPane();
root2.getChildren().add(btn2);
Scene scene2 = new Scene(root2, 500, 400);
// button actions
btn1.setOnAction((ActionEvent event) -> {
primaryStage.setScene(scene2);
});
btn2.setOnAction((ActionEvent event) -> {
primaryStage.setScene(scene1);
});
primaryStage.setMaximized(true);
primaryStage.setScene(scene1);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
SOLUTION
create scenes depending on the screen size of your monitor
after several attempts I finally figured how to easily solve this problem to keep the maximized screen while retaining the focused node on each Scene. Hope it helps the community:
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Screen;
import javafx.stage.Stage;
public class NewFXMain extends Application {
#Override
public void start(Stage primaryStage) {
// get screensize of monitor
Rectangle2D screenSize = Screen.getPrimary().getVisualBounds();
// init buttons
Button btn1 = new Button("switch to next scene >>");
Button btn2 = new Button("<< switch to previous scene");
// first rootNode
StackPane root1 = new StackPane();
root1.getChildren().add(btn1);
Scene scene1 = new Scene(root1, screenSize.getWidth(), screenSize.getHeight());
// second rootNode
StackPane root2 = new StackPane();
root2.getChildren().add(btn2);
Scene scene2 = new Scene(root2, screenSize.getWidth(), screenSize.getHeight());
// button actions
btn1.setOnAction((ActionEvent event) -> {
primaryStage.setScene(scene2);
});
btn2.setOnAction((ActionEvent event) -> {
primaryStage.setScene(scene1);
});
primaryStage.setMaximized(true); // keep this since otherwise the titlebar is bit overlapped
primaryStage.setScene(scene1);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I think it's a bug. You can report it at: http://bugreport.java.com.
In the meantime, as a workaround, you probably need to just set the pane for a shared scene, replacing its content rather than replacing the scene.
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class NewFXMainFixed extends Application {
#Override
public void start(Stage primaryStage) {
// init buttons
Button btn1 = new Button("switch to next scene >>");
Button btn2 = new Button("<< switch to previous scene");
// first scene
StackPane root1 = new StackPane();
root1.getChildren().add(btn1);
// second scene
StackPane root2 = new StackPane();
root2.getChildren().add(btn2);
// button actions
btn1.setOnAction((ActionEvent event) ->
primaryStage.getScene().setRoot(root2)
);
btn2.setOnAction((ActionEvent event) ->
primaryStage.getScene().setRoot(root1)
);
Scene scene = new Scene(root1);
primaryStage.setMaximized(true);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Categories