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?
Related
I am trying to solve an issue with a calculator project I am working on with javafx 11 and java11 using Scene Builder. I am trying to figure out a way to make the buttons on the calculator change color when typing the corresponding value from the keyboard. Is there a method, or onKeyPressed etc type solution to this issue?
I was able to make the button change colors when the a user clicks on it with a mouse (changes to green). This was accomplished in my css style sheet. I tried to add a method to my onKeyReleased method in my controller class, and could change the background that way, but could not determine a way to have the color change back in a timely manner without causing a lag on the UI. I want the UI to change colors similar to most calculators such as the standard windows calculator. This is where a user holds the key down and it changes color, and when releasing the key it changes back.
//main.java
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
Parent root =
FXMLLoader.load(getClass().getResource("calculator.fxml"));
primaryStage.getIcons().add(new Image("CALC.png"));
primaryStage.setTitle(" TS Calculator");
primaryStage.setScene(new Scene(root, 250, 375));
primaryStage.setResizable(true);
primaryStage.setMinHeight(375);
primaryStage.setMinWidth(250);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
/CSS
Button{
-fx-background-color: black;
-fx-text-align: center;
-fx-text-fill: white;
-fx-border-color: green;
-fx-font-size: 1em;
-fx-border-radius: 10 10 10 10;
-fx-background-radius: 10 10 10 10;
}
Button:pressed{
-fx-background-color: green;
}
TextField{
-fx-font-size: 1.5em;
}
//FXML (Only showing 1 button)
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<GridPane maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" minHeight="306.00" minWidth="204.0"
prefHeight="288.0" prefWidth="208.0" style="-fx-background-color:
DARKSLATEGREY; -fx-border-color: green;"
stylesheets="#styles.css" xmlns="http://javafx.com/javafx/11.0.1"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.trevorsmith.Controller"
onKeyReleased="#acceptKeyboardInput">
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnSpan="4"
GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS"
onKeyPressed="#acceptKeyboardInput">
<children>
<TextField fx:id="textFieldDisplay" editable="false"
alignment="CENTER_RIGHT" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" prefWidth="196.0"
AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0"
AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
</children>
</AnchorPane>
<AnchorPane maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0"
GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.vgrow="ALWAYS">
<children>
<Button maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" text="0" AnchorPane.bottomAnchor="0.0"
AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0" />
</children>
I am unable to make the background color change on click, and when I release my key it change back.
You'll want to register a couple of listeners on your Scene to listen to the pressed keys.
Once you have the key, you can use JavaFX's PseudoClass selectors to update the pressed style of each Button.
There could be a more streamlined way to do this, but this is my implementation. Here is a complete sample you can try out to see it in action.
Note that I did not implement the actual functionality of the calculator.
Final result/screenshot at the end.
Main.java:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("MainLayout.fxml"));
Scene scene = new Scene(loader.load());
scene.getStylesheets().add("style.css");
primaryStage.setScene(scene);
primaryStage.setTitle("Calculator");
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
MainLayout.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox alignment="TOP_CENTER" spacing="10.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="UI.BaseApps.Calculator.MainController">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<children>
<TextField fx:id="txtDisplay" disable="true" alignment="CENTER_RIGHT" editable="false" minHeight="-Infinity"
prefHeight="50.0" text="0"/>
<GridPane hgap="10.0" vgap="10.0" VBox.vgrow="ALWAYS">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="-Infinity"/>
<ColumnConstraints hgrow="SOMETIMES" minWidth="-Infinity"/>
<ColumnConstraints hgrow="SOMETIMES" minWidth="-Infinity"/>
<ColumnConstraints hgrow="NEVER" minWidth="-Infinity"/>
<ColumnConstraints hgrow="SOMETIMES" minWidth="-Infinity"/>
<ColumnConstraints hgrow="SOMETIMES" minWidth="-Infinity"/>
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="-Infinity" vgrow="SOMETIMES"/>
<RowConstraints minHeight="-Infinity" vgrow="SOMETIMES"/>
<RowConstraints minHeight="-Infinity" vgrow="SOMETIMES"/>
<RowConstraints minHeight="-Infinity" vgrow="SOMETIMES"/>
</rowConstraints>
<children>
<Button fx:id="btn7" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="7"/>
<Button fx:id="btn8" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="8" GridPane.columnIndex="1"/>
<Button fx:id="btn9" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="9" GridPane.columnIndex="2"/>
<Separator orientation="VERTICAL" prefHeight="200.0" GridPane.columnIndex="3" GridPane.rowSpan="4"/>
<Button fx:id="btnDivide" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="÷" GridPane.columnIndex="4"/>
<Button fx:id="btnClear" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="C" GridPane.columnIndex="5"/>
<Button fx:id="btn4" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="4" GridPane.rowIndex="1"/>
<Button fx:id="btn5" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="5" GridPane.columnIndex="1"
GridPane.rowIndex="1"/>
<Button fx:id="btn6" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="6" GridPane.columnIndex="2"
GridPane.rowIndex="1"/>
<Button fx:id="btnMultiply" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="x" GridPane.columnIndex="4"
GridPane.rowIndex="1"/>
<Button fx:id="btn1" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="1" GridPane.rowIndex="2"/>
<Button fx:id="btn2" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="2" GridPane.columnIndex="1"
GridPane.rowIndex="2"/>
<Button fx:id="btn3" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="3" GridPane.columnIndex="2"
GridPane.rowIndex="2"/>
<Button fx:id="btn0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" text="0" GridPane.columnSpan="2"
GridPane.rowIndex="3"/>
<Button fx:id="btnDecimal" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="." GridPane.columnIndex="2"
GridPane.rowIndex="3"/>
<Button fx:id="btnSubtract" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="-" GridPane.columnIndex="4"
GridPane.rowIndex="2"/>
<Button fx:id="btnAdd" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="+" GridPane.columnIndex="4"
GridPane.rowIndex="3"/>
<Button fx:id="btnEquals" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="="
GridPane.columnIndex="5" GridPane.rowIndex="2" GridPane.rowSpan="2"/>
<Button fx:id="btnBackspace" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="←" GridPane.columnIndex="5"
GridPane.rowIndex="1"/>
</children>
</GridPane>
</children>
</VBox>
MainController.java:
import javafx.application.Platform;
import javafx.css.PseudoClass;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
public class MainController {
// Here we'll define our PseudoClass needed to set the style for each pressed Button
private static final PseudoClass PRESSED = PseudoClass.getPseudoClass("pressed");
// Define FXML controls
#FXML
private TextField txtDisplay;
#FXML
private Button btn7, btn8, btn9;
#FXML
private Button btn4, btn5, btn6;
#FXML
private Button btn1, btn2, btn3;
#FXML
private Button btn0, btnDecimal;
#FXML
private Button btnMultiply, btnSubtract, btnAdd, btnDivide;
#FXML
private Button btnClear, btnEquals, btnBackspace;
#FXML
private void initialize() {
// We need access to the Scene to register our key listeners, so we need to wrap the code in a Platform.runLater(). If we try to do this without Platform.runLater(), we'll get a NullPointerException because txtDisplay hasn't been rendered yet.
Platform.runLater(() -> {
Scene scene = txtDisplay.getScene();
// Add a listener to capture any key that is pressed. We add this to the entire scene and we can then change the style of the corresponding button accordingly.
scene.setOnKeyPressed(event -> {
// We need to know which Button we're working with
Button button = getButton(event.getCode());
// Add our "pressed" style to the Button
if (button != null) button.pseudoClassStateChanged(PRESSED, true);
});
// Once the user releases the key, remove our custom style and trigger whatever onAction() code has been applied to the corresponding Button.
scene.setOnKeyReleased(event -> {
Button button = getButton(event.getCode());
if (button != null) {
button.pseudoClassStateChanged(PRESSED, false);
// Fire the button's onAction()
button.fire();
}
});
});
}
// Helper method to get the Button that corresponds to the pressed key. The Scene.setOnKeyPressed() listener provides the KeyCode for the pressed key. We can use that to determine which of our Buttons to trigger.
private Button getButton(KeyCode keyCode) {
switch (keyCode) {
case NUMPAD0: return btn0;
case NUMPAD1: return btn1;
case NUMPAD2: return btn2;
case NUMPAD3: return btn3;
case NUMPAD4: return btn4;
case NUMPAD5: return btn5;
case NUMPAD6: return btn6;
case NUMPAD7: return btn7;
case NUMPAD8: return btn8;
case NUMPAD9: return btn9;
case DECIMAL: return btnDecimal;
case DIVIDE: return btnDivide;
case ADD: return btnAdd;
case MULTIPLY: return btnMultiply;
case SUBTRACT: return btnSubtract;
case ENTER: return btnEquals;
case BACK_SPACE: return btnBackspace;
case ESCAPE: return btnClear;
}
return null;
}
}
style.css:
.text-field {
-fx-opacity: 1.0;
-fx-font-family: Consolas;
-fx-font-size: 200%;
}
.button {
-fx-font-family: Consolas;
-fx-font-size: 150%;
-fx-background-radius: 25px;
-fx-border-radius: 25px;
/* Remove focus highlighting */
-fx-focus-traversable: false;
}
.button:pressed {
-fx-background-color: lightgreen;
-fx-border-color: green;
}
And here is the result:
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'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'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.
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);
}