JavaFx2 OutOfMemoryError:Java heap space - javafx

I creat a simple JavaFx application with FXML and CSS in order to change UI Theme at runtime.
There are three Button and one Label in the scene. I define different CSS for Label and "-fx-background-image"(PNG format, size 1.23M) for BorderPane in the CSS file.
Application can switch UI Theme by click "Style" Button.
But Mem usage will raise and don't free when I click one of "Style" Button. Application will OutOfMemoryError after switch Theme about 30 times. I don't know how to fix it.Someone can help me?
java.lang.OutOfMemoryError: Java heap space
at java.awt.image.DataBufferInt.<init>(DataBufferInt.java:75)
at java.awt.image.Raster.createPackedRaster(Raster.java:467)
at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1032)
at java.awt.image.BufferedImage.<init>(BufferedImage.java:359)
at com.sun.prism.j2d.J2DTexture.<init>(J2DTexture.java:46)
at com.sun.prism.j2d.J2DResourceFactory.createTexture(J2DResourceFactory.java:72)
at com.sun.prism.impl.BaseResourceFactory.createTexture(BaseResourceFactory.java:127)
My environment: jdk1.7.0_51, Windows Server 2003 x86, 3G RAM
I am sorry that I don't know how to post IMG file(background.png) to forum.
Click "AutoSwitch" Button for auto Switching Theme.
Source Code:
Main.Java
public class Main extends Application {
private Stage primaryStage;
public Stage getPrimaryStage() {
return primaryStage;
}
public void setPrimaryStage(Stage primaryStage) {
this.primaryStage = primaryStage;
}
private BorderPane rootPane;
public BorderPane getRootPane() {
return rootPane;
}
#Override
public void start(Stage primaryStage) {
try {
setPrimaryStage(primaryStage);
URL url = new URL(getClass().getResource("AppFrame.fxml").toExternalForm());
FXMLLoader loader =new FXMLLoader(url);
rootPane = (BorderPane)loader.load();
Scene scene = new Scene(rootPane,400,400);
primaryStage.setScene(scene);
//MAX screen
Screen screen = Screen.getPrimary();
Rectangle2D bounds = screen.getVisualBounds();
primaryStage.setX(bounds.getMinX());
primaryStage.setY(bounds.getMinY());
primaryStage.setWidth(bounds.getWidth());
primaryStage.setHeight(bounds.getHeight());
primaryStage.show();
AppFrameController appFrameController = (AppFrameController)loader.getController();
appFrameController.setAppMain(this);
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
AppFrameController.java
public class AppFrameController {
private String style1Url = getClass().getResource("FxStyle1.css").toExternalForm();
private String style2Url = getClass().getResource("FxStyle2.css").toExternalForm();
#FXML private Label lblSceneTitle;
private Main appMain;
public Main getAppMain() {
return appMain;
}
public void setAppMain(Main appMain) {
this.appMain = appMain;
}
private int switchCount=0;
public AppFrameController()
{
}
public void handleClickStyle1()
{
ObservableList<String> stylesheets = getAppMain().getRootPane().getStylesheets();
stylesheets.remove(style2Url);
if(!stylesheets.contains(style1Url))
{
stylesheets.add(style1Url);
}
}
public void handleClickStyle2()
{
ObservableList<String> stylesheets = getAppMain().getRootPane().getStylesheets();
stylesheets.remove(style1Url);
if(!stylesheets.contains(style2Url))
{
stylesheets.add(style2Url);
}
}
public void handleClickSwitch()
{
SwitchCssTask handleTask = new SwitchCssTask();
new Thread(handleTask).start();
}
private class SwitchCssTask implements Runnable {
#Override
public void run() {
while (true) {
if (switchCount % 2 == 0) {
handleClickStyle1();
} else {
handleClickStyle2();
}
switchCount++;
System.out.println("Switch count=" + switchCount);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
AppFrame.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane prefHeight="362.0" prefWidth="749.3739013671875" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="application.AppFrameController">
<!-- TODO Add Nodes -->
<center>
<BorderPane id="center-pane" prefHeight="-1.0" prefWidth="-1.0" BorderPane.alignment="CENTER">
<center>
<VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" spacing="20.0">
<children>
<Button mnemonicParsing="false" onAction="#handleClickStyle1" prefHeight="70.0" prefWidth="148.0" text="Style1" />
<Button mnemonicParsing="false" onAction="#handleClickStyle2" prefHeight="70.0" prefWidth="148.0" text="Style2" />
<Button mnemonicParsing="false" onAction="#handleClickSwitch" prefHeight="70.0" prefWidth="148.0" text="AutoSwitch" />
</children>
</VBox>
</center>
</BorderPane>
</center>
<stylesheets>
<URL value="#FxStyle2.css" />
</stylesheets>
<top>
<HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" spacing="10.0" BorderPane.alignment="CENTER">
<children>
<Label id="scene-title" fx:id="lblSceneTitle" alignment="TOP_CENTER" prefWidth="371.0" text="Test FxStyle" />
</children>
<padding>
<Insets bottom="15.0" left="12.0" right="12.0" top="15.0" />
</padding>
</HBox>
</top>
</BorderPane>
FxStyle1.css
#center-pane {
-fx-background-image: url("background.png");
}
#scene-title {
-fx-font-family: "Tahoma";
-fx-background-insets: 0;
-fx-text-fill: green;
-fx-font-weight: bold;
-fx-font-size: 4em;
-fx-effect: dropshadow( one-pass-box , rgba(0,0,0,0.9) , 1, 0.0 , 0 , 1 );
}
FxStyle2.css
#center-pane {
-fx-background-image: url("background.png");
}
#scene-title {
-fx-font-family: "Courier New";
-fx-background-insets: 0;
-fx-text-fill: red;
-fx-font-weight: bold;
-fx-font-size: 4em;
-fx-effect: dropshadow( one-pass-box , rgba(0,0,0,0.9) , 1, 0.0 , 0 , 1 );
}

I get answer from Oracle Communtiy.
please see here.

Related

JavaFX theme switch button

I am currently creating the game PacMan using JavaFX MVC. I made an FXML file using SceneBuilder.
I have also added 2 themes: a classic theme and an X-Mas theme. The thing I want to do now is switch themes using a button which is created in the FXML file (see image: buttons 'classic' & 'xmas'.
Please help me out.
This is how it looks like:
This is my current code:
FXMLSideMenucontroller.fxml
package sidemenu;
import com.jfoenix.controls.JFXButton;
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
public class FXMLSideMenuController implements Initializable {
#FXML
private AnchorPane ap_main;
#FXML
private AnchorPane ap_gamefield;
#FXML
private Pane pnl_highscore;
#FXML
private Pane pnl_main;
#FXML
private Pane pnl_moeilijkheid;
#FXML
private VBox vbox_moeilijkheid;
#FXML
private JFXButton btn_easy;
#FXML
private JFXButton btn_medium;
#FXML
private JFXButton btn_hard;
#FXML
private Pane pnl_credits;
#FXML
private Pane pnl_spelers;
#FXML
private JFXButton btn_mraerts;
#FXML
private ImageView iview_mraerts;
#FXML
private JFXButton btn_mrlemmens;
#FXML
private ImageView iview_mrlemmens;
#FXML
private Pane pnl_thema;
#FXML
private VBox vbox_thema;
#FXML
private JFXButton btn_classic;
#FXML
private JFXButton btn_xmas;
#FXML
private AnchorPane ap_sidemenu;
#FXML
private AnchorPane ap_sidepane;
#FXML
private JFXButton btn_spelers;
#FXML
private JFXButton btn_moeilijkheid;
#FXML
private JFXButton btn_thema;
#FXML
private JFXButton btn_highscore;
#FXML
private JFXButton btn_credits;
#FXML
private FontAwesomeIconView iview_spelers;
#FXML
private FontAwesomeIconView iview_niveau;
#FXML
private FontAwesomeIconView iview_thema;
#FXML
private FontAwesomeIconView iview_highscore;
#FXML
private FontAwesomeIconView iview_credits;
#FXML
private void handleButtonAction(ActionEvent event) {
if(event.getSource() == btn_spelers) {
pnl_spelers.toFront();
} else
if(event.getSource() == btn_moeilijkheid) {
pnl_moeilijkheid.toFront();
} else
if(event.getSource() == btn_thema) {
pnl_thema.toFront();
} else
if(event.getSource() == btn_highscore) {
pnl_highscore.toFront();
} else
if(event.getSource() == btn_credits) {
pnl_credits.toFront();
}
}
/**
#FXML
private void handleThemeSwitcher(ActionEvent event) {
if(event.getSource() == btn_classic) {
scene.getStylesheets().remove(getClass().getResource("Resources/style.css").toExternalForm());
scene.getStylesheets().remove(getClass().getResource("Resources/xmas.css").toExternalForm());
scene.getStylesheets().add(getClass().getResource("Resources/style.css").toExternalForm());// Load voor custom stylesheet
}
if(event.getSource() == btn_xmas) {
scene.getStylesheets().remove(getClass().getResource("Resources/style.css").toExternalForm());
scene.getStylesheets().remove(getClass().getResource("Resources/xmas.css").toExternalForm());
scene.getStylesheets().add(getClass().getResource("Resources/xmas.css").toExternalForm());// Load voor custom stylesheet
}
} */
/** #FXML
private void closeMenuItem(ActionEvent event) {
if(event.getSource() == icon_close) {
pnl_main.toFront();
}
}*/
#Override
public void initialize(URL location, ResourceBundle resources) {
pnl_main.toFront();
}
}
SideMenu.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 sidemenu;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.text.Font;
import javafx.stage.Stage;
/**
*
* #author User
*/
public class SideMenu extends Application {
#Override
public void start(Stage stage) throws Exception {
Font.loadFont(
SideMenu.class.getResource("Resources/CrackMan.TTF").toExternalForm(),
10); // Load voor custom font
Parent root = FXMLLoader.load(getClass().getResource("FXMLSideMenu.fxml"));
Scene scene = new Scene(root);
//scene.getStylesheets().add(getClass().getResource("Resources/style.css").toExternalForm());// Load voor custom stylesheet
stage.setTitle("PacMan");
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Style.css
/* Classic */
#ap_sidemenu {
-fx-background-color: #1919A6;
}
#ap_sidepane {
-fx-background-color: #a8a8a8;
}
#pnl_main {
-fx-background-color: #FFFF00;
}
#pnl_spelers {
-fx-background-color: #FFFF00;
}
#pnl_moeilijkheid {
-fx-background-color: #FFFF00;
}
#pnl_thema {
-fx-background-color: #FFFF00;
}
#pnl_highscore {
-fx-background-color: #FFFF00;
}
#pnl_credits {
-fx-background-color: #FFFF00;
}
.button {
-fx-background-radius: 50;
-fx-font-family: CrackMan;
-fx-font-size: 26;
}
.button:hover {
-fx-background-color: #1919A6;
-fx-background-radius: 50;
-fx-font-family: CrackMan;
-fx-font-size: 26;
-fx-border-color: black;
-fx-border-radius: 50;
-fx-border-width: 1;
-fx-text-fill: white;
}
.button:pressed {
-fx-background-color: #1919A6;
-fx-background-radius: 50;
-fx-font-family: CrackMan;
-fx-font-size: 26;
-fx-border-color: black;
-fx-border-radius: 50;
-fx-border-width: 3;
-fx-text-fill: white;
-fx-rotate: 2;
}
.button:focused {
-fx-background-color: #1919A6;
-fx-background-radius: 50;
-fx-font-family: CrackMan;
-fx-font-size: 26;
-fx-text-fill: darkgrey;
}
xmas.css
/* X-Mas*/
#ap_sidemenu {
-fx-background-color: #165B33;
}
#ap_sidepane {
-fx-background-color: #BB2528;
}
#pnl_main {
-fx-background-color: #F8B229;
}
#pnl_spelers {
-fx-background-color: #F8B229;
}
#pnl_moeilijkheid {
-fx-background-color: #F8B229;
}
#pnl_thema {
-fx-background-color: #F8B229;
}
#pnl_highscore {
-fx-background-color: #F8B229;
}
#pnl_credits {
-fx-background-color: #F8B229;
}
.button {
-fx-background-radius: 50;
-fx-font-family: CrackMan;
-fx-font-size: 26;
}
.button:hover {
-fx-background-color: #EA4630;
-fx-background-radius: 50;
-fx-font-family: CrackMan;
-fx-font-size: 26;
-fx-border-color: #146B3A;
-fx-border-radius: 50;
-fx-border-width: 1;
-fx-text-fill: white;
}
.button:pressed {
-fx-background-color: #BB2528;
-fx-background-radius: 50;
-fx-font-family: CrackMan;
-fx-font-size: 26;
-fx-border-color: #165B33;
-fx-border-radius: 50;
-fx-border-width: 3;
-fx-text-fill: white;
-fx-rotate: 2;
}
.button:focused {
-fx-background-color: #BB2528;
-fx-background-radius: 50;
-fx-font-family: CrackMan;
-fx-font-size: 26;
-fx-text-fill: darkgrey;
}
You can do this doing this:
First, create the urls for both themes:
private String urlTheme1 = getClass().getResource("css1.css").toExternalForm();
private String urlTheme2 = getClass().getResource("css2.css").toExternalForm();
And when click on the "Change Style" button, you can do something like this:
changeStylebtn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
//Remove from scene the theme1(asumming you added to your scene when your app starts)
scene.getStylesheets().remove(urlTheme1);
//Add the new theme
scene.getStylesheets().add(urlTheme2);
}
}
this will do the trick.

Scrollbar doesn't appear when scrolling

I'm using HiddenSidesPane to show and hide scrollbar when needed. Scrollbar appears when I move mouse to the edge of the ScrollPane and hides when I move back. However, I have a problem to show scrollbar when the scrolling is detected. You can find my code below:
FXML:
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.layout.VBox?>
<?import org.controlsfx.control.HiddenSidesPane?>
<?import java.net.URL?>
<ScrollPane xmlns:fx="http://javafx.com/fxml"
fx:controller="hypermap.components.featurespanel.view.properties.PropertiesTab" fx:id="propertyTabRoot"
fitToWidth="true" hbarPolicy="NEVER" vbarPolicy="NEVER">
<stylesheets>
<URL value="#Scrollbar.css"/>
</stylesheets>
<HiddenSidesPane fx:id="hiddenSidesPane" minWidth="280">
<content>
<VBox fx:id="vboxInsideScroll">
<VBox fx:id="groupsContainer"/>
<VBox fx:id="messageContainer"/>
</VBox>
</content>
</HiddenSidesPane>
</ScrollPane>
CSS file:
.scroll-pane{
-fx-focus-color: none;
-fx-background-color: transparent;
}
.scroll-bar > .increment-button, .decrement-button, .increment-arrow, .decrement-arrow{
-fx-pref-height: 0;
}
.scroll-bar:vertical{
-fx-background-color: transparent;
-fx-border-color: transparent;
-fx-pref-width: 10;
-fx-padding: 0;
}
.scroll-bar:vertical .thumb{
-fx-background-color: color-dark-slate;
-fx-border-radius: 100;
-fx-padding: 0 4 0 0;
-fx-opacity: 0.2
}
.scroll-bar:vertical .track{
-fx-background-color: transparent;
}
Controller file with method using HiddenSidesPane:
#FXML
private VBox groupsContainer;
#FXML
private VBox messageContainer;
#FXML
private ScrollPane propertyTabRoot;
#FXML
private HiddenSidesPane hiddenSidesPane;
private void makeScrollable(ScrollPane scrollPane) {
final Node scrollbar = scrollPane.lookup(".scroll-bar:vertical");
hiddenSidesPane.setRight(scrollbar);
hiddenSidesPane.setTriggerDistance(40);
hiddenSidesPane.setAnimationDuration(Duration.millis(500));
scrollPane.setOnScroll((event -> {
hiddenSidesPane.setRight(scrollbar);
event.consume();
}));
I would be very grateful for any help. Also, I don't know why the scrollbar's thumb has the same hight all the time, even if the content is so huge that it should be smaller.
Thank you!

how tp set the different font fill text color for selected label in a JFXListView?

I've create a JFXListView in th FXML file :
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<JFXListView fx:id="listName" layoutX="-1.0" layoutY="-5.0" />
</children>
</AnchorPane>
and injected in controller
#FXML
private JFXListView<Label> listName;
then I fill the JFXListView with labels
public void loadListAdsTarget(){
listName.setVerticalGap(7.0);
for (int i = 0; i < 4; i++) {
listName.getItems().add(new Label("name " +i+ " desc : text text text"));
}
listName.getStyleClass().add("mylistview");
listName.depthProperty().set(1);
listName.setExpanded(true);
}
I tried to change the color of the selected label by css, but I did not get a good result by changing the text to white.
.mylistview .label {
-fx-text-fill: #a0a2ab;
}
.mylistview:selected .label:selected {
-fx-text-fill: red;
}
.mylistview:focused .label:selected {
-fx-text-fill: while;
}
.mylistview .list-cell:selected {
-fx-background-color: #2196f3;
}
.mylistview .list-cell {
-fx-background-color: #282d40;
}
Add this section of css to your file and it will change the selected text color
.mylistview .list-cell:selected .label{
-fx-text-fill: rgb(20, 20, 20);
}
You can also remove this section
.mylistview:focused .label:selected {
-fx-text-fill: while;
}

CSS and JavaFX - CSS in a TableView

I want to apply css in all of my upper side of the tableview, the following photo show the part I want to apply the css (The part at the side of the column "Estado")
enter image description here
here's my css:
.table-view{
-fx-background-color: transparent;
}
.table-view:focused{
-fx-background-color: transparent;
}
.table-view .column-header-background{
-fx-background-color: linear-gradient(#101010 0%, #424141 100%);
}
.table-view .column-header-background .label{
-fx-background-color: transparent;
-fx-text-fill: white;
}
.table-view .column-header {
-fx-background-color: transparent;
}
.table-view .table-cell{
-fx-text-fill: white;
}
.table-row-cell{
-fx-background-color: -fx-table-cell-border-color, #616161;
-fx-background-insets: 0, 0 0 1 0;
-fx-padding: 0.0em;
}
.table-row-cell:odd{
-fx-background-color: -fx-table-cell-border-color, #424242;
-fx-background-insets: 0, 0 0 1 0;
-fx-padding: 0.0em;
}
.table-row-cell:selected {
-fx-background-color: #005797;
-fx-background-insets: 0;
-fx-background-radius: 1;
}
The part is white because it isn't a column of my tableview, so I want to know how to apply CSS in empty parts (without columns) in the table.
FXML code:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<HBox prefHeight="300.0" prefWidth="773.0"
stylesheets="/iftorrent/gui/menuPrincipal/MenuPrincipalCSS.css"
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="iftorrent.gui.menuPrincipal.MenuPrincipalControlador">
<children>
<TableView fx:id="tabela" prefWidth="773.0">
<columns>
<TableColumn fx:id="numero" prefWidth="35.0" text="NÂș " />
<TableColumn fx:id="nome" prefWidth="183.0" text="Nome" />
<TableColumn fx:id="tamanho" prefWidth="76.0" text="Tamanho" />
<TableColumn fx:id="velocidade" prefWidth="76.0" text="Velocidade" />
<TableColumn fx:id="tempo_estimado" prefWidth="120.0" text="Tempo Estimado" />
<TableColumn fx:id="estado" prefWidth="283.0" text="Estado" />
<TableColumn fx:id="progresso" prefWidth="283.0" text="Progresso" />
</columns>
</TableView>
</children>
</HBox>
You are looking for the .filler inside the .column-header-background. Add this rule:
.table-view .column-header-background .filler {
-fx-background-color: linear-gradient(#101010 0%, #424141 100%);
}
For reference, you can use the JavaFX CSS Reference, or use the CSS Analyzer tool built into SceneBuilder.

Using both CSS and setStyle

I have an object where I have css stylizing the object. In my program I would like to change specific elements in the styling such as background color. The problem that I have run into was that when I call setStyle(-fx-background-color:red) it will override all the styling elements. Even if I just change background color.
#header {
-fx-background-color: #4d4d4d;
-fx-border-color: #545454;
-fx-border-width: 1px;
-fx-border-style: solid;
}
#header:hover {
-fx-background-color: #9ACD32;
}
You should define your colors in your CSS using "looked up colors".
See the JavaFX CSS reference for details.
Looked-up Colors
With looked-up colors you can refer to any other color property that is set on the current node or any of its parents. This is a very powerful feature, as it allows a generic palette of colors to be specified on the scene then used thoughout the application. If you want to change one of those palette colors you can do so at any level in the scene tree and it will affect that node and all its decendents. Looked-up colors are not looked up until they are applied, so they are live and react to any style changes that might occur, such as replacing a palette color at runtime with the "style" property on a node.
In the following example, all background color of all buttons uses the looked up color "abc".
.root { abc: #f00 }
.button { -fx-background-color: abc }
Sample Application
In the sample application, the key code is the setting of the looked up color value dynamically in code:
headerColorToggleGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
#Override
public void changed(
ObservableValue<? extends Toggle> observableValue,
Toggle oldToggle,
Toggle newToggle
) {
RadioButton radio = (RadioButton) newToggle;
header.setStyle("header-base-color: " + radio.getText());
}
});
Together with the definition of the header-base-color lookup id for the color in the css below:
header-color.css
.root {
header-base-color: #4d4d4d;
}
#header {
-fx-background-color: header-base-color;
-fx-border-color: #545454;
-fx-border-width: 1px;
-fx-border-style: solid;
}
#header:hover {
-fx-background-color: #9ACD32;
}
header-color.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?scenebuilder-stylesheet header-color.css?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import java.net.URL?>
<BorderPane id="BorderPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="-1.0" prefWidth="-1.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="HeaderColorController">
<top>
<HBox fx:id="header" prefHeight="-1.0" prefWidth="-1.0">
<children>
<Label text="A really hard to read label" />
</children>
</HBox>
</top>
<center>
<VBox prefHeight="-1.0" prefWidth="-1.0" spacing="10.0" style="-fx-background-color: azure;">
<children>
<RadioButton mnemonicParsing="false" style="-fx-text-fill: forestgreen;" text="forestgreen">
<toggleGroup>
<ToggleGroup fx:id="headerColorToggleGroup" />
</toggleGroup>
</RadioButton>
<RadioButton mnemonicParsing="false" style="-fx-text-fill: firebrick;" text="firebrick" toggleGroup="$headerColorToggleGroup" />
<RadioButton mnemonicParsing="false" selected="true" style="-fx-text-fill: #4d4d4d;" text="#4d4d4d" toggleGroup="$headerColorToggleGroup" />
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
</VBox>
</center>
<stylesheets>
<URL value="#header-color.css" />
</stylesheets>
</BorderPane>
HeaderColorApp.java
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class HeaderColorApp extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("header-color.fxml"));
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
public static void main(String[] args) { launch(args); }
}
HeaderColorController.java
import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.value.*;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
public class HeaderColorController {
#FXML
private ResourceBundle resources;
#FXML
private URL location;
#FXML
private HBox header;
#FXML
private ToggleGroup headerColorToggleGroup;
#FXML
void initialize() {
assert header != null : "fx:id=\"header\" was not injected: check your FXML file 'header-color.fxml'.";
assert headerColorToggleGroup != null : "fx:id=\"headerColorToggleGroup\" was not injected: check your FXML file 'header-color.fxml'.";
headerColorToggleGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
#Override
public void changed(ObservableValue<? extends Toggle> observableValue, Toggle oldToggle, Toggle newToggle) {
RadioButton radio = (RadioButton) newToggle;
header.setStyle("header-base-color: " + radio.getText());
}
});
}
}

Resources