JavaFX FullScreen Mode not working - java

I have a basic JavaFX application, that opens as so
public class MyApplication extends Application {
private Stage stage;
public static void main(String[] args) {
Console.setDebug();
launch(args);
}
#Override
public void start(Stage primaryStage) {
// set stage as primary
stage = primaryStage;
stage.setFullscreen(true);
stage.show();
stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
public void handle(WindowEvent we) {
System.out.println("Closing application...");
}
});
}
}
Now to change screens i have this function, which i call
private void replaceScene(String resource, IControlledScreen controller) {
try {
controller.setApp(this);
FXMLLoader loader = new FXMLLoader(getClass().getResource(resource));
loader.setController(controller);
Pane screen = (Pane) loader.load();
Scene scene = new Scene(screen);
stage.setScene(scene);
stage.setFullscreen(true);
} catch (Exception e) {
System.out.println("Cannot load resource " + resource);
System.out.println(e.getMessage());
}
}
Example call would be
public void goToHome() {
replaceScene("/fxml/HomeView.fxml", new HomeController());
}
Now when i run the application, the first screen is in fullscreen mode, then when i change screens, the screen resizes to window size, then changes again to full screen??? I have tried adding
stage.setFullscreen(false);
before i call
stage.setFullscreen(true);
but this does work either. How can i change screens/scenes without it resizing?
Also is is possible to toggle full screen mode using code, say if i want the user to be able to select full screen mode, can this be done?

This is the solution:
private void replaceScene(String resource, IControlledScreen controller) {
try {
controller.setApp(this);
FXMLLoader loader = new FXMLLoader(getClass().getResource(resource));
loader.setController(controller);
Pane screen = (Pane) loader.load();
stage.getScene().setRoot(screen);
} catch (Exception e) {
System.out.println("Cannot load resource " + resource);
System.out.println(e.getMessage());
}
}

Thanks to Mailkov for his code, nearly worked, but had to change it slightly, to cope with the first screen loading. This now works using
private void replaceScene(String resource, IControlledScreen controller) {
try {
controller.setApp(this);
FXMLLoader loader = new FXMLLoader(getClass().getResource(resource));
loader.setController(controller);
Pane screen = (Pane) loader.load();
if (stage.getScene() == null) {
Scene scene = new Scene(screen);
stage.setScene(scene);
} else {
stage.getScene().setRoot(screen);
}
} catch (Exception e) {
System.out.println("Cannot load resource " + resource);
System.out.println(e.getMessage());
}
}

Related

Stage is showing to be null in javafx

This method(abc) is called when a button is pressed in the first scene. What it does is it changes the scene to waitingScreen and calls another method waitscr()
public void abc(ActionEvent event)throws Exception{
stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
//for changing the scene.
Parent administrator =
FXMLLoader.load(getClass().getResource("waitingScreen.fxml"));
stage.setScene(new Scene(administrator));
stage.show();
conn.close();
waiting_screen_Controller c = new waiting_screen_Controller();
c.waitscr(event);
What waitscr does is it starts a timer for 5 seconds and when the timer ends
it calls another method setscr() (maybe i could have started the timer in abc only)
public void waitscr(ActionEvent event)throws IOException{
timetask = new TimerTask(){
#Override
public void run() {
if(!timing){
try{
timetask.cancel();
setscr(event);
}
catch(Exception ex){
ex.printStackTrace();
}
}
else
timing = updateTime();
}
};
timer.scheduleAtFixedRate(timetask,1000,1000);
}
it updates the time
public boolean updateTime(){
System.out.println(s);
if(s==0){
return false;
}
s--;
return true;
}
what setscr does is it changes the scene back to the first one..
public void setscr(ActionEvent event)throws IOException{
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("first.fxml"));
Parent parent = loader.load();
Scene s=new Scene(parent);
stage = (Stage)((Node) event.getSource()).getScene().getWindow();
System.out.print(event.getSource());
stage.setScene(s);
stage.show();
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
}
But the problem is it gives npe in stage.
java.lang.NullPointerException
at sample.waiting_screen_Controller.setscr(waiting_screen_Controller.java:106)
at sample.waiting_screen_Controller$1.run(waiting_screen_Controller.java:45)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
I thought this was because of ActionEvent because npe is at stage but i printed the source of ActionEvent and it is not null.
You're replacing the scene before calling waitscr. This way when you call Scene.getWindow the scene is no longer associated with a window and the result is null.
You shouldn't do this from a non-application thread anyways.
By retrieving the window only once and using a Platform.runLater you should be able to fix this issue:
public void abc(ActionEvent event)throws Exception{
stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
...
c.waitscr(stage);
public void waitscr(final Stage stage) throws IOException {
timetask = new TimerTask(){
#Override
public void run() {
if(!timing){
try{
timetask.cancel();
setscr(stage);
} catch(Exception ex){
ex.printStackTrace();
}
}
else
timing = updateTime();
}
};
timer.scheduleAtFixedRate(timetask,1000,1000);
}
public void setscr(Stage stage)throws IOException{
// there seems to be a try missing somewhere
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("first.fxml"));
Parent parent = loader.load();
Scene s=new Scene(parent);
Platform.runLater(() -> {
// scene update on javafx application thread
stage.setScene(s);
stage.show();
});
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
}

How to reset a selected path from file chooser in JavaFx

I have a reset and Draw button on a slide panel. I choose a desired file from file chooser, which is in RootLayout class, and pass the file path to a controller class. Then it does some processes and initializes field in DataCunstructor class. By clicking on Draw a TreeTableView will be shown on slide pane, which is in MainController class. When I click my reset button the table will be cleared but I do not know how to reset the chosen path. After reseting if I click Draw again the same treetable comes up. and If I choose another file and hit Draw, the program breaks.
How can I reset all fields including the path to null, and be able to choose another file and process that one?
Here is my Draw and Reset in MainController class:
public void treeTableDraw(ActionEvent event) {
drawTable();//creates the TreeTableView
numberOfFunctions= dc.getFuncAll().size();
numberOfOrganizations = dc.getSortedAssignedOrg().size();
funcLabel.setText(numberOfFunctions+"");//set Lable value
orgLabel.setText(numberOfOrganizations + "");//set Lable value
}
public void treeTableReset(ActionEvent event){
funcLabel.setText("0");//reset Label
orgLabel.setText("0");
treeTable.getColumns().clear(); //clears columns (TreeTable)
///////////////////////////////////////
//non of the following did the path reset//
///////////////////////////////////////
//dc = new DataConstructor();
//Controller controller = new Controller();
//controller.setPath(null);
RootLayoutController rlc = loader.getController();
rlc.reset();
}
My File Chooser in RootLayout class:
#FXML
private void handleOpen() {
FileChooser fileChooser = new FileChooser();
// Set extension filter
FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter(
"3lgm2 files (*.z3lgm)", "*z3lgm");
fileChooser.getExtensionFilters().add(extFilter);
// Show save file dialog
File file = fileChooser.showOpenDialog(main.getPrimaryStage());
path = file.toString();
if (path != null) {
new Controller(path);
}
}
public void reset(){
path = null;
}
I add OverView at the center of rootlayout here at main class:
public class Main extends Application {
private Stage primaryStage;
private BorderPane rootLayout;
//private ObservableList<DataConstructor> treeTableData = FXCollections.observableArrayList();
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("IT-Saturation");
initRootLayout();
showOverView();
}
private void showOverView() {
try{
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("/view/OverView.fxml"));
AnchorPane overView = (AnchorPane) loader.load();
rootLayout.setCenter(overView);
}catch(IOException e){
e.printStackTrace();
}
}
private void initRootLayout() {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("/view/RootLayout.fxml"));
rootLayout = (BorderPane) loader.load();
//show scene containing the root layout
Scene scene = new Scene(rootLayout);
scene.getStylesheets().add(
getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
//gives controller access to main app
RootLayoutController controller = loader.getController();
controller.setMainApp(this);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
File file = getFilePath();
if (file != null) {
loadDataFromFile(file);
}
}
/**
* Returns the main stage.
* #return primaryStage
*/
public Stage getPrimaryStage() {
return primaryStage;
}
public static void main(String[] args) {
launch(args);
}
}
Just declare a reset() in your RootLayout class:
public class RootLayout {
private Path path;
#FXML
private void handleOpen() {
...
path = file.toString();
}
public void reset() {
path= null;
}
}
Never construct the constructor using the keyword new, always get it from the FXMLLoader.
public class MainController {
...
RootLayoutController controller = loader.getController();
controller.reset();
...
}

How to rerun a program in JavaFX

I have 2 controller for 2 fxml files. In one controller I have a handleOpen function which opens a file chooser and gives the path to a Class which I have called model. Then on the other controller a function, treeTableDraw gets this path, after clicking on Draw Button and runs the program. I have Another Button to reset the program. It sets the result back to null, but when open another file to run, the program crashes, because the path is null. How can I reset the program and make it use the new path which is selected from open file chooser?
//Gets the path from model and runs the program
public void treeTableDraw(ActionEvent event) {
new Controller(model.getText());
drawTable();
numberOfFunctions = dc.getFuncAll().size();
numberOfOrganizations = dc.getSortedAssignedOrg().size();
funcLabel.setText(numberOfFunctions + "");
orgLabel.setText(numberOfOrganizations + "");
btnDraw.setDisable(true);
}
/**
* Clrears TreeTableView and sets back labels
*
* #param event
*/
public void treeTableReset(ActionEvent event) {
btnDraw.setDisable(false);
model.setText(null);
funcLabel.setText("0");
orgLabel.setText("0");
treeTable.getColumns().clear();
}
This is RootLayout class which has open file function:
#FXML
private void handleOpen() {
FileChooser fileChooser = new FileChooser();
// Set extension filter
FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter(
"3lgm2 files (*.z3lgm)", "*z3lgm");
fileChooser.getExtensionFilters().add(extFilter);
// Show open file dialog
File file = fileChooser.showOpenDialog(main.getPrimaryStage());
if (file != null) {
path = file.toString();
model.setText(path);
}
}
Here is the model class
public class Model {
private final StringProperty text = new SimpleStringProperty();
public StringProperty textProperty() {
return text;
}
public final String getText() {
return textProperty().get();
}
public final void setText(String text) {
textProperty().set(text);
}
}
This is the main, where I combine two fxmls and set stage:
public class Main extends Application {
private Stage primaryStage;
private BorderPane rootLayout;
private Model model = new Model();
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("IT-Saturation");
initRootLayout();
showOverView();
}
private void showOverView() {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("/view/OverView.fxml"));
loader.setController(new OverViewController(model));
AnchorPane overView = (AnchorPane) loader.load();
rootLayout.setCenter(overView);
} catch (IOException e) {
e.printStackTrace();
}
}
private void initRootLayout() {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("/view/RootLayout.fxml"));
loader.setController(new RootLayoutController(model));
rootLayout = (BorderPane) loader.load();
// show scene containing the root layout
Scene scene = new Scene(rootLayout);
scene.getStylesheets().add(
getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
// gives controller access to main
RootLayoutController controller = loader.getController();
controller.setMainApp(this);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Returns the main stage.
*
* #return primaryStage
*/
public Stage getPrimaryStage() {
return primaryStage;
}
public static void main(String[] args) {
launch(args);
}
public void showMostComputerizedStatistics() {
try {
// Load the fxml file and create a new stage for the popup.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class
.getResource("view/BirthdayStatistics.fxml"));
AnchorPane page = (AnchorPane) loader.load();
Stage dialogStage = new Stage();
dialogStage.setTitle("Birthday Statistics");
dialogStage.initModality(Modality.WINDOW_MODAL);
dialogStage.initOwner(primaryStage);
Scene scene = new Scene(page);
dialogStage.setScene(scene);
// Set the persons into the controller.
MostComputerizedController controller = loader.getController();
dialogStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The problem was not the path. I had to reset the data which got initialized at the the former run of program. So after setting path to null I just newed the instance of class which had reference to data.
...
public void treeTableReset(ActionEvent event) {
btnDraw.setDisable(false);
//model.setText(null);
funcLabel.setText("0");
orgLabel.setText("0");
treeTable.getColumns().clear();
dc = new DataConstructor();
}

change scene onEndOfMedia

is there a way to change the scene by setOnEndOfMedia in javafx ? .. i tried this but it's throwing a NullPointerException
void change(Event event){
try{
Node node=(Node) event.getSource();
Stage stage=(Stage) node.getScene().getWindow();
Parent root = FXMLLoader.load(getClass().getClassLoader().getResource("astrolabe/astrolabe_intro.fxml"));/* Exception */
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setFullScreenExitHint("");
stage.show();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
and calling change() on end of media like this
astrolabe_intro.setOnEndOfMedia(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("tewst");
Event e = new Event(null) ;
e.fireEvent(astrolabe_intro1, e);
change( e);
}
});
If the exception is coming from the FXMLLoader.load(...) line, the chances are that the path to the fxml file is wrong. Log the value of the URL you get from the call to getResource(...) to check.
But also:
Why do you need the event at all? The only place you use it in the change method is to get a node and get hold of the window. You presumably have other references to some nodes (I'm assuming this is a controller.) Why not just do
void change(){
try{
Node node= ... ;// any node in your scene will do....
Stage stage=(Stage) node.getScene().getWindow();
Parent root = FXMLLoader.load(getClass().getClassLoader().getResource("astrolabe/astrolabe_intro.fxml"));/* Exception */
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setFullScreenExitHint("");
stage.show();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
and then
astrolabe_intro.setOnEndOfMedia(new Runnable() {
#Override
public void run() {
change();
}
});
which in Java 8 you can abbreviate to
astrolabe_intro.setOnEndOfMedia(this::change);

JavaFX Application returning NullPointerException when other Scene is called (just sometimes)

My application has a Login Scene and a Main View Scene, what is happening is when I do my login and MainView is called SOMETIMES I get this exception:
java.lang.NullPointerException
at javafx.scene.Scene.focusInitial(Scene.java:1879)
at javafx.scene.Scene.access$3600(Scene.java:170)
at javafx.scene.Scene$ScenePulseListener.focusCleanup(Scene.java:2181)
at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2221)
at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:363)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:460)
at com.sun.javafx.tk.quantum.QuantumToolkit$9.run(QuantumToolkit.java:329)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:73)
at java.lang.Thread.run(Thread.java:722)
The curious is it doesn't happening always, just sometimes.
My class:
public class TargetAppDesktop extends Application {
#Override
public void start(Stage primaryStage) throws IOException {
Scene scene = new Scene(new AnchorPane());
LoginManager loginManager = new LoginManager(scene);
loginManager.showLoginScreen();
primaryStage.setResizable(false);
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent t) {
MainViewController.deleteTempFiles();
Platform.exit();
System.exit(0);
}
});
}
public static void main(String[] args) {
launch(args);
}
}
MY LOGIN MANAGER CLASS
public class LoginManager {
private Scene scene;
LoginManager(Scene scene) {
this.scene = scene;
}
public void logout() {
showLoginScreen();
}
void showLoginScreen() {
try {
FXMLLoader loader = new FXMLLoader(
getClass().getResource("Login.fxml"));
// scene.getStylesheets().add(this.getClass().getResource("Login.css").toExternalForm());
scene.setRoot((Parent) loader.load());
LoginController controller =
loader.<LoginController>getController();
controller.initManager(this);
} catch (IOException ex) {
Logger.getLogger(LoginManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
void showMainViewScreen(Login loginTargetApp, Login loginGateway, Gateway gateway, File file, ArrayList<Integer> anoList) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("MainView.fxml"));
scene.setRoot((Parent) loader.load());
MainViewController controller = loader.<MainViewController>getController();
controller.initSessionID(this, scene, loginTargetApp, loginGateway, gateway, file, anoList);
} catch (Exception ex) {
Logger.getLogger(LoginManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
void autheticated(Login loginTargetApp, Login loginGateway, Gateway gateway, File file, ArrayList<Integer> anoList) {
showMainViewScreen(loginTargetApp, loginGateway, gateway, file, anoList);
}
}
This problem was ocurring because I was trying to change my scene in another Thread, but it must to be changed in a Javafx Main Thread, so a simple Platform.runLater solved my problem.
More detail you can find here. (JIRA link)

Categories

Resources