I currently have some code that makes a button in the primaryStage that spawns a new stage. My goal is to have the button close the stage it's on using the setOnMouseClicked method right after launching the new one. Here is how it's currently setup:
#Override
public void start(Stage primaryStage) {
setPlayBtn();
}
private void setPlayBtn() {
play = new ImageView(new Image(BugWars.class.getResourceAsStream("images/play-btn.png")));
play.setFitHeight(50);
play.setFitWidth(50);
play.setX(375);
play.setY(375);
play.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent t) {
setGame(); // This creates the new stage.
primaryStage.close();
}
});
Unfortunately this doesn't work. Netbeans complains that it can't find the symbol. It thinks it's a variable. I'm sure it's something stupid, but any help referencing the primaryStage would be appreciated. Thanks guys!
So I've worked around the problem by simply making the PlayBtn instatiate inside of the start() method that(I believe) creates primaryStage and then making primaryStage final. I don't know why this works, but it does.
Related
I am completly lost atm. I have been working with scenebuilder and javaFX in the past but I am stuck like 5 hours now and I didnt get a step further. Let me explain:
I have a working java Eclipse Project, using maven dependencies
The Main is where I want to use JavaFX or load a fxml into
The programm takes many many VCC Files and extracts the data to put it all together in an excel
The programm works but I cant load a FXML file into the main or even show a pane in there
Now does my Java Main class has to extend Application? I tried both ways - doenst work.
Some example code:
public void start(Stage primaryStage) {
try {
bpmain = new BorderPane(FXMLLoader.load(new File("src\\fxml\\UserInterface.fxml").toURI().toURL()));
primaryStage.setScene(new Scene(bpmain));
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
or this (from original Docs)
public void start(Stage stage) {
Circle circ = new Circle(40, 40, 30);
Group root = new Group(circ);
Scene scene = new Scene(root, 400, 300);
stage.setTitle("My JavaFX Application");
stage.setScene(scene);
stage.show();
}
but this start method is just not getting called... where do I put that?
What my Programm should look like is pretty simple actually. I want a small UI Windows that lets you pick a Folder where the VCC data lives in and a OK Button that basically should run the Main method.
So a TextField that when its picked a Path in the Main gets replaced (filepath) and just a simple OK Button that says: yeah run the main - because the main works perfectly it is just that I cant show that ui and I dont know how to really connect it to the Main.java
Any help is appreciated - Ty
Option 1
public class Launch extends Application {
public static Stage stage = null;
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/fxml/Main.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
this.stage = stage;
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Option 2:
public class SidebarController implements Initializable {
#Override
public void initialize(URL url, ResourceBundle rb) {
}
#FXML
void btnHome_OnMouseClicked(MouseEvent event) throws IOException {
BorderPane borderPane = (BorderPane) ((Node) event.getSource()).getScene().getRoot();
Parent sidebar = FXMLLoader.load(getClass().getResource("/fxml/ContentArea.fxml"));
borderPane.setCenter(sidebar);
}
}
#Override
public void start(Stage primaryStage) {
playerIsSelected = false;
enemyIsSelected = false;
Blockquote Can be compiled, but when I click the EXIT button, it shows that the error as: Exception in thread "JavaFX Application Thread" java.lang.NullPointerException.And the Exit button click doesn't exit the window.
there is nowhere in your code that the identifier stage is defined. However, since your code is compiling I would assume this is defined outside of the method. Though, considering you've invoked primaryStage.show(); then eventually you might want to perform primaryStage.close();.
change this:
public void exit(){
stage.close(); //<-- cause of the NullPointerException
}
to this:
public void exit(){
primaryStage.close();
}
I have a program that uses a simple preloader while the init() method creates the main gui. Everything works fine but after the init() method completes and the preloader disappears, there's a noticeable delay before the main stage shows up. I say noticeable because it can be as much as 7 seconds, enough for a user to get confused.
I tried to put as little as possible in the start() method:
public void start(Stage stage) {
/*Scene*/
scene = new Scene(root, 1200, 700);
stage.setScene(scene);
scene.setFill(null);
/*Stage*/
stage.initStyle(StageStyle.TRANSPARENT);
stage.centerOnScreen();
stage.show();
}
Is there a way to reduce/eliminate this delay? Would it be better to scrap the preloader altogether and implement is as a stage in the main program? Thanks in advance.
EDIT:
I took Maverick283's advice and implemented a fadeOut of the preloader. There was still a bit of delay so I sent the final notification (from the main program to the preloader) after showing the main stage and it worked perfectly!
public void start(Stage stage) {
/*Scene*/
scene = new Scene(root, 1200, 700);
stage.setScene(scene);
scene.setFill(null);
/*Stage*/
stage.initStyle(StageStyle.TRANSPARENT);
stage.centerOnScreen();
stage.show();
notifyPreloader(new Preloader.ProgressNotification(0.99));
}
From Oracle:
The last state change notification received by the preloader before the application starts is StateChangeNotification.Type.BEFORE_START. After it is processed, the application's start() method is called. However, it can take time before the application is ready to display its stage after the start() method is called. If the preloader stage is already hidden, then there could be a period of time when the application shows nothing on the screen.
Thus they provide example code how to fix that:
#Override
public void handleStateChangeNotification(StateChangeNotification evt) {
if (evt.getType() == StateChangeNotification.Type.BEFORE_START) {
if (isEmbedded && stage.isShowing()) {
//fade out, hide stage at the end of animation
FadeTransition ft = new FadeTransition(
Duration.millis(1000), stage.getScene().getRoot());
ft.setFromValue(1.0);
ft.setToValue(0.0);
final Stage s = stage;
EventHandler<ActionEvent> eh = new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
s.hide();
}
};
ft.setOnFinished(eh);
ft.play();
} else {
stage.hide();
}
}
}
If you continue reading there is even a way of sharing the two stages (preloader and main application stage)...
I tried the solution shown before but not worked, then I wrote a code that worked for me, what I did was make the preloader dont be hiden by itself, it just get hided when the main app is shown, look:
On Preload:
I commented the stage.hide();
#Override
public void handleStateChangeNotification(StateChangeNotification scn) {
if (scn.getType() == StateChangeNotification.Type.BEFORE_INIT) {
//stage.hide();
}
}
I set stage as static
static Stage stage;
I added this code:
public static Stage getStage() {
return stage;
}
On main app:
#Override
public void start(Stage stage) throws IOException {
scene = new Scene(loadFXML("fxmlLoginGUI.fxml"), 640, 480);
stage.setScene(scene);
stage.show();
if (stage.showingProperty().get()) {
try {
UkhuluvelaERP_Preloader.getStage().hide();
} catch (Exception ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
I check if the stage is already shown, then I set the preloader stage to hide() using a get method.
I hope this works for you guys as did for me. good luck. chers
I have a Webview (JavaFX 8) that load an article from Wikipedia.
I put a refresh button to allow a refresh, basically, it does another call to the load method of the webEngine of the WebView with the same URL. But about 50% of the time the article is never rendered. In this case, I can right-click on the web view to manually refresh, then it will be rendered successfully.
I tried to look at the LoadWorker state, it always says "SUCCEED"...
Below is a short runnable Test class that demonstrates my point.
public class Test1 extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
final WebView webView = new WebView();
webView.getEngine()
.load("http://fr.wikipedia.org/wiki/Sp%C3%A9cial:Page_au_hasard");
Tab tab = new Tab("webView", webView);
TabPane tabPane = new TabPane(tab);
BorderPane borderPane = new BorderPane(tabPane);
Button buttonRefresh = new Button("Refresh");
buttonRefresh.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
webView.getEngine()
.load("http://fr.wikipedia.org/wiki/Sp%C3%A9cial:Page_au_hasard");
}
});
borderPane.setBottom(buttonRefresh);
Scene scene = new Scene(borderPane);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main (String[] args) {
launch(args);
}
}
Am I doing something wrong? Does anyone know where this problem might come from?
EDIT
I added a few lines to bypass the problem, I check the header in the DOM when the state of the loadWorker becomes SUCCESS. If it is empty, I reload. Now it (looks) 100% ok, but still I am very curious why it didn't simply work all the time first.
Some thoughts that may be useful
The link http://fr.wikipedia.org/wiki/Sp%C3%A9cial:Page_au_hasard redirects to a random article (that's why my refresh button can't use webView.getEngine.reload()).
Putting a ChangeListener on the stateProperty of the workLoader to call the reload method of webEngine actually works. Each page is rendered successfully, but already rendered page will also be re-rendered, which is terrible.
I have to write a method that will do something when the user closes a window. So far I managed to write this code but it does not work (i placed it in my initialize method in my controller) :
Scene scene = myTable.getScene();
Window window = null;
if (scene != null)
{
window = scene.getWindow();
System.out.println("scene is not null");
window.addEventHandler(WindowEvent.WINDOW_HIDDEN, new EventHandler<WindowEvent>
()
{
#Override
public void handle(WindowEvent w)
{
System.out.println("do somethong here");
};
});
Unfortunately Even my message "scene is not null does not get displayed. Does anyone have a better idea on how to do it?
If you want to do something when the user closes the window you should use the setOnCloseRequest() method like this :
window.setOnCloseRequest(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent event) {
//do something
}
});
Now if scene is null then this code won't be executed and nothing will happen, maybe a little System.out.println(scene); before the test would help you debug this issue.
Add a change listener to the scene property of the table, and only add your event handler when the scene is changed to a non-null value.
As recommended by Marc, calling setOnCloseRequest or setOnHidden, is probably a better way to configure your EventHandler.