I'm trying to add a functionality to my app which changes the language.
I wrote a following controller for this -> https://pastebin.com/n3nXdAx8
I'm having a problem with starting my JavaFx Application, when I run it I get a following error https://hastebin.com/agakacubuv.js
I tried to fix it following this topic Starting JavaFX from Main method of class which doesn't extend Application
It's my Main class https://pastebin.com/6s8iqcUe
try changing
public static Stage stage=new Stage();
to
public static Stage stage;
You initialize the stage in start() method anyway.
Edit
The second thing is that there is no such key as bundles.main.view.application.title (Main:32). try to use main.view.application.title instead.
Related
everyone. I've been searching for this question but I haven't found it here, so I'll guess it's really simple.
I'm creating a very simple application in JavaFX with a single button. Now I want to handle its events (like when it's pressed or when it's released), but when I see examples over the Internet, they all use anonymous classes (and a different class for each event), which makes the code dirty in my opinion. That's why I want to put the event handlers in a separate class and add them to the button.
The problem is that I don't know if I have to create a different class for every event, which I think isn't cool. So I came up with an idea. In the handle() method of the class I check which type of event is going on and process it.
This is the code
Main class
public class Main extends Application{
Button button;
PruebaEventHandler evhandler;
public Main() {
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception{
primaryStage.setTitle("h0i");
button = new Button("Púlsame!");
evhandler = new PruebaEventHandler();
button.addEventHandler(MouseEvent.ANY, evhandler);
StackPane layout = new StackPane();
layout.getChildren().add(button);
Scene scene = new Scene(layout, 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
}
}
EventHandler class
public class PruebaEventHandler implements EventHandler<MouseEvent>{
#Override
public void handle(MouseEvent event){
if(event.getEventType().equals(MouseEvent.MOUSE_PRESSED)){
System.out.printf("Te cogí\n");
}
if(event.getEventType().equals(MouseEvent.MOUSE_RELEASED)){
System.out.printf("\nMe ha soltado!!!");
}
}
}
I don't know if this is very inefficient or bad programming style, but is the only solution I've come up with so far. So I want to ask you if this is a good solution or, if there's a better one, shed your light on me! Thanks beforehand.
There already exists a solution for this, which is creating a JavaFX-project with a FXML-file, Controller and also a Main class. IDEs like IntelliJ and NetBeans have support for letting you create a JavaFX-project, which automatically creates those files for you, but I'm not sure if you have to add a plugin to make it work, that I don't remember.
The FXML-file takes care of the GUI, for example placing a button in a scene, and the easiest way to use it is with a SceneBuilder, which Oracle has, and can also be integrated in your IDE.
If you use FXML you can direct buttons to methods inside your FXML-document, so you don't need to have anonymous classes for event handlers. Instead you make the button call a spesific method in your Controller-class.
Here are a couple of youtube-tutorials that showcase the basics of using JavaFX with FXML:
https://www.youtube.com/watch?v=K7BOH-Ll8_g
https://www.youtube.com/watch?v=LMdjhuYSrqg
Recently I started learning JavaFX and now something is bothering me and I can’t find a solution to my “problem”. I have found similar questions and couple of solutions to problems like mine, but I couldn’t find one that’s working for me or simply I am doing something wrong. What I want to do is to have one main FXML file with its own FXML Controller Class. Then I want to add (import) other FXML files, which also have controllers, in the main FXML. I tried couple of things, but nothing worked, so I decided to describe what I am doing. First I am creating the Main FXML file with Scene Builder and then I am creating the Controller for the Main FXML. Then I am setting in Scene Builder the controller class for the Main FXML to be the Main Controller (of course…). After that I am doing the same for the second FXML. Then I am trying to import the second FXML to the Main FXML and it works fine, if I haven’t set a controller for the second FXML. If I have however selected a controller for the second FXML before importing it to the Main FXML, I am still able to import the FXML file and save it, but after I try to run the program, I am getting an error. So basically what I am trying to do is to have multiple FXML files with their own controllers in one Main FXML file, which also has a Controller Class. I am not exactly sure that this is possible at all, so please tell me is that possible at all, and if it’s possible, what am I doing wrong. This is my code :
public class MainSceneController implements Initializable {
#FXML
private TextField mainTxtField;
public MainSceneController() {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("MainScene.fxml"));
fxmlLoader.setController(this);
fxmlLoader.setRoot(this);
try {
fxmlLoader.load();
} catch (IOException exc) {
} }
#FXML
public void buttonActionMethod(ActionEvent event) {
mainTxtField.setText("Button1 is clicked");
}
#Override
public void initialize(URL location, ResourceBundle resources) {
} }
I called the second FXML and the second controller LeftScene and LeftSceneController, so here is the code for the second controller :
public class LeftSceneController implements Initializable {
#FXML
private TextField leftTxtField;
public LeftSceneController() {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("MainScene.fxml"));
fxmlLoader.setController(this);
fxmlLoader.setRoot(this);
try {
fxmlLoader.load();
} catch (IOException exc) {
}
}
#FXML
public void button2Action(ActionEvent event) {
leftTxtField.setText("Button 2 is clicked");
}
#Override
public void initialize(URL location, ResourceBundle resources) {
} }
And finally, this is the MainClass, in which are the main method and the start method :
public class MainClass extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("MainScene.fxml"));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setTitle("Multiple FXMLs in one");
primaryStage.show();
} }
I hope you are getting what I want to do. As I said, I have tried a lot of things and none of them worked how I wanted it to. This version is compiling and it’s running, if I don’t set a controller class for the second FXML before importing it, but as you can expect, the second button from the imported FXML is not doing anything. I would post screenshots, if I could, but I am new here and usually I am only reading, so I am not allowed to post screenshots. Also I tried to post my FXML code, but I was having problems with the system and I couldn't post more than one line of the code.
So… Is it possible to make this work how I want it to or not?
And also if you read all this mess, thanks at least for your time! :)
It has been a while, but finally I found an answer to my question. I found this video on YouTube and it is showing exactly what I needed. Although I found a couple of problems while I was doing the things from the video step by step.
First of all, if I import another FXML file into the main FXML, like in this tutorial, SceneBuilder is importing the FXML like the things from the imported FXML are in the main FXML and this causes problems. What I mean is for example if you have a Button in the imported FXML, when you import it in the main FXML with SceneBuilder, the imported Button appears in the main FXML like a new Button with all the information for it (postion, onClickMethod, etc.) and that it's not how it's supposed to be. This causes errors, because Java is looking for the onClickMethod for the imported button in the Main Controller and not in the Controller of the imported FXML. I don't know why it's different by me and it is not like in the video, but the solution is simple. If you want to import a FXML file into another FXML, you should do it with an editor and you just have to add the following line in the content of the main FXML :
<fx:include fx:id="importedFXML" source="ImportedFXML.fxml" />
The important thing in this case is that the fx:id should be with the same name as the .FXML file, but with a small first letter.
And the other thing, which was shown in the video and which caused problems by me was if you want to have a multiple imported FXML files and you want them to communicate with each other. The video is showing how to do that, but it is not mentioning that the Controller objects of the imported FXML files, which you have to create in the MainController, must have the same names like the fx:id + the word Controller. For example with the fx:id from above, the object should look like this :
#FXML private ImportedFXMLController importedFXMLController
if the ImportedFXMLController is the controller of the importedFXML
So, I hope that this is going to be helpful to someone.
I want to create a program in Java with a main window, that can open more subprograms in other windows.
I created a simple JavaFX program for the main window, and it works as expected, like so:
public class MainThread extends Application {
#Override
public void start(Stage primaryStage) {
// code goes here...
}
}
... and I created other Java classes the same way.
I tried to run them simply with new SubProgramThread();- as I would create a new instance of any object- but that hasn't worked for me- it doesn't run the start() method in the subprogram classes.
Is that the right way to create an Application instance?
Thanks.
I do this all the time. I have a menu of items. When a user clicks the item button I create the new window by calling start() on the FX class:
new TyAltSvr().start(new Stage());
Some people don't like calling start() but it hasn't caused me any problems.
I recently started playing around with Java FX, FXML, and scene builder, and I've been trying to add key listeners to one of the controllers for a scene. When I do this though, the key listeners don't work as they should, and I figure it's because they're not focused onto that particular scene. I tried to get access to the scene the controller was part of in order to set it directly, but it comes up that it's part of a null scene.
Is there a way to gain access to the scene that this controller is used in in order to try and assign key event and listeners to that particular scene? Should I go through the rootController which is static throughout the whole application? Or, better yet, is there a simpler way of going about this?
Most examples I see assume that everything is mostly together in a main class or separated amongst a couple of other classes without FXML being brought in, and I'm not sure how to apply their fixes when I have the java controllers, FXML pages, and the main application all separated.
Thanks for any help!
Use any of the controls that is bound in the Controller and use getScene() on it.
Remember not to use it in initialize() as the root element(though completely processed) is still not placed on the scene when initialize() is called for the controller
public class WindowMainController implements Initializable {
#FXML
private Button button;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println(button.getScene()); // Gives you the Scene
}
#Override
public void initialize(URL url, ResourceBundle rb) {
System.out.println(button.getScene()); // Prints null
}
}
The problem I'm having is that when I create a new JavaFX project in NetBeans the main method is ignored, and somehow start() is somehow called and everything is just fine, but any time I try to call start I wind up with an exception. The class I used:
public final class JFXDriver extends Application {
public JFXDriver() {
Application.launch();
}
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("GUI.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
}
I've attempted to start it using the constructor, but it fails (Throws an Exception) for some reason saying that it is being called more than once, which should be impossible because I've constructed this class from a main method with only the new JFXDriver(); in it.
You are doing it wrong in the code. You should not call launch in your constructor. You should call it in your main and pass the name of the class that extends Application.
This causes the system to call init and then start and thus begins the lifecycle of your applicaton. For a more detailed explanation have a look here: http://codelatte.wordpress.com/2013/11/15/getting-started-with-javafx-hello-world-2/
Are you attempting a Swing and FX interop ?
Alright, I've found a solution to the problem. I added:
public static void start() {
Application.launch();
}
and took out the call to Application.launch() in the constructor. This approach worked. I guess that the JavaFX thread created its own instance of the class leading to the Application.launch() being called more than once. Interestingly, without the one application limit, I wonder if this would have led to a StackOverflowException due to the recursive nature of the call.