I have noticed the following JavaFX behavior when implementing a JavaFX Application as follows:
public class Test extends Application {
private static Stage innerStage;
public static void main(String[] args) {
launch(args);
printSize(innerStage, "after closing the window");
}
#Override
public void start(Stage primaryStage) {
primaryStage.setWidth(300);
primaryStage.setHeight(250);
primaryStage.setTitle("Hello World!");
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(event -> System.out.println("Hello World!"));
StackPane root = new StackPane();
root.getChildren().add(btn);
primaryStage.setScene(new Scene(root, 250, 200));
primaryStage.show();
primaryStage.setResizable(false);
innerStage = primaryStage;
printSize(primaryStage, "at start-up");
}
private static void printSize(Stage stage, String phase) {
System.out.println(String.format("Width %s: %.1f", phase, stage.getWidth()));
System.out.println(String.format("Height %s: %.1f", phase, stage.getHeight()));
}
}
First print of the stage size gives:
Width at start-up: 300.0
Height at start-up: 250.0
while the second one gives:
Width after closing the window: 312.0
Height after closing the window: 284.0
This happens on Debian GNU/Linux 9.12 (stretch) but not on Windows 10.
Could someone explain what is causing it and let me know if there's a workaround for this such that the stage (window) does not change size by itself?
Thank you
later edit: from what I've seen, the re-size happens right after the start method of the JavaFX Application is done.
Related
I am a Newbie trying to learn java and I am a complete beginner at java Fx so please forgive the noob question but I am trying to structure my code more cleanly by having all my buttons in a class but I know that I have to have the variable 'button' in a StackPane but when I do it it tells me that java can't find the variable. if someone can help me then that would be greatly appreciated. (also when the button is not in another class the code worked)
//this class is for drawing the buttons
public void Buttons() {
Button button = new Button("My Button");
}
public static void main(String[] args) { launch(args); }
#Override
public void start(Stage primaryStage) {
//this sets the Title for the window
primaryStage.setTitle("Calcultor");
//this calls the class that draws the buttons on screen
Buttons();
StackPane root = new StackPane();
root.getChildren().add(button);
//this cerates a stage and sets the window size
primaryStage.setScene(new Scene(root, 300, 400));
//this refreshes the window
primaryStage.show();
}
}
I don't know how to close the main window in java fxml.
This part of code is in the class Main:
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
Parent root2 = FXMLLoader.load(getClass().getResource("2ndwin.fxml"));
Scene scene = new Scene(root);
primaryStage.setTitle("Hello World");
primaryStage.setScene(scene);
primaryStage.show();
Scene scene2 = new Scene(root2);
secondaryStage.setScene(scene2);
}
public void show(){
secondaryStage.show();
}
I've got this. In controller i did this:
Main m = new Main();
m.show();`
but I still don't know how I can close primaryStage.
Please help me or tell me how I can create a new window and close the old window. I think this what I want to do - it isn't correct but I came up with it myself.
I do it by using an object in the stage you want to close to get the window
Window currentStage = OBJECTINSCENE.getScene().getWindow();
(Replace 'OBJECTINSCENE' with the id of anything in your scene). This gives you a reference to the stage you have open. Then call
currentStage.hide();
To close the stage when you want to.
So your show function would be as follows
public void show(){
Window currentStage = OBJECTINSCENE.getScene().getWindow();
secondaryStage.show();
currentStage.hide();
}
I have an undecorated FXML stage. I created a button to minimize window and created an event for it in Controller class in initialize method.
minimizeBtn.setOnAction(e -> {
Stage stage = (Stage)((Button)e.getSource()).getScene().getWindow();
stage.setIconified(true);
System.out.println(stage.isIconified());
});
Problem:
isIconified() returns true, while nothing happens to window visually.
If I switch from UNDECORATED to default my custom button perfectly works.
Same problem for me on both MacOS High Sierra and Mojave, with jdk 11.0.2 and JavaFX 12.0.1
There's the example code to reproduce the issue.
Note that without setting the UNDECORATED style to the stage the problem doesnt' happen.
On Windows the behaviour is correct no matter what the stage style is.
public class DemoApplication extends Application {
#Override
public void start(Stage primaryStage) {
Button minimize = new Button("MINIMIZE");
minimize.setOnAction(event -> primaryStage.setIconified(true));
primaryStage.initStyle(StageStyle.UNDECORATED);
Scene scene = new Scene(new StackPane(minimize));
primaryStage.setTitle("JavaFX App");
primaryStage.setWidth(960);
primaryStage.setHeight(600);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
If I want a scene to be 500 by 500... does that make the stage 550 by 550 or does it make the scene 450 by 450 and the stage 500 by 500? What is the width and length of the extra title bar space above the scene that include the close, restore, and minimize buttons?
No, the extra space on top of a stage is not included in the size of the Scene.
If you want to know the exact size, it is platform dependent. A very simple example to verify is to create a Scene of 500 x 500 and set the Stage at X=0, Y=0 and check the mouse co-ordinates to measure the size.
public class MyStageSize extends Application {
#Override
public void start(Stage stage) {
Label label = new Label();
VBox root = new VBox(label);
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 500, 500);
stage.setScene(scene);
stage.setX(0);
stage.setY(0);
stage.show();
scene.setOnMouseMoved(e -> label.setText(String.valueOf("X = " + e.getScreenX() + "\nY = " + e.getScreenY())));
}
public static void main(String[] args) {
launch(args);
}
}
I have a Text that contains a String of 7 lines. I want to put this Text in a panel width 500 and height 70 This text should smoothly move slowly from the bottom up and play again and again without stopping.
I did the following code.
But the text only once playing and floating movement is done with small jumps rather smoothly.
How I can do smooth motion and play it again and again without ever stop?
public class TextSh extends Application {
#Override
public void start(Stage primaryStage) {
String message =" Here is the text of seven lines";
Text textRef = TextBuilder.create()
.layoutY(100)
.textOrigin(VPos.TOP)
.textAlignment(TextAlignment.CENTER)
.wrappingWidth(400)
.text(message)
/*.fill(Color.rgb(187, 195, 107))*/
.fill(Color.OLIVE)
.font(Font.font("SansSerif", FontWeight.BOLD, 18))
.build();
TranslateTransition transTransition = TranslateTransitionBuilder.create()
.duration(new Duration(75000))
.node(textRef)
.toY(-1640)
.interpolator(Interpolator.LINEAR)
.cycleCount(Timeline.INDEFINITE)
.autoReverse(true)
.build();
StackPane root = new StackPane();
root.getChildren().add(textRef);
StackPane r = new StackPane();
r.getChildren().add(root);
Scene scene = new Scene(r, 500, 70);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
transTransition.play();
}
public static void main(String[] args) {
launch(args);
}
}