Switch between scenes in fullscreen mode JavaFX [duplicate] - java

I have read several questions/solutions here that are related to my problems. but nothing seems to work.
so I have a primarystage in fullscreen mode, say if i click a button it changes the scene. but the stage seems to display the taskbar. also I resolved the issue by adding this to all of the scene methods..
stage.setFullScreen(false);
stage.setFullScreen(true);
BUT, the transition in scenes is not that fluid. first it goes to desktop and back to fullscreen.. which is not the ideal solution.
here is my code for the primary stage:
public static Stage stage;
private static AnchorPane mainLayout;
#Override
public void start(Stage primaryStage) throws IOException
{
Main.stage = primaryStage;
Main.stage.setTitle("Raven App");
stage.initStyle(StageStyle.UNDECORATED);
stage.setFullScreen(true);
stage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
Main.showMain();
}
here is my code for changing the scene:
public static void UserLogin() throws IOException
{
FXMLLoader loader=new FXMLLoader();
loader.setLocation(Main.class.getResource("page/UserHomeLogin.fxml"));
mainLayout=loader.load();
Scene scene=new Scene(mainLayout);
stage.setScene(scene);
stage.show();
}
I don't know if this is a bug or something. But i thought if you set your primary stage to full screen. and should be fullscreen all through out regardless of scene.
also, if i have a primary stage in full screen mode.. and a secondary stage NOT in full screen mode. the primary stage seems to disappear if i click a button to show the secondary stage. I wanted to show the secondary page on top of the primary stage, and the primary stage should not be clickable unless the secondary page is closed.
my code for showing the secondary stage:
public static void PasswordVerify() throws IOException
{
Stage stage = new Stage();
Parent root = FXMLLoader.load(Main.class.getResource("page/PassConfirm.fxml"));
stage.setScene(new Scene(root));
stage.setTitle("popup window");
stage.initModality(Modality.APPLICATION_MODAL);
stage.showAndWait();
stage.show();
}

Instead of creating a new scene, just change the root of the existing scene:
public static void UserLogin() throws IOException {
FXMLLoader loader=new FXMLLoader();
loader.setLocation(Main.class.getResource("page/UserHomeLogin.fxml"));
mainLayout=loader.load();
stage.getScene().setRoot(mainLayout);
// or just
// scene.setRoot(mainLayout);
// if you already have a reference to the scene
}
The second thing you are asking is not really possible. In JavaFX, on many platforms "full screen mode" is really implemented as "exclusive screen mode"; so there is a unique window visible. So you would need another solution entirely to this, that didn't involve displaying a new window at all.

Related

Stage blink on load

I need to maximize Stage on load via code.
Here is my code:
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
Parent root = FXMLLoader.load(getClass().getResource("Main.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.setTitle("Контрола трошкова кућног буџета");
primaryStage.setMaximized(true);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
I have all needed imports. Problem is when run it primaryStage blink for a part of second in size created in Scene Builder, then maximize as intended and I want it to show Maximized. It happend in Eclipse and when make runnable JAR and run it with *.bat file.
Is there anything I am doing wrong?
For testing I created small app in WPF it works properly, no blinking.
EDIT: When stage is in normal size and I click Maximize button, it maximizes stage as I want. Is there possibility to write code to simulate or call Maximize button on top of window? Othere way besides
stage.setMaximized(true);
because that line doesn't work well.
Here is a workaround, set the stage's opacity to 0 before showing it so the resizing happens while the stage is not visible, then change it back to 1:
primaryStage.setOpacity(0);
primaryStage.show();
primaryStage.setOpacity(1);

In Javafx when a window is opened how can i set it so that the user isnt able to open the same window again?

I tried a lot but just couldn't find any solution. At the moment the opened window(popup window) is always on top but the user can still access the main window. That's how it should be, but it shouldn't be possible to open the same popup window again.
Stage stage = new Stage();
stage.setTitle(panelTitle);
stage.setScene(new Scene(root));
stage.initModality(Modality.WINDOW_MODAL);
stage.setAlwaysOnTop(true);
stage.showAndWait();
Thank you in advance!
As LazerBanana said, I would disable the button that opens the window, and I would enable it when you close it.
Stage stage = new Stage();
button.setDisable(true);
stage.setTitle(panelTitle);
stage.setScene(new Scene(root));
stage.initModality(Modality.WINDOW_MODAL);
stage.setAlwaysOnTop(true);
stage.showAndWait();
// your logic here
button.setDisable(false);
An alternative solution to creating a new one each time is to create one and just setup and show.
public class Stack extends Application {
private final Stage popup = new Stage();
#Override
public void start(Stage stage) throws Exception {
BorderPane root = new BorderPane();
root.setPrefWidth(400);
root.setPrefHeight(200);
Button button = new Button("ClickMePopup");
root.setCenter(button);
button.setOnAction(
event -> {
if (!popup.isShowing()) {
// you dont set modality because after the stage is set to visible second time it will throw an exception.
// Again depends on what you need.
// popup.initModality(Modality.WINDOW_MODAL);
// this focuses the popup and main window is not clickable
// popup.initOwner(stage);
VBox dialogVbox = new VBox(20);
dialogVbox.getChildren().add(new Text("Some Dialog"));
Scene dialogScene = new Scene(dialogVbox, 300, 200);
popup.setScene(dialogScene);
// you can actually put all above into the method called initPopup() or whatever, do it once, and just show it here or just bind the property to the button.
popup.show();
}
});
Scene scene = new Scene(root);
stage.setTitle("Stack");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Or disable the button when clicked, but if your popup is not driven by the button or can be opened from other places the first idea would be a bit better in my opinion. Depends on what you need.
Or just create your own class and Springify it.

Start the application window maximized in JavaFX FXML not working properly

I want my Javafx FXML application to start maximized so I used the method setMaximized(true) in my stage.
The program opens as Maximized no problem on that, but the problem is that there is a small black area that flashes for half a second on the application startup just before the window appears.
Here's a recording (gif) of what I describe:
I figured out that the problem is with the scene as it is trying to open in its prefWidth & prefHeight then it scales up to fit the stage.
How can I fix this and make the program start as normal programs do?
here's my start() method:
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("editor.fxml"));
primaryStage.setTitle("Simple Text Editor");
primaryStage.setScene((new Scene(root)));
primaryStage.setMaximized(true);
primaryStage.show();
}
The only workaround I found is this:
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("editor.fxml"));
primaryStage.setTitle("Simple Text Editor");
primaryStage.setScene(new Scene(root));
primaryStage.setMinWidth(450);
primaryStage.setMinHeight(300);
Screen screen = Screen.getPrimary();
Rectangle2D bounds = screen.getVisualBounds();
primaryStage.setWidth(bounds.getWidth());
primaryStage.setHeight(bounds.getHeight());
primaryStage.setMaximized(true);
primaryStage.show();
}

Parent Stage hidden on switching to the 3rd party window and again switching to Application Stage

My parent stage "stage1" is opening child stage "stage2" and i have set child stage's modality as below.
stage2.initModality(Modality.APPLICATION_MODAL);
Now when i open stage2 from stage1, stage1 is appears behind stage2 that is expected, but when i press "Ctrl+Tab" key, control switches to 3rd paty applicaton for example "Outlook", then I again press "Ctrl+Tab" key, it returns to our main applicaton and it shows stage2 but stage1 appears hidden. My expectation is that stage1 should be hidden behind stage2.
Any help is greatly appriciated.
It is because Stage2.getOwner() == null is true. Your expectation is the way it works, when it is false. so to solve your problem do this
Stage2.initOwner(Stage1);
ediit
here is some demo
#Override
public void start(Stage stage) {
Pane p = new Pane();
p.setStyle("-fx-background-color: red");
stage.setTitle("I AM THE PARENT");
Scene scene = new Scene(p);
stage.setWidth(600);
stage.setHeight(600);
stage.setScene(scene);
stage.show();
Stage s = new Stage(StageStyle.DECORATED);
s.initModality(Modality.APPLICATION_MODAL);
p = new Pane();
p.setStyle("-fx-background-color: yellow");
s.setScene(new Scene(p,150,150));
//s.initOwner(stage); //with this commented it wont work
s.show();
}
Also you will notice that when your press CTRL + TAB the windows popup only shows your second window STAGE2, that is who he knows of, because its has not parent, but when it has owner is shows only the owner

JavaFX - Adding a ScrollPane popup which closes when user clicks out of it

My title is badly worded because my problem is very hard to describe, so I drew an image for it:
I have an ImageView object which represents a pile of cards (not poker cards but just used them as an example). When this image view is clicked, I need a window to popup that features a ScrollPane and shows them all the card objects that are in the linked list. When the user clicks anywhere outside of the window (and later on, any right mouse button click) the scrollpane window needs to close.
Ways that I have already tried:
Scene with APPLICATION_MODAL. Then did Scene.showAndWait(). I didn't like this method because it made another application on the user's taskbar. It also felt clunky and just bad.
Changed my root pane to a StackPane, then added this Scrollpane to the stackpane when the user clicked on the deck. This for some reason was really slow and seemed really obtrusive. It was also annoying because my alternate class needed to have access to the root pane (since when it closes, it needs to go to the root StackPane and call .remove() on itself).
Are there any other better ways to accomplish this? My application is going to have many of these piles and so this framework needs to work very well.
I would still propose to open a new Stage with some restrictions to solve your issues with this approach.
You can use the initOwner property of the Stage to have another Stage as owner, therefore no other icon will appear on the taskbar.
You can use the initStyle property with TRANSPARENT or UNDECORATED StageStlye, this will ensure that only the content is visible.
And in the end you can use the focusedProperty to check whether the Stage lost focus to close it.
Example
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);
Button b = new Button("Open deck");
b.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Stage popupStage = new Stage();
popupStage.initOwner(primaryStage);
popupStage.initStyle(StageStyle.UNDECORATED);
Scene sc = new Scene(new ScrollPane(), 300, 300);
popupStage.setScene(sc);
popupStage.focusedProperty().addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue,
Boolean newValue) {
if(!newValue)
popupStage.close();
}
});
popupStage.show();
}
});
root.setCenter(b);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
It is also possible of course to not open it in a new Stage, but draw a ScrollPane inside the current Stage which overlaps the content of the Stage using for example an AnchorPane or Group as root, but the first solution has the advantage that you are not bound to the dimensions of main Stage (the popup can have any size that you want).
You can achieve this with a low level system hook that catches the mouse events.
http://kra.lc/blog/2016/02/java-global-system-hook/ or https://github.com/kwhat/jnativehook/releases
I hope that is what you needed, otherwise i got your question wrong.

Categories

Resources