I'm currently trying to create custom components in JavaFx for my desktop app, and I would like to use Spring DI.
I have read about how to make extendable components and without Spring I can do it, based on this code https://github.com/matrak/javafx-extend-fxml.
But when I replace the FXMLLoader with a custom SpringFXMLLoader it can't load the components.
In the main window, there is a button and a editbox, and on click I woul'd like to create a new custom module, with the given name. But it says, that the label in the custom component is null.
What am I doing wrong?
BasicModule.class
#org.springframework.stereotype.Controller
#DefaultProperty(value = "extension")
public class BasicModule extends BorderPane {
public Label label;
public AnchorPane extension;
public BasicModule() {
super();
}
public ObservableList<Node> getExtension() {
return extension.getChildren();
}
}
BasicModule.fxml
<fx:root type="javafx.scene.layout.BorderPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.akos.fxmlTest.BasicModule">
<top>
<Label fx:id="label" text="Label Basic" BorderPane.alignment="CENTER"/>
</top>
<center>
<AnchorPane fx:id="extension" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER"/>
</center>
</fx:root>
CustomModule.class
public class CustomModule extends BasicModule {
#FXML
public Label customModuleLabel;
public void setText(String text) {
customModuleLabel.setText(text);
}
}
CustomModule.fxml
<fx:root type="com.akos.fxmlTest.BasicModule" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.akos.fxmlTest.CustomModule">
<Label fx:id="customModuleLabel" text="asdasdasdasd"/>
</fx:root>
Main.class
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfiguration.class);
context.getBeanFactory().registerResolvableDependency(Stage.class, primaryStage);
SpringFxmlLoader loader = context.getBean(SpringFxmlLoader.class);
Parent parent = (Parent) loader.load("/fxml/main.fxml");
primaryStage.setScene(new Scene(parent, 1000, 600));
primaryStage.setTitle("test");
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
main.fxml
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.akos.fxmlTest.Controller">
<center>
<VBox fx:id="itemList" prefHeight="200.0" prefWidth="100.0" BorderPane.alignment="CENTER">
<BorderPane.margin>
<Insets left="50.0" right="50.0" />
</BorderPane.margin>
</VBox>
</center>
<left>
<VBox prefHeight="200.0" prefWidth="100.0" BorderPane.alignment="CENTER">
<children>
<Button fx:id="addButton" mnemonicParsing="false" onAction="#addNewModule" text="Button" />
<TextField fx:id="moduleNameEdit" />
</children>
</VBox>
</left>
</BorderPane>
Controller.class
#org.springframework.stereotype.Controller
public class Controller {
public VBox itemList;
public Button addButton;
public TextField moduleNameEdit;
public void addNewModule(ActionEvent actionEvent) {
CustomModule customModule = new CustomModule();
itemList.getChildren().add(customModule);
customModule.setText(moduleNameEdit.getText());
}
}
AppConfiguration.class
#Configuration
#ComponentScan("com.akos.fxmlTest")
public class AppConfiguration {}
Sorry for the wall of text.
Related
so I have two Controllers: the MainControllerand an ImageContainerboth have a FXML layout. In my MainController i set up a SplitPane and inside of it a FlowPane now I want to load the layout of the ImageContainer in the flowpane at runtime:
PROBLEM
How do I place the layout inside the flowpane with pre filled values in textFields, set an image etc.?
Idea
ImageContainer must extend Pane, and in the MainController I have to call the constructor of the ImageContainer and add the ImageContainer to the flowpane:
ImageContainer imgC = new ImageContainer(4,2,"location");
fp_contentFlowPane.getChildren().add(imgC);
Caused by: java.lang.NullPointerException
Caused by: java.lang.reflect.InvocationTargetException
If anyone has an ideas, help is appreciated!
Code snippet Part of ImageContainer Contoller:
public class ImageContainer extends Pane {
public HBox hbx_elementContainer;
public Label lb_likeCount;
public Label lb_commentCount;
public Label lb_location;
public ImageContainer(int likeCount, int commentCount, String location) {
this.lb_likeCount.setText(String.valueOf(likeCount));
this.lb_commentCount.setText(String.valueOf(commentCount));
this.lb_location.setText(location);
Image image = new Image("/sampleFoto.JPG");
iv_feedImage.setImage(image);
}
}
Code snippet Part of MainController Note this is not the whole code:
public class MainScreenController{
public TextField tf_userName;
public ListView lv_listView;
public FlowPane fp_contentFlowPane;
public SplitPane sp_splitPane;
public void onItemClicked(MouseEvent mouseEvent) throws IOException {
int index = lv_listView.getSelectionModel().getSelectedIndex();
if (mouseEvent.getButton().equals(MouseButton.SECONDARY)) {
if (index >= 0) {
lv_listView.getItems().remove(index);
userList.remove(index);
}
}
else{
//fp_contentFlowPane.getChildren().add(new
ImageContainer(5,5,"test"));
ImageContainer imgC = new ImageContainer(4,2,"location");
fp_contentFlowPane.getChildren().add(imgC);
}
}}
Code snippet Main
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/sample.fxml"));
Parent root = loader.load();
primaryStage.setTitle("Get Viral");
primaryStage.setScene(new Scene(root, 1000, 700));
primaryStage.show();
primaryStage.getIcons().add(new Image("/iconSpectures.jpg"));
}
public static void main(String[] args) {
launch(args);
}
}
FXML of ImageContainer:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.text.Font?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" prefHeight="200.0" prefWidth="200.0"
xmlns="http://javafx.com/javafx/8.0.172-ea"
xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.ImageContainer">
<bottom>
<HBox fx:id="hbx_elementContainer" prefHeight="31.0" prefWidth="600.0"
BorderPane.alignment="CENTER">
<children>
<Label fx:id="lb_likeCount" contentDisplay="TOP" text="Label">
<HBox.margin>
<Insets right="10.0" />
</HBox.margin></Label>
<Label fx:id="lb_commentCount" text="Label">
<HBox.margin>
<Insets right="20.0" />
</HBox.margin></Label>
<Label fx:id="lb_location" text="Label" />
<Label fx:id="lb_accountHolder" text="Label" />
<Button mnemonicParsing="false" text="Download">
<font>
<Font name="Arial Bold" size="11.0" />
</font>
<HBox.margin>
<Insets right="10.0" />
</HBox.margin>
</Button>
</children>
</HBox>
</bottom>
<center>
<AnchorPane prefHeight="200.0" prefWidth="200.0"
BorderPane.alignment="CENTER">
<children>
<ImageView fx:id="iv_feedImage" fitHeight="150.0"
fitWidth="200.0"
pickOnBounds="true" preserveRatio="true" AnchorPane.bottomAnchor="0.0"
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
</center>
</BorderPane>
If you want your ImageContainer to make use of your FXML then you can simply load it in the constructor using FXMLLoader and get rid of the fx:controller="sample.ImageContainer" from your FXML.
Here's a post about when to use which method of setting a controller for an fxml file to use (fx:controller vs FXMLLoader); Because your ImageContainer constructor requires arguments, it's easier imo to use the FXMLLoader method.
public class ImageContainer extends Pane {
private static final PATH_FXML = "/internal/path/to/layout.fxml"
#FXML public HBox hbx_elementContainer;
#FXML public Label lb_likeCount;
#FXML public Label lb_commentCount;
#FXML public Label lb_location;
public ImageContainer(int likeCount, int commentCount, String location) {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(PATH_FXML));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException e) {
throw new RuntimeException(e);
}
this.lb_likeCount.setText(String.valueOf(likeCount));
this.lb_commentCount.setText(String.valueOf(commentCount));
this.lb_location.setText(location);
Image image = new Image("/sampleFoto.JPG");
iv_feedImage.setImage(image);
}
}
For some extra fun stuff: If you define getters and setters on a custom Control, then you can use them in the attributes of that control in FXML.
It's not exactly necessary for your use case, but you can do stuff like this.
Custom Control:
package path.to.my_package;
public class MyControl extends Control {
private String myField;
public String getMyField() { return myField; }
public void setMyField(String myField) { this.myField = myField; }
}
FXML:
<?import path.to.my_package.MyControl ?>
<BorderPane xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1">
<center>
<MyControl myField="myValue"/>
</center>
</BorderPane>
I have a FXML-application with a main.fxml, which includes two other fxml files. Each of these fxml files has its own controller class.
My question is, of how to get access to objects from a specific controller, although these objects are defined on another fxml file.
The following code is just a minimal example. I thought it was a good idea to split ui elements in different fxml files, because they are getting larger and larger.
My main fxml:
<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="MainController">
<fx:include fx:id="top" source="top.fxml"/>
<fx:include fx:id="bottom" source="bottom.fxml"/>
</VBox>
top.fxml:
<VBox fx:id="vbox" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="ControllerTop">
<children>
<Button fx:id="topbtn" onAction="#printOutput" text="OK" />
</children>
</VBox>
bottom.fxml
<VBox fx:id="vbox" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="ControllerBottom">
<children>
<Button fx:id="bottombtn" onAction="#printOutput" text="OK" />
</children>
</VBox>
For top.fxml i have created this controller class:
public class ControllerTop {
#FXML public Button topbtn;
#FXML public Button bottombtn;
#FXML
public void printOutput() {
System.out.println("Hello from top button");
topbtn.setDisable(true); //OK!
bottombtn.setDisable(false); //Failed
}
}
Of course bottombtn is defined in bottom.fxml and has its own controller. The problem is, that bottombtn of printOut() of this ControllerTop results in a NullPointerException. So i need help by accessing objects in a nice and smart way.
Thanks
in main controller:
public class MainController {
/**
* var name has to be topController
*/
public TopController topController;
/**
* var name has to be bottomController
*/
public BottomController bottomController;
public void initialize(){
Button topbtn=topController.topbtn;
Button bottombtn=bottomController.bottombtn;
topbtn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("Hello from top button");
topbtn.setDisable(true); //OK!
bottombtn.setDisable(false); //Failed
}
});
}
}
bottom.fxml:
<VBox fx:id="vbox" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="BottomController">
<children>
<Button fx:id="bottombtn" text="OK" />
</children>
</VBox>
top.fxml:
<VBox fx:id="vbox" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="TopController">
<children>
<Button fx:id="topbtn" text="OK" />
</children>
</VBox>
and in class TopController and BottomController set #FXML public Button **btnName**;
BottomController:
public class BottomController {
public Button bottombtn;
}
TopController:
public class TopController {
public Button topbtn;
}
Another option it to use initialize at MainController to set the value of bottombtn in topController
I'm trying to change from one screen to another in full screen model but only the first screen is on full screen, when I change to another screen the full screen dosn't work.
Here's my code:
Main
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setFullScreen(true);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
sample.fmxl
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.text.Text?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<children>
<StackPane prefHeight="200.0" prefWidth="200.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
<children>
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="First Screen" textAlignment="CENTER" />
</children>
</HBox>
</children>
</StackPane>
<StackPane layoutY="163.0" prefHeight="200.0" prefWidth="600.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
<children>
<HBox alignment="CENTER" prefHeight="200.0" prefWidth="600.0">
<children>
<Button fx:id="next" mnemonicParsing="false" onAction="#nextScreen" text="Next" />
</children>
</HBox>
</children>
</StackPane>
</children>
</AnchorPane>
FirstScreenController
public class Controller implements Initializable {
#FXML
private Button next;
#Override
public void initialize(URL location, ResourceBundle resources) {
}
public void nextScreen(ActionEvent actionEvent) throws Exception {
SecondScreenController secondScreen = new SecondScreenController();
Stage stage = (Stage) next.getScene().getWindow();
stage.setFullScreen(true);
secondScreen.start(stage);
}
public void start(Stage window) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
Scene scene = new Scene(root);
window.setScene(scene);
window.show();
}
}
sample2.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.text.Text?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.SecondScreenController">
<children>
<StackPane prefHeight="200.0" prefWidth="200.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
<children>
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Second Screen" textAlignment="CENTER" />
</children>
</HBox>
</children>
</StackPane>
<StackPane layoutY="163.0" prefHeight="200.0" prefWidth="600.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
<children>
<HBox alignment="CENTER" prefHeight="200.0" prefWidth="600.0">
<children>
<Button fx:id="back" mnemonicParsing="false" onAction="#backScreen" text="Back" />
</children>
</HBox>
</children>
</StackPane>
</children>
</AnchorPane>
SecondScreenController
public class SecondScreenController implements Initializable {
#FXML
private Button back;
#Override
public void initialize(URL location, ResourceBundle resources) {
}
public void start(Stage window) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("sample2.fxml"));
Scene scene = new Scene(root);
window.setScene(scene);
window.show();
}
public void backScreen(ActionEvent actionEvent) throws Exception {
Controller firstScreen = new Controller();
Stage stage = (Stage) back.getScene().getWindow();
stage.setFullScreen(true);
firstScreen.start(stage);
}
}
When I press the button Full Screen mode stop working, even if I go back to the first screen. Any idea how to solve this?
Add a window.setFullScreen(true); in SecondScreenController.java before window.show();.
Also add window.setFullScreen(true); in Controller.java in start() before window.show();
I have a question.
I want to change the color of a pane from another controller class.
I am using this code:
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/Menu.fxml"));
try {
Parent loaded = (Parent) loader.load();
} catch (IOException e) {
e.printStackTrace();
}
MenuController controller = (MenuController) loader.getController();
Platform.runLater(new Runnable() {
#Override
public void run() {
Pane pane = controller.getRedPane();
pane.setBackground(new Background(new BackgroundFill(Color.BLUE, CornerRadii.EMPTY, Insets.EMPTY)));
}
});
The loaded, controller and pane aren't null.
But the pane's color doesn't change, can someone help me with this problem?
Thank you very much.
[EDIT]
public class MenuController implements Initializable
{
#FXML
private GridPane MenuRoot;
#FXML
private Pane redPane;
#Override
public void initialize(URL location, ResourceBundle resources)
{
}
#FXML
private void changeGridSize(ActionEvent event){
new ChangeSizes();
}
public GridPane getMenuRoot(){
return this.MenuRoot;
}
public Pane getRedPane(){
return this.redPane;
}
}
[EDIT]
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<GridPane fx:id="MenuRoot" gridLinesVisible="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nl.voxworks.homeserver.client.MenuController">
<columnConstraints>
<ColumnConstraints hgrow="ALWAYS" maxWidth="1.7976931348623157E308" minWidth="0.0" percentWidth="50.0" />
<ColumnConstraints hgrow="ALWAYS" maxWidth="1.7976931348623157E308" minWidth="0.0" percentWidth="50.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="0.0" percentHeight="50.0" vgrow="ALWAYS" />
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="0.0" percentHeight="50.0" vgrow="ALWAYS" />
</rowConstraints>
<children>
<Pane fx:id="redPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="0.0" minWidth="0.0" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: red;" GridPane.rowIndex="1" />
<Pane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="0.0" minWidth="0.0" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: black;" GridPane.columnIndex="1" GridPane.rowIndex="1" />
</children>
</GridPane>
[EDIT] (different project all files included)
package javafxapplication16;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Insets;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
public class ChangeSize {
public ChangeSize(){
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
try {
loader.load();
} catch (IOException ex) {
Logger.getLogger(ChangeSize.class.getName()).log(Level.SEVERE, null, ex);
}
FXMLDocumentController controller = (FXMLDocumentController) loader.getController();
Platform.runLater(new Runnable() {
#Override
public void run() {
Pane pane = controller.getPane();
pane.setBackground(new Background(new BackgroundFill(Color.BLUE, CornerRadii.EMPTY, Insets.EMPTY)));
}
});
}
}
FXMLDocumentController.
package javafxapplication16;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
public class FXMLDocumentController implements Initializable {
#FXML
private Pane redPane;
#FXML
private void changeGridSize(ActionEvent event){
new ChangeSize();
}
#Override
public void initialize(URL url, ResourceBundle rb) {
}
public Pane getPane(){
return this.redPane;
}
}
JavaFXApplication16
package javafxapplication16;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class JavaFXApplication16 extends Application {
#Override
public void start(Stage stage) throws Exception {
// Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
// FXMLLoader loader
Parent loaded=null;
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
try {
loaded = (Parent) loader.load();
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(loaded);
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
FXML
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<GridPane fx:id="MenuRoot" gridLinesVisible="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication16.FXMLDocumentController">
<columnConstraints>
<ColumnConstraints hgrow="ALWAYS" maxWidth="1.7976931348623157E308" minWidth="0.0" percentWidth="50.0" />
<ColumnConstraints hgrow="ALWAYS" maxWidth="1.7976931348623157E308" minWidth="0.0" percentWidth="50.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="0.0" percentHeight="50.0" vgrow="ALWAYS" />
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="0.0" percentHeight="50.0" vgrow="ALWAYS" />
</rowConstraints>
<children>
<Pane fx:id="redPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="0.0" minWidth="0.0" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: red;" GridPane.rowIndex="1" />
<Pane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="0.0" minWidth="0.0" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: black;" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Button mnemonicParsing="false" onAction="#changeGridSize" text="Button" />
</children>
</GridPane>
This is my code: I hope helped you
FXMLDocumentController.class
public class FXMLDocumentController implements Initializable {
#FXML
private Pane redPane;
#FXML
private void changeGridSize(ActionEvent event){
// new ChangeSizes();
}
#Override
public void initialize(URL url, ResourceBundle rb) {
}
public Pane getPane(){
return this.redPane;
}
}
JavaFXMLApplication3.class
public class JavaFXMLApplication3 extends Application {
#Override
public void start(Stage stage) throws Exception {
// Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
// FXMLLoader loader
Parent loaded=null;
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
try {
loaded = (Parent) loader.load();
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(loaded);
stage.setScene(scene);
stage.show();
FXMLDocumentController controller = (FXMLDocumentController) loader.getController();
Platform.runLater(new Runnable() {
#Override
public void run() {
Pane pane = controller.getPane();
pane.setBackground(new Background(new BackgroundFill(Color.BLUE, CornerRadii.EMPTY, Insets.EMPTY)));
}
});
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
FXMLDocument.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.*?>
<GridPane fx:id="MenuRoot" gridLinesVisible="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxmlapplication3.FXMLDocumentController">
<columnConstraints>
<ColumnConstraints hgrow="ALWAYS" maxWidth="1.7976931348623157E308" minWidth="0.0" percentWidth="50.0" />
<ColumnConstraints hgrow="ALWAYS" maxWidth="1.7976931348623157E308" minWidth="0.0" percentWidth="50.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="0.0" percentHeight="50.0" vgrow="ALWAYS" />
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="0.0" percentHeight="50.0" vgrow="ALWAYS" />
</rowConstraints>
<children>
<Pane fx:id="redPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="0.0" minWidth="0.0" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: red;" GridPane.rowIndex="1" />
<Pane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="0.0" minWidth="0.0" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: black;" GridPane.columnIndex="1" GridPane.rowIndex="1" />
</children>
</GridPane>
I test your code and the problem is that you create another Pane redPane that isn't show:
when you call FXMLLoader you create a new loader that isn't show in stage.
I suggested you a possible solution : create a static Stage ... example code:
public class JavaFXMLApplication3 extends Application {
static Stage staticstage;
// Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
// FXMLLoader loader
#Override
public void start(Stage stage) throws Exception {
// Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
// FXMLLoader loader
staticstage=stage;
Parent loaded=null;
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
try {
loaded = (Parent) loader.load();
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(loaded);
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
and change class ChangeSize
public class ChangeSize {
public ChangeSize() {
Parent loaded=null;
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
try {
loaded = (Parent) loader.load();
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(loaded);
JavaFXMLApplication3.staticstage.setScene(scene);
JavaFXMLApplication3.staticstage.show();
FXMLDocumentController controller = (FXMLDocumentController) loader.getController();
Platform.runLater(new Runnable() {
#Override
public void run() {
Pane pane = controller.getPane();
pane.setBackground(new Background(new BackgroundFill(Color.BLUE, CornerRadii.EMPTY, Insets.EMPTY)));
}
});
}
}
another solution is to pass FXMLDocumentController to class ChangeSize ... example code :
public class ChangeSize {
public ChangeSize(FXMLDocumentController controller) {
Platform.runLater(new Runnable() {
#Override
public void run() {
Pane pane = controller.getPane();
pane.setBackground(new Background(new BackgroundFill(Color.BLUE, CornerRadii.EMPTY, Insets.EMPTY)));
}
});
}
and in FXMLDocumentController class change the changeGridSize
#FXML
private void changeGridSize(ActionEvent event){
new ChangeSize(this);
}
I need to close my JDialog from JavaFx Button defined in my FXML file.
I post code of my class called by Main Application:
ExampleWindow.java
public class ExampleWindow extends JDialog
{
#FXML
Button closeButton;
public ExampleWindow()
{
}
public void initAndShowGUI()
{
final JFXPanel fxPanel = new JFXPanel();
add(fxPanel);
Platform.runLater(new Runnable()
{
#Override
public void run()
{
AnchorPane parent = null;
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setRoot(this);
try {
parent = fxmlLoader.load(getClass().getResource("WindowControlPanel.fxml"));
}
catch (IOException e) {
e.printStackTrace();
}
scene = new Scene(parent);
fxPanel.setScene(scene);
}
});
}
public void onAction(ActionEvent ac)
{
this.dispose();
}
}
Method onAction is called by JavaFx Button (on FXML file)
WindowControlPanel.fxml
<AnchorPane id="AnchorPane" fx:id="windowPanel" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="50.0" prefWidth="1024.0" style="-fx-border-color: white, grey; -fx-border-width: 2, 1; -fx-border-insets: 0, 0 1 1 0" xmlns:fx="http://javafx.com/fxml" fx:controller="ExampleWindow">
<children>
<FlowPane alignment="CENTER_RIGHT" columnHalignment="CENTER" prefHeight="50.0" prefWidth="1024.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<Button fx:id="closeButton" mnemonicParsing="false" onAction="#onAction" prefHeight="35.0" prefWidth="100.0" text="Close">
<FlowPane.margin>
<Insets bottom="5.0" left="20.0" right="20.0" top="5.0" />
</FlowPane.margin>
</Button>
</children>
</FlowPane>
</children>
</AnchorPane>
When I pressed closeButton, method onAction is correctly called, but my JDialog doesn't close. Any ideas? Where am I wrong?