inserting a data to a gridpane in another fxml file - javafx

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>

Related

Setting up to use JAVAFX at the Command Line

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?

pane.getChildren().addAll(); not working in a scene javafx

This code will not allow the line to draw in my window... All I have in the fxml file is a simple pane with the fx:id of hi to test things out. There is no error, the line simply doesn't appear. I've also tried this with a box and circle. I really need help, this is an important project.
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Line;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
public class PlotSceneController implements Initializable {
#FXML
Pane hi;
#Override
public void initialize(URL url, ResourceBundle rb) {
Line line = new Line(0,0,10,110);
line.setStroke(Color.BLACK);
line.setStrokeWidth(10);
hi.getChildren().addAll(line);
}
}
FXML File
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.shape.*?>
<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<Pane fx:id="hi" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-
Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0"
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
</children>
</Pane>
Main Class, leads to another page with a button that leads to the page I'm having trouble with.
public class Main extends Application {
Stage firstStage;
Scene loginButton;
#Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Main.fxml"));
firstStage = primaryStage;
loginButton = new Scene(root, 900, 700);
primaryStage.setTitle("Treatment Data");
primaryStage.setScene(loginButton);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) { //Main class
launch(args); //Launches application/window
}
}
You are missed to set a controller class PlotSceneController.java. Set controller class in different two way like using main class setController() method or set controller class in left bottom side controller pane in scene Builder screen.
Using Main
FXMLLoader loader = new FXMLLoader(getClass().getResource("Main.fxml"));
loader.setController(new PlotSceneController());
Parent root = (Parent) loader.load();
Or Using FXML
Set Controller class with full package path like below way

JavaFX Netbeans FXML not found

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")

Calling Fxml file using Start Method which extends Application Class

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);
}
}

JavaFx 2.0 with FXML: tabs at bottom instead of top?

Is it possible to define the TabBar to place the tabs at bottom instead of top?
To set the side of the tabs use following snippet:
TabPane tabPane = new TabPane();
Tab tab1 = new Tab("Tab 1");
tab1.setContent(new Label("Tab1 content"))
tabPane.getTabs().add(tab1);
tabPane.setSide(Side.BOTTOM)
Now the content is above the tabs.
Also as full FXML example:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.collections.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.effect.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.shape.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.web.*?>
<BorderPane xmlns:fx="http://javafx.com/fxml" fx:controller="example.MainViewController">
<bottom>
<HBox>
<children>
<Button fx:id="btnNewTab" mnemonicParsing="false" text="Add New Tab" onAction="#btnNewTabAction" />
</children>
</HBox>
</bottom>
<center>
<TabPane fx:id="tabPane" side="BOTTOM">
<tabs>
<Tab text="Untitled Tab 1">
<content>
<AnchorPane id="Content">
<Label>Content 1</Label>
</AnchorPane>
</content>
</Tab>
<Tab text="Untitled Tab 2">
<content>
<AnchorPane id="Content">
<Label>Content 2</Label>
</AnchorPane>
</content>
</Tab>
</tabs>
</TabPane>
</center>
<top>
<Label text="TabPane Example" />
</top>
</BorderPane>
The main class:
package example;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class ExampleMain extends Application {
/**
* #param args
*/
public static void main(String[] args) {
Application.launch(ExampleMain.class, args);
}
#Override
public void start(Stage primaryStage) throws Exception {
URL location = ExampleMain.class.getResource("MainView.fxml");
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(location);
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
try {
Parent root = (Parent) fxmlLoader.load(location.openStream());
// in case you need access to the controller
MainViewController mainViewController = fxmlLoader.getController();
primaryStage.setScene(new Scene(root, 1024, 768));
Scene s = primaryStage.getScene();
s.setRoot(root);
primaryStage.sizeToScene();
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
And the controller:
package example;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
public class MainViewController {
private static int counter = 0;
#FXML
private TabPane tabPane;
#FXML
public void btnNewTabAction() {
Tab tab = new Tab();
tab.setText("new Tab " + ++counter);
tab.setContent(new Label("Content of new tab " + counter));
tabPane.getTabs().add(tab);
}
}
as you can see in the example, fxml is an xml representation of the Java classes. If the class has an property side (getSide, setSide) then the class has in fxml an attribute side. So you can read the api documentation to find out which attributes are available in fxml as well.
Hope this helps.
Don't define the TabBar! Use a proper layout pane e.g. javafx.scene.layout.BorderPane.
Find attached examples for JavaFX 2.0 API and FXML:
JAVAFX 2.0 API
package tabtest;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class TabTest extends Application {
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
Scene scene = new Scene(root, 300, 250);
TabPane tabPane = new TabPane();
Tab tab1 = new Tab("Tab 1");
tabPane.getTabs().add(tab1);
root.setBottom(tabPane);
primaryStage.setScene(scene);
primaryStage.show();
}
}
For further information have a look at http://download.oracle.com/javafx/2.0/layout/jfxpub-layout.htm
FXML
package fxmltest;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class FxmlTest extends Application {
public static void main(String[] args) {
Application.launch(FxmlTest.class, args);
}
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
Scene scene = new Scene(root, 300, 250);
stage.setScene(scene);
stage.show();
}
}
Sample.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane>
<bottom>
<TabPane>
<tabs>
<Tab text="Tab 1" />
</tabs>
</TabPane>
</bottom>
</BorderPane>

Resources