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
Related
I would like to create a scrollpane and button from the controller and display it in fxml, is that possible? This my code but it doesn't work
controller
package application;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
public class controller {
ScrollPane scrollPane = new ScrollPane();
Button button = new Button("My Button");
public void initialize() {
button.setPrefSize(400, 300);
scrollPane.setContent(button);
scrollPane.setVbarPolicy(ScrollBarPolicy.AS_NEEDED);
scrollPane.setHbarPolicy(ScrollBarPolicy.AS_NEEDED);
}
}
main
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
final Parent parent = FXMLLoader.load(getClass().getResource("ui.fxml"));
primaryStage.setTitle("ScrollPane Demo ");
primaryStage.setScene(new Scene(parent,600, 600));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);}
}
fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<VBox id="vbox" prefHeight="400" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller">
<children>
<Pane prefHeight="200.0" prefWidth="200.0" />
</children>
</VBox>
You need to include your vbox in your controller, like this:
#FXML
private VBox vbox;
After that, add your scrollpane to your vbox's children:
vbox.getChildren().add(scrollPane);
Note that, you not added your button to your scrollpane's content, so your scrollpane is currently empty!
Edit: why you want to add nodes via fxml and from code too? Use this solution if it is really necessary, anyway use fxml to build your UI.
I'm new in FXML and I searched a lot to find a solution for my troubles with TabPanes. In the below example (based on the example in JavaFX: Adding a new tab from a tab controller) I want to add some tabs to a TapPane - adding a new tab from inside an "included"-tab (Tab 1) isn't a problem, but when I try to add a tab from inside a dynamically created tab (e.g. Tab 2), I always get a NullPointerException.
Could anyone please tell me how I get access to the FirstTab-Controller from inside the dynamically created tab (Tab 2)?
TestingTabPane.java:
package testingtabs;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class TestingTabPane extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FirstTab.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
FirstTab.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.*?>
<TabPane fx:id="myTabPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" tabClosingPolicy="UNAVAILABLE" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="testingtabs.FirstTabController">
<tabs>
<Tab fx:id="FirstTab" text="Tab 1">
<fx:include source="NewTab.fxml" fx:id="newTab"/>
</Tab>
</tabs>
</TabPane>
FirstTabController.java:
package testingtabs;
import java.io.IOException;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
public class FirstTabController {
#FXML
public TabPane myTabPane;
#FXML
public NewTabController newTabController;
public void initialize() {
newTabController.setMainWindowController(this);
}
public void createTab() throws IOException {
int numTabs = myTabPane.getTabs().size();
Tab tab = new Tab("Tab " + (numTabs + 1));
Parent root = FXMLLoader.load(getClass().getResource("NewTab.fxml"));
tab.setContent(root);
myTabPane.getTabs().add(tab);
}
}
NewTab.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.*?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="testingtabs.NewTabController">
<children>
<Button fx:id="addTabBtn" layoutX="268.0" layoutY="187.0" mnemonicParsing="false" onAction="#onAddTabBtnClicked" text="add tab" />
</children>
</AnchorPane>
NewTabController.java:
package testingtabs;
import java.io.IOException;
import javafx.fxml.FXML;
public class NewTabController {
private FirstTabController firstTabController ;
public void setMainWindowController(FirstTabController mainWindowController) {
this.firstTabController = mainWindowController ;
}
#FXML
public void onAddTabBtnClicked() throws IOException {
firstTabController.createTab();
}
}
When you load a tab "dynamically" via the createTab() method, you never call setMainWindowController(...) on the controller for that newly-created tab content. So in that controller, firstTabController is still null, and you get a Null Pointer Exception in the onAddTabBtnClicked method.
You can do
public void createTab() throws IOException {
int numTabs = myTabPane.getTabs().size();
Tab tab = new Tab("Tab " + (numTabs + 1));
FXMLLoader loader = new FXMLLoader(getClass().getResource("NewTab.fxml"));
Parent root = loader.load();
NewTabController newTabController = loader.getController();
newTabController.setMainWindowController(this);
tab.setContent(root);
myTabPane.getTabs().add(tab);
}
You don't really need to treat the first tab differently to the others; you could simply call the createTab() method from initialize() to make the first one, reducing the code a little (and using consistent techniques throughout):
FirstTab.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.*?>
<TabPane fx:id="myTabPane" maxHeight="-Infinity" maxWidth="-Infinity"
minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"
prefWidth="600.0" tabClosingPolicy="UNAVAILABLE"
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="testingtabs.FirstTabController" />
FirstTabController:
package testingtabs;
import java.io.IOException;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
public class FirstTabController {
#FXML
public TabPane myTabPane;
public void initialize() {
createTab();
}
public void createTab() throws IOException {
int numTabs = myTabPane.getTabs().size();
Tab tab = new Tab("Tab " + (numTabs + 1));
FXMLLoader loader = new FXMLLoader(getClass().getResource("NewTab.fxml"));
Parent root = loader.load();
NewTabController newTabController = loader.getController();
newTabController.setMainWindowController(this);
tab.setContent(root);
myTabPane.getTabs().add(tab);
}
}
NewTab.fxml and NewTabController remain the same.
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);
}
}
Ok so I've created my own customer label, for this example it's extremely basic. What I did was extend the Javafx Label in my custom class called MyLabel. I'm also using FXML to create the GUI. Now when I do this I can't seem to instantiate with my custom class as I get this error.
"Can not set net.blacksquirreldevs.tests.MyLabel field net.blacksquirreldevs.tests.SampleLabelController.sampleLabel to javafx.scene.control.Label"
Here is the code for everything
Main.java
package net.blacksquirreldevs.tests;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("SampleLabel");
AnchorPane anchorPane = (AnchorPane) FXMLLoader.load(getClass().getResource("SampleLabel.fxml"));
primaryStage.setScene(new Scene(anchorPane));
primaryStage.show();
}
public static void main(String... args) {
launch(args);
}
}
MyLabel.java
package net.blacksquirreldevs.tests;
import javafx.scene.control.Label;
public class MyLabel extends Label {
public MyLabel(String text) {
super();
setText(text);
}
}
SampleLabelController.java
package net.blacksquirreldevs.tests;
import javafx.fxml.FXML;
import java.net.URL;
import java.util.ResourceBundle;
public class SampleLabelController {
#FXML
private ResourceBundle resources;
#FXML
private URL location;
#FXML
private MyLabel sampleLabel = new MyLabel("Hello world!");
#FXML
void initialize() {
assert sampleLabel != null : "fx:id=\"sampleLabel\" was not injected: check your FXML file 'SampleLabel.fxml'.";
}
}
And finally the fxml file SampleLabel.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.text.*?>
<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml" fx:controller="net.blacksquirreldevs.tests.SampleLabelController">
<children>
<Label fx:id="sampleLabel" layoutX="153.0" layoutY="171.0" text="Sample Text">
<font>
<Font name="Arial Bold" size="50.0" />
</font>
</Label>
</children>
</AnchorPane>
So what I want to know is why I can' declare, in my SamplelabelController class, the sampleLabel as MyLabel?
Hopefully I've explained this well enough, if not let me know and I'll try to go a bit more in detail.
You are using <Label ... in your FXML instead of <MyLabel
Beside that your MyLabel has a none default constructor and in this case you NEED to provide a builder named MyLabelBuilder so that FXMLLoader can create an instance of MyLabel