This question already has an answer here:
Java FX fxml on Action
(1 answer)
Closed 4 years ago.
I am trying to create a basic UI with JavaFX. The problem is only that my Handlers can't be found in my controller.
my ui.fxml:
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<StackPane id="pane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="reldb0.controller.PersonOverviewController">
<children>
<Button text="Hinzufügen" onAction="#handleAddClicked" fx:id="addButton" />
<Button text="Entfernen" onAction="#handleDeleteClicked" fx:id="deleteButton" />
<TableView fx:id="table">
<columns>
<TableColumn fx:id="vorname" prefWidth="100" text="Vorname" />
<TableColumn fx:id="nachname" prefWidth="100" text="Nachname" />
</columns>
</TableView>
</children>
</StackPane>
My Controller class:
package reldb0.controller;
import java.awt.event.ActionEvent;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import reldb0.entity.Person;
import reldb0.MockData;
/**
*
* #author hnsdi
*/
public class PersonOverviewController implements Initializable{
#FXML
private TableView<Person> table;
#FXML
private TableColumn<Person, String> vorname;
#FXML
private TableColumn<Person, String> nachname;
#Override
public void initialize(URL location, ResourceBundle resources) {
vorname.setCellValueFactory(new PropertyValueFactory<Person, String>("vorname"));
nachname.setCellValueFactory(new PropertyValueFactory<Person, String>("nachname"));
table.getItems().setAll(MockData.persons());
}
#FXML
private void handleAddClicked(ActionEvent event) {
StackPane root = new StackPane();
Scene scene = new Scene(root, 300, 300);
Stage addWindow = new Stage();
addWindow.setTitle("Person hinzufügen");
addWindow.setScene(scene);
addWindow.show();
}
#FXML
private void handleDeleteClicked(ActionEvent event) {
//TODO
}
}
I can't find the issue why my EventHandlers can't be found. I have the #FXML Annotations and the controller is registered correctly because the Table is filled with the data.
import java.awt.event.ActionEvent; // which is wrong
Import javafx.event.ActionEvent instead of java.awt.event.ActionEvent in your PersonOverviewController class
Related
I am writing a JavaFX app. I use a StackPane with two children. The topmost has a transparent background. I want the another pane to capture mouse events.
How can I do this?
I tried to make the top child mouse-transparent, but that makes its children transparent to mouse events.
// sample/Main.java
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class Main extends Application {
public static final String appName = "Application name";
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.initStyle(StageStyle.UNDECORATED);
root.getStylesheets().add("sample/sample.css");
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 400, 300));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
// sample/Controller.java
package sample;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
public class Controller {
#FXML
private AnchorPane topbar;
#FXML
private Label lbAppName;
#FXML
private Button btnCloseApp;
#FXML
private Button button1;
#FXML
private Button button2;
#FXML
private void initialize() {
lbAppName.setText(Main.appName);
// this disables btnCloseApp
topbar.setMouseTransparent(true);
btnCloseApp.setOnAction(event -> {
Platform.exit();
});
button1.setOnAction(event -> {
System.out.println("Clicked button1");
});
button2.setOnAction(event -> {
System.out.println("Clicked button2");
});
}
}
<!-- sample/sample.fxml -->
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<StackPane fx:controller="sample.Controller"
xmlns:fx="http://javafx.com/fxml">
<HBox>
<VBox fx:id="sidebar">
<Button fx:id="button1" text="Button 1"/>
<Button fx:id="button2" text="Button 2"/>
</VBox>
<GridPane fx:id="form">
<Label text="Field 1" GridPane.rowIndex="0" GridPane.columnIndex="0"/>
<TextField fx:id="field1" GridPane.rowIndex="0" GridPane.columnIndex="1"/>
<Label text="Field 2" GridPane.rowIndex="1" GridPane.columnIndex="0"/>
<TextField fx:id="field2" GridPane.rowIndex="1" GridPane.columnIndex="1"/>
</GridPane>
</HBox>
<AnchorPane fx:id="topbar">
<Label fx:id="lbAppName" AnchorPane.topAnchor="8" AnchorPane.leftAnchor="8"/>
<Button fx:id="btnCloseApp" text="Close" AnchorPane.topAnchor="8" AnchorPane.rightAnchor="8"/>
</AnchorPane>
</StackPane>
/* sample/sample.css*/
.root {
-fx-border-color: #a8c;
}
#sidebar {
-fx-padding: 40 8 8 8;
-fx-spacing: 8;
-fx-background-color: #caf;
-fx-pref-width: 150;
}
#form {
-fx-padding: 40 8 8 8;
-fx-hgap: 8;
-fx-vgap: 4;
}
I'm using JavaFX, problem is when traing drawing new line in XYChart, I get error NullPointerException. Its hapen after create a new Pane. Secont Pane is opening with line chart but is empty. I get the error from this line of the below code.
lineChart.getData().addAll(series);
When I trying to do this in primary window everything is going fine and the line is drawing correctly. But when i trying to do this after i create a second pane i get a error NullPointerException.
Fragment of code sending me a error:
chartsButton.setOnAction(new EventHandler<ActionEvent>() {
#SuppressWarnings("unchecked")
#Override
public void handle(ActionEvent event) {
Parent chartParent;
try {
Stage chartsWindow = new Stage();
chartParent = FXMLLoader.load(getClass().getResource("/eng/gascalculator/view/ChartsPane.fxml"));
chartsWindow.setTitle("Charts");
chartsWindow.setScene(new Scene(chartParent, 450, 450));
chartsWindow.show();
} catch (IOException e) {
}
XYChart.Series<String, Number> series = new XYChart.Series<String, Number>();
series.getData().add(new XYChart.Data<String, Number>("Jan", 10));
series.getData().add(new XYChart.Data<String, Number>("Feb", 30));
lineChart.getData().addAll(series);
}
});
Its should works like, when i click a chart Button, new pane should open with chart line and data on the chart.
I think this will be a problem with a new separate instance, like #Slaw tell. Below I prepare new program with minimal code. I have 2 fxml file both have controlled assassin to MainController class. MainPane open correct but when I push button to open second Pane with chart i get information the lineChart is null.
MainConntroller class:
package application;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.stage.Stage;
public class MainController implements Initializable {
#FXML
private Button chartButton;
#FXML
private LineChart<String, Number> lineChart;
#Override
public void initialize(URL location, ResourceBundle resources) {
chartButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Parent chartParent;
try {
Stage chartsWindow = new Stage();
chartParent = FXMLLoader.load(getClass().getResource("/application/ChartPane.fxml"));
chartsWindow.setTitle("Charts");
chartsWindow.setScene(new Scene(chartParent, 450, 450));
chartsWindow.show();
} catch (IOException e) {
}
XYChart.Series<String, Number> series = new XYChart.Series<String, Number>();
series.getData().add(new XYChart.Data<String, Number>("Jan", 10));
series.getData().add(new XYChart.Data<String, Number>("Feb", 30));
lineChart.getData().addAll(series);
}
});
}
}
Main class:
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;
public class Main extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent parent = FXMLLoader.load(getClass().getResource("/application/MainPane.fxml"));
Scene scene = new Scene(parent);
stage.setScene(scene);
stage.setTitle("First window");
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
MainPane.fxml file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0"
xmlns="http://javafx.com/javafx/10.0.1"
xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainController">
<children>
<Button fx:id="chartButton" layoutX="265.0" layoutY="188.0"
mnemonicParsing="false" text="Chart" />
</children>
ChartPane.fxml file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.chart.CategoryAxis?>
<?import javafx.scene.chart.LineChart?>
<?import javafx.scene.chart.NumberAxis?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0"
xmlns="http://javafx.com/javafx/10.0.1"
xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainController">
<children>
<LineChart fx:id="lineChart" layoutX="50.0">
<xAxis>
<CategoryAxis side="BOTTOM" />
</xAxis>
<yAxis>
<NumberAxis side="LEFT" />
</yAxis>
</LineChart>
</children>
</AnchorPane>
I have seen a similar question being asked, however my problem is that I want the stage to maintain full screen mode during the entirety of the scene change ie not simply adding stage.setFullScreen(true) at the end of it, which causes a momentary but very noticeable exit from full screen. Hiding the stage before changing scenes doesn't really help either, as there is a noticeable disappearance . Here's my code:
Main:
package sample;
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{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root));
primaryStage.setFullScreen(true);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller:
package sample;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class Controller {
#FXML
private AnchorPane pane;
#FXML
void doSomething(ActionEvent event) throws Exception {
Stage stage = (Stage) pane.getScene().getWindow();
Parent parent = FXMLLoader.load(getClass().getResource("sample2.fxml"));
Scene scene = new Scene(parent);
stage.setScene(scene);
stage.setFullScreen(true);
stage.show();
}
}
Sample:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="pane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-
Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0"
xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="sample.Controller">
<children>
<Button layoutX="180.0" layoutY="188.0" mnemonicParsing="false"
onAction="#doSomething" prefHeight="25.0" prefWidth="241.0" text="Do Something"
/>
</children>
</AnchorPane>
Sample2
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="pane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-
Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" style="-fx-background-color: blue;"
xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="sample.Controller">
<children>
<Button layoutX="180.0" layoutY="188.0" mnemonicParsing="false"
onAction="#doSomething" prefHeight="25.0" prefWidth="241.0" text="Do Something"
/>
</children>
</AnchorPane>
As you can see, if you run the code and press the button, there is a momentary exit from full screen. Is there any way to fix this, other than using the same fxml file?
Thanks a lot.
I didn't clearly understood what you are saying. I think you need a stage of size equals to Computer screen resolution and switch between the two screens. If yes then the following files will help you do so. If you want to come back to first scene from second scene then keep another button to load the first scene or keep a static variable and switch between the scenes by incrementing the variable and show the scene based on odd or even. Like for odd value of the variable show first scene and for even values show second scene.
Other process is getting the children of the stage. This gives you a ObservableList. Now clear the list and then add the respective scene to the list and show the stage.
Main class:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Screen;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
Scene scene = new Scene(root, 500, 200);
primaryStage.setScene(scene);
Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
//set Stage boundaries to visible bounds of the main screen
primaryStage.setX(primaryScreenBounds.getMinX());
primaryStage.setY(primaryScreenBounds.getMinY());
primaryStage.setWidth(primaryScreenBounds.getWidth());
primaryStage.setHeight(primaryScreenBounds.getHeight());
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller Class:
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Screen;
import javafx.stage.Stage;
public class Controller {
#FXML
private AnchorPane pane;
#FXML
void doSomething(ActionEvent event) throws Exception {
Stage stage = (Stage) pane.getScene().getWindow();
Parent parent = FXMLLoader.load(getClass().getResource("sample2.fxml"));
Scene scene = new Scene(parent, 500, 200);
stage.setScene(scene);
Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
//set Stage boundaries to visible bounds of the main screen
stage.setX(primaryScreenBounds.getMinX());
stage.setY(primaryScreenBounds.getMinY());
stage.setWidth(primaryScreenBounds.getWidth());
stage.setHeight(primaryScreenBounds.getHeight());
stage.show();
}
}
Here i want, if i wrote something on textarea and then click on button then the label will change as what i typed. But i can't handle the code properly.
Here is my source code---
ClickDemo.java-
package Application;
import java.io.FileInputStream;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class ClickDemo extends Application{
#Override
public void start(Stage stage) throws Exception {
FXMLLoader loader = new FXMLLoader();
// Path to the FXML File
String fxmlDocPath = "src/View/sample1.fxml";
FileInputStream fxmlStream = new FileInputStream(fxmlDocPath);
// Create the Pane and all Details
AnchorPane root = (AnchorPane) loader.load(fxmlStream);
// Create the Scene
Scene scene = new Scene(root);
// Set the Scene to the Stage
stage.setScene(scene);
// Set the Title to the Stage
stage.setTitle("A SceneBuilder Example");
// Display the Stage
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Sample1Controller.java
/*
* 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.
*/
package Controllers;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.input.MouseEvent;
/**
* FXML Controller class
*
* #author Dell
*/
public class Sample1Controller {
/**
* Initializes the controller class.
*/
#FXML
private Button btn;
#FXML
private Label label;
#FXML
private TextArea textarea;
#FXML
void btn1handle(ActionEvent event) {
// label.setText("Hello world");
textarea.textProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
//System.out.println(newValue);
label.setText(newValue);
}
});
}
#FXML
void textareaHandle(MouseEvent event) {
}
}
Sample1.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.111" fx:controller="Controllers.Sample1Controller">
<children>
<Button fx:id="btn" layoutX="274.0" layoutY="230.0" mnemonicParsing="false" onAction="#btn1handle" text="Button" />
<Label fx:id="label" layoutX="210.0" layoutY="58.0" prefHeight="42.0" prefWidth="233.0" text="This is Text 1">
<font>
<Font size="31.0" />
</font>
</Label>
<TextArea fx:id="textarea" layoutX="101.0" layoutY="121.0" onDragDetected="#textareaHandle" prefHeight="79.0" prefWidth="399.0" />
</children>
</AnchorPane>
The issue is that you have the wrong implementation of the method called btn1handle. You are adding the new listener to the textarea instead of setting textarea's text into the label. The implementation of the method btn1handle could be very simple:
#FXML
void btn1handle(ActionEvent event) {
label.setText(textarea.getText());
}
I've asked this question before but I couldn't offer a preferably a Minimal, Complete, and Verifiable example. So I made another sample which is correctly working and completely minimal. By the way, I want to change the color of a menu box which I click one of those, and it would be remain persistent whenever I click another item such as a button. Here's a sample below and please help me..again..
FXMLDocumentController.java
package javafxapplication1;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.binding.Bindings;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
/**
*
* #author James
*/
public class FXMLDocumentController implements Initializable {
#FXML
private VBox menuVBox1 = new VBox();
#FXML
private VBox menuVBox2 = new VBox();
#FXML
private VBox menuVBox3 = new VBox();
#FXML
private VBox parentMenuVBox = new VBox(menuVBox1, menuVBox2, menuVBox3);
private final Background focusBackground = new Background(new BackgroundFill(Color.web("#000000"), CornerRadii.EMPTY, Insets.EMPTY));
private final Background unfocusBackground = new Background(new BackgroundFill(Color.web("#F4F4F4"), CornerRadii.EMPTY, Insets.EMPTY));
private void setMenuBoxColor (VBox menu) {
VBox menuVBox = menu;
menuVBox.requestFocus();
for (Node child : parentMenuVBox.getChildren()) {
VBox vb = (VBox) child;
vb.backgroundProperty().bind(Bindings
.when(vb.focusedProperty())
.then(focusBackground)
.otherwise(unfocusBackground)
);
}
}
#FXML
private void handleSelectMenus(MouseEvent event) {
//Change the color of clicked VBox
setMenuBoxColor((VBox)event.getSource());
System.out.println("Menu clicked");
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
FXMLDocument.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="132.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication1.FXMLDocumentController">
<left>
<VBox fx:id="parentMenuVBox" prefHeight="200.0" prefWidth="100.0" spacing="10.0" BorderPane.alignment="CENTER">
<children>
<VBox fx:id="menuVBox1" onMouseClicked="#handleSelectMenus" prefHeight="200.0" prefWidth="100.0" style="-fx-border-color: #000000;">
<children>
<Label text="MENU1" />
</children>
</VBox>
<VBox fx:id="menuVBox2" layoutX="10.0" layoutY="10.0" onMouseClicked="#handleSelectMenus" prefHeight="200.0" prefWidth="100.0" style="-fx-border-color: #000000;">
<children>
<Label text="MENU2" />
</children>
</VBox>
<VBox fx:id="menuVBox3" layoutX="10.0" layoutY="160.0" onMouseClicked="#handleSelectMenus" prefHeight="200.0" prefWidth="100.0" style="-fx-border-color: #000000;">
<children>
<Label text="MENU3" />
</children>
</VBox>
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
</VBox>
</left>
<bottom>
<HBox prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
<Button mnemonicParsing="false" text="Next" />
</children>
</HBox>
</bottom>
</BorderPane>
javaFXApplication1.java
package javafxapplication1;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*
* #author James
*/
public class JavaFXApplication1 extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.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);
}
}
First set the unfocusBackground for all child vboxes, and then set focusBackground for only selected one.
public class FXMLDocumentController implements Initializable
{
#FXML
private VBox parentMenuVBox;
private final Background focusBackground = new Background( new BackgroundFill( Color.web( "#000000" ), CornerRadii.EMPTY, Insets.EMPTY ) );
private final Background unfocusBackground = new Background( new BackgroundFill( Color.web( "#F4F4F4" ), CornerRadii.EMPTY, Insets.EMPTY ) );
#FXML
private void handleSelectMenus( MouseEvent event )
{
// Set unfocusBackground for all child vboxes
for ( Node child : parentMenuVBox.getChildren() )
{
VBox vb = ( VBox ) child;
vb.setBackground( unfocusBackground );
}
// and set focusBackground for only selected one
VBox selected = ( VBox ) event.getSource();
selected.setBackground( focusBackground );
System.out.println( "Menu clicked" );
}
#Override
public void initialize( URL url, ResourceBundle rb )
{
}
}
I changed only the fxml controller from the code in the question.