I am experimenting with FXML. Here is the java file. It resides in /Users/morrison/teaching/java/xml and all files have read permission.
import javafx.application.Application;
import javafx.application.Platform;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.Parent;
import javafx.fxml.FXMLLoader;
import java.io.IOException;
import java.io.File;
import java.net.URL;
public class Example extends Application
{
private Stage primary;
#Override
public void start(Stage primary)
{
this.primary = primary;
Parent root = null;
try
{
File f = new File("/Users/morrison/teaching/java/xml/");
FXMLLoader loader = new FXMLLoader(f.toURI().toURL());
System.out.println(loader.getLocation());
root = loader.load(getClass().getResource("Example.fxml"));
primary.setScene(new Scene(root, 500, 500));
primary.setTitle("FXML Example");
primary.show();
}
catch(IOException ex){System.err.println("file cant be found");}
}
}
Here is the .fxml file, which resides in the same directory.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.canvas.Canvas?>
<BorderPane xmlns:fx="http://javafx.com/fxml">
<top>
<HBox>
<Button text="Go!" onAction="#handleGo" fx:id="goButton"/>
<Button text="Stop!" onAction="#handleStop" fx:id="stopButton"/>
</HBox>
</top>
<center>
<canvas fx:id="colorField">
</canvas>
</center>
</BorderPane>
When I run this, I am being told the FXML file can't be found.
Is there some other piece I am missing?
Related
Using the FXML project template in netbeans, I've been experiencing an issue with defining the FX controller in my FXML file.
The main class, fxml document and fxml controller are all in the same package: "login".
I am importing the controller into the fxml document using it's fully qualified name.
Error occurs at the import line: "Class login.MyController does not exist."
FXML Document
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.shape.Polygon?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>
<?import login.MyController?>
<VBox prefHeight="400.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="login.MyController">
<children>
<AnchorPane maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" style="-fx-background-color: #091D34;" VBox.vgrow="ALWAYS">
<children>
<Polygon fill="#000000b1" layoutX="363.0" layoutY="103.0" points="-50.0, 40.0, 50.0, 40.0, 50.0, -73.0" stroke="BLACK" strokeType="INSIDE" style="-fx-fill: #133863;" />
<ButtonBar layoutX="233.0" layoutY="256.0" prefHeight="40.0" prefWidth="161.0">
<buttons>
<Button layoutX="135.0" layoutY="18.0" minWidth="49.0" mnemonicParsing="false" prefHeight="25.0" text="Login" onAction="#doLogin" />
<Button layoutX="165.0" layoutY="18.0" mnemonicParsing="false" text="About" />
</buttons>
</ButtonBar>
<PasswordField layoutX="186.0" layoutY="216.0" prefHeight="25.0" prefWidth="273.0" promptText="Password" onKeyPressed="#onEnter" />
<TextField layoutX="186.0" layoutY="175.0" prefHeight="25.0" prefWidth="273.0" promptText="Username" />
<Text layoutX="253.0" layoutY="76.0" strokeType="OUTSIDE" strokeWidth="0.0" style="-fx-fill: #236AB9;" text="Anatomy Law" textAlignment="CENTER" wrappingWidth="120.58984375">
<font>
<Font name="Aparajita" size="22.0" />
</font>
</Text>
</children>
</AnchorPane>
Controller
package login;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
public class MyController implements Initializable {
#FXML
public void doLogin(Event e){
System.out.println("do login called");
}
#FXML
public void onEnter(KeyEvent ke){
if(ke.getCode() == KeyCode.ENTER){
System.out.println("on enter called");
login();
}
}
private void login(){
}
#Override
public void initialize(URL location, ResourceBundle resources) {
}
}
Main
package login;
import java.net.URL;
import javafx.application.Application;
import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage stage) throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader();
MyController fxmlController = new MyController();
fxmlLoader.setController(fxmlController);
fxmlLoader.setLocation(new URL("C:/.../login/Login.fxml"));
VBox vbox = fxmlLoader.<VBox>load();
Scene scene = new Scene(vbox);
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Note
I recently tried the following line in my FXML document:
<?import login.*?>
Which resulted in "package login does not exist."
And
<?import MyController?>
Which resulted in class does not exist.
So i'm assuming it's some kind of build path error but they're all in the same package. I even added the package that they're in to additional source packages to build from just to make sure but that didn't solve anything. My project layout is the following:
Project Name
Source Packages
login
Login.fxml
MyController.java
Main.java
I reviewed the other question postings for this problem but no one seemed to have this specific problem. If I did however miss someone's post with an identical answer, I will gladly take that reference.
You don't have to import it. You have to specify the full name of your controller class though.
In your case it is login.MyController so fx:controller="login.MyController".
Though you might have some other problems because I'm not having any issues when i put that import statement in the fxml. It just isn't necessary.
Make sure that the document you are editing is definitely the document in your package.
Somehow, in my case I was actually editing a document outside of the package with the same exact name. This is why it couldn't find the controller class when I tried to import it.
i have created a web view in javafx and loaded a webpage in it. The webpage contain and image which is generated randomly from the server. Once the page is loaded i try to run the javascript to get the url of the image and try to apply it to image viewer but the url makes another request to server for another image and it render different image but i want the same image which is loaded first on the webview. i do not want my web viewer should request to another image and render it.
First.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.*?>
<?import javafx.scene.web.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="com.jb.FirstController">
<children>
<SplitPane dividerPositions="0.3732638888888889" layoutX="10.0" layoutY="3.0" prefHeight="372.0" prefWidth="578.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<WebView fx:id="webview" layoutX="6.0" layoutY="10.0" prefHeight="346.0" prefWidth="200.0" />
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<ImageView fx:id="imageview" fitHeight="311.0" fitWidth="256.0" layoutX="23.0" layoutY="23.0" pickOnBounds="true" preserveRatio="true" />
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
FirstController.java
package com.jb;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.ImageViewBuilder;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
/**
* FXML Controller class
*
* #author admin
*/
public class FirstController implements Initializable {
#FXML
WebView webview;
#FXML
ImageView imageview;
private WebEngine webengine;
#Override
public void initialize(URL url, ResourceBundle rb) {
webengine = webview.getEngine();
//once the page is loaded this event occures
webengine.getLoadWorker().stateProperty().addListener((obs,oldValue,newValue) -> {
//if page loaded successfully
if(newValue==Worker.State.SUCCEEDED)
{
//executing script to get the image src from webview
String img=(String)webengine.getDocument().getElementById("addimage").getAttribute("src");
System.out.println("img:"+img);
//img variable has the value 'http://localhost:8080/WebApplication10/getNewAddImage'
//'getNewAddImage' is a servlet which accept get request
//this servlet gives a random image from backend
//setting the url in image view
imageview.setImage(new Image(img));
}
});
//requesting to index.jsp to load in webview
webengine.load("http://localhost:8080/WebApplication10/index.jsp");
}
}
Test.java
package com.jb;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
/**
*
* #author admin
*/
public class Test extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("First.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
i need to load the same image which is first loaded in the webview
i do not won't to request to new image
Any help would be appreciated
Thanks
Hello everyone i am learning javafx and i am having issue to run simple basic program of hello world i know that javafx works in MVC type structure which fxml,mainclass, and controller so what i am doing is i just created the first program in JavaFX in which 3 things were there a HelloWorld.Java , HelloWorld.fxml and HelloWorldController.java and creating a com.bean package for HelloWorld.java and com.gui for HelloWorld.fxml and com.controller for HelloWorldController.java but i am facing an issue while i am running it it shows an exception that fxml is not loaded a location is required.....please help i also bild and cleaned it many time but not working.....
HelloWorld.java
package com.bean;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* #author Love Poet
*/
public class HelloWorld extends Application{
#Override
public void start(Stage stage) throws Exception {
Parent root=FXMLLoader.load(this.getClass().getResource("com/gui/HelloWorld.fxml"));
Scene scene=new Scene(root);
stage.setTitle("Hellow World Example");
stage.setScene(scene);
stage.show();
}
public static void main(String args[])
{
launch(args);
}
}
HelloWorldController.java
package com.controller;
/**
* Sample Skeleton for 'HelloWorld.fxml' Controller Class
*/
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
public class HelloWorldController implements Initializable{
#FXML // fx:id="button"
private Button button; // Value injected by FXMLLoader
#FXML // fx:id="label"
private Label label; // Value injected by FXMLLoader
#FXML
void handleButtonAction(ActionEvent event) {
label.setText("Hello World !");
}
#Override
public void initialize(URL url, ResourceBundle rb) {
}
}
HelloWorld.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import com.controller.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="HelloWorldController">
<children>
<Button fx:id="button" layoutX="47.0" layoutY="129.0" onAction="#handleButtonAction" prefHeight="25.0" prefWidth="211.0" text="Click Me!" />
<Label fx:id="label" layoutX="35.0" layoutY="35.0" minHeight="16" minWidth="69" prefHeight="45.0" prefWidth="274.0" />
</children>
</AnchorPane>
for this i am using netbeans my structure of doing this is :-
This is an image of netbeans project structure
You're using a class in the com.bean to get the resource, which means using the relative path com/gui/HelloWorld.fxml creates a url that would point to the HelloWorld.fxml in the com.bean.com.gui package.
In this case you either need to use the ClassLoader with the same relative path:
this.getClass().getClassLoader().getResource("com/gui/HelloWorld.fxml")
or use a path relative to the classpath root
this.getClass().getResource("/com/gui/HelloWorld.fxml")
my first fxml (button) :
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<StackPane xmlns:fx="http://javafx.com/fxml" fx:controller="fxml_grid_test.fxml_gridtest_controller" >
<Button fx:id="insertBut" text="insert" onMouseClicked="#insertData"/>
</StackPane>
my second fxml (gridpane) :
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<BorderPane xmlns:fx="http://javafx.com/fxml" fx:controller="fxml_grid_test.fxml_gridtest_controller">
<top>
<GridPane fx:id="gpane">
</GridPane>
</top>
</BorderPane>
my controller :
package fxml_grid_test;
import java.io.IOException;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class fxml_gridtest_controller extends Application {
#FXML private Button insertBut;
#FXML private GridPane gpane;
#FXML private void insertData() throws IOException{
gpane.add(new Label("test"), 0, 0);
Stage primaryStage = new Stage();
Parent root = FXMLLoader.load(getClass().getResource("grid_fxml.fxml"));
Scene scene = new Scene(root, 500, 350);
primaryStage.setScene(scene);
primaryStage.show();
}
#Override
public void start(Stage primaryStage) throws Exception {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
my main :
package fxml_grid_test;
import java.io.IOException;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Fxml_grid_test extends Application {
#Override
public void start(Stage primaryStage) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("button_fxml.fxml"));
Scene scene = new Scene(root, 300, 275);
primaryStage.setTitle("insert data test");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
the idea is :
when i pressed the button, i want to insert some data to my gridpane , and then show the fxml.
both of my fxml share the controller, i feel this is the root of the problem, but i dont know how to solve it.
Controllers are compiled class that implement the "code behind" the object hierarchy defined by the fxml. These are useful to define methods which manipulate the UI elements and can be called by other classes, if necessary.
In your case, we need to define a controller for the grid.fxml because we want to create a method which will be responsible for adding elements to the grid.This method will be called in the MainController, which is responsible for loading grid.fxml and updating it.
FXMLLoader helps us to get an instance of the controller which is being referenced in the fxml.
So, you can have two different controllers for each of your fxml file. For the fxml with button, lets call the controller as ParentController since it is responsible for loading the sencond fxml.
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
public class ParentController implements Initializable {
#FXML
private Button insertButton;
#Override
public void initialize(URL location, ResourceBundle resources) {
}
#FXML
private void insertData() throws IOException {
Stage newStage = new Stage();
FXMLLoader loader = new FXMLLoader(getClass().getResource("gridpane.fxml"));
Parent root = loader.load();
//Get controller instance from the FXMLLoader
GridPaneController controller = loader.getController();
controller.updateGridPane();
Scene scene = new Scene(root, 500, 350);
newStage.setScene(scene);
newStage.show();
}
}
As you can see, we are fetching the controller instance and then trying to call a method in the GridPaneController class.
GridPaneController controller = loader.getController();
controller.updateGridPane();
This updateGridPane() contains the logic for updating your GridPane, if you need something to be set on the GridPane, you can include parameters to the method and use them.
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import java.net.URL;
import java.util.ResourceBundle;
public class GridPaneController implements Initializable {
#FXML private GridPane gpane;
public void updateGridPane() {
Label newLabel = new Label("test");
gpane.add(newLabel, 0, 0);
}
#Override
public void initialize(URL location, ResourceBundle resources) {
}
}
The FXML does nothing special, it just have different controllers.
grid.fxml
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.GridPane?>
<BorderPane xmlns:fx="http://javafx.com/fxml" fx:controller="fxml_grid_test.GridPaneController">
<top>
<GridPane fx:id="gpane">
</GridPane>
</top>
</BorderPane>
main.fxml
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.StackPane?>
<StackPane xmlns:fx="http://javafx.com/fxml" fx:controller="fxml_grid_test.ParentController" >
<Button fx:id="insertButton" text="insert" onMouseClicked="#insertData"/>
</StackPane>
I want to make a new FXML file which has few Controls like Label. But when I run the application Some times the from is not Showing and Sometime when form is Showing label are not Showing.
I have written the following code:
DashBoard.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="603.0" prefWidth="1063.0" styleClass="mainFxmlClass" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.DashBoard.DashBoardController">
<stylesheets>
<URL value="#dashboard.css" />
</stylesheets>
<children>
<Label fx:id="welcome" layoutX="403.0" layoutY="52.0" text="Label" />
</children>
</AnchorPane>
DashBoardController.java :
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
/**
* FXML Controller class
*
* #author DELL
*/
public class DashBoardController implements Initializable {
/**
* Initializes the controller class.
*/
#FXML
private Label welcome;
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
DashRun.java :
package com.DashBoard;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class DashRun extends Application{
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("DashBoard.fxml"));
Scene scene = new Scene(root);
Label a = new Label();
stage.setTitle("Dash Board");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}