How to use ControlsFX with javafx and FXML? - javafx

I'm new to Javafx and FXML and trying to import ControlsFX in scene builder and when I try to Run the java application it throws java.lang.ClassNotFoundException.
My Graphic Class is as follows,
I have not imported ControlsFX in java class file.
FXMLLoader loader = new FXMLLoader(getClass().getResource("homeUI.fxml"));
Parent root_ = loader.load();
primaryStage.initStyle(StageStyle.UNDECORATED);
Scene main_scene = new Scene(root_);
primaryStage.setScene(main_scene);
primaryStage.show();
My FXML file is as follows
<?xml version="1.0" encoding="UTF-8"?>
<?import com.gluonhq.charm.glisten.control.Icon?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" style="-fx-background-color: rgb(66,64,61);" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
<top>
<Icon content="HELP_OUTLINE" BorderPane.alignment="CENTER" />
</top>
</BorderPane>
I have imported this Icon from ControlsFX via Scene Builder.

Related

JavaFx : tab item does not fill the content

I have a TabPane declared like this :
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.TabPane?>
<TabPane fx:id="rootNode" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" stylesheets="#dark_theme.css" tabClosingPolicy="UNAVAILABLE" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controllers.AppController" />
And I want to add tabs from my controller. So I do :
jsonConfig.getAvailableChannelIds().forEach( chId -> {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("tab_item.fxml"));
Tab item = fxmlLoader.load();
item.setText(String.format("%d", chId));
rootNode.getTabs().add(item);
}catch (Exception e) {
e.printStackTrace();
}
});
"tab_item.fxml" looks as follows :
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.layout.VBox?>
<Tab xmlns:fx="http://www.w3.org/1999/XSL/Transform">
<VBox>
<fx:include source="test.fxml"/>
</VBox>
</Tab>
And finally "test.fxml" :
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" style="-fx-background-color: red;" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" />
And here is what I have :
What am I missing to fill the Tab content with the red square ?
Most layout panes, such as VBox, will by default try to size their content to the preferred size, and will make every attempt to keep the sizes within the constraints specified as the minimum and maximum.
I recommend reading the old Oracle layout tutorial. It was written a long time ago (before Java 8), so the code style is a bit out of date, but the layout concepts are all still relevant. Also read the Javadocs for the layout package, and presumably you already read the Javadocs for any layout component you are using (if not, you should always read the docs for the classes you use).
You have
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity"
minHeight="-Infinity" minWidth="-Infinity"
prefHeight="400.0" prefWidth="600.0"
style="-fx-background-color: red;"
xmlns="http://javafx.com/javafx/19"
xmlns:fx="http://javafx.com/fxml/1" />
which explicitly sets the preferred size to 600x400 pixels, and additionally sets the minimum and maximum sizes to -Infinity, which is the sentinel value Region.USE_PREF_SIZE. Therefore, the VBox will always size the content to 600x400 pixels (as long as there is enough space in the VBoxto do so).
Remove all those settings (I corrected the namespace too, though you don't really need it here):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane style="-fx-background-color: red;"
xmlns:fx="http://javafx.com/fxml" />
Now the VBox will still attempt to set the content to its preferred size, which by default is computed from its own content. Since the anchor pane is empty, that preferred size will be computed as 0x0. However, since the max size is now unconstrained, you can tell the VBox to let it grow:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.layout.VBox?>
<Tab xmlns:fx="http://javafx.com/fxml/">
<VBox fillWidth="true">
<fx:include source="test.fxml" VBox.vgrow="ALWAYS" />
</VBox>
</Tab>
Now the content defined in test.fxml will fill the VBox. The behavior of a Tab is to let its content fill the entire region of the tab, so the VBox will fill the tab.
Of course, it's not really clear why you are wrapping test.fxml in a VBox in the first place. Since the tab will be filled by its content by default, why not just simplify to
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Tab?>
<Tab xmlns:fx="http://javafx.com/fxml/">
<fx:include source="test.fxml" />
</Tab>
Here is a complete example, with all the unnecessary hard-coded sizes and redundant layout panes removed:
HelloApplication.java:
package org.jamesd.examples.tab;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
#Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 320, 240);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
hello-view.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.TabPane?>
<TabPane fx:id="rootNode"
tabClosingPolicy="UNAVAILABLE"
xmlns:fx="http://javafx.com/fxml/"
fx:controller="org.jamesd.examples.tab.AppController" />
AppController.java:
package org.jamesd.examples.tab;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
public class AppController {
#FXML
private TabPane rootNode ;
public void initialize() {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("tab_item.fxml"));
Tab item = fxmlLoader.load();
item.setText(String.format("%d", 42));
rootNode.getTabs().add(item);
}catch (Exception e) {
e.printStackTrace();
}
}
}
tab-item.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Tab?>
<Tab xmlns:fx="http://javafx.com/fxml/">
<fx:include source="test.fxml" />
</Tab>
and test.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane style="-fx-background-color: red;"/>
Ok, so I found at least a workaround here -> just wrap fx:include with AnchorsPane and it works :
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.layout.AnchorPane?>
<Tab xmlns:fx="http://www.w3.org/1999/XSL/Transform">
<content>
<AnchorPane>
<fx:include source="test.fxml" AnchorPane.topAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.leftAnchor="0" AnchorPane.bottomAnchor="0"/>
</AnchorPane>
</content>
</Tab>

Why the button does nothing? javafx

so i'm creating this application using javafx which has one login screen, but I've had no sucess at all in this, I have been working on this little part of the project for some days and it simply didn't work in any way I try to do it, I watched some tutorials and most of them were making like the codes below, yet it didn't work for me, if anyone can help me with that explaining why my label text doesn't change(that's how I'm testing if the login was sucessful) it would be nice, here are the codes:
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/view/telaLogin.fxml"));
stage.setTitle("morrer");
stage.setScene(new Scene(root, 380, 450));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller:
package controller;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.event.ActionEvent;
public class LoginController {
#FXML
private TextField username;
#FXML
private PasswordField pfSenha;
#FXML
private Label labelTeste;
public void login(ActionEvent event) throws Exception {
if(username.getText().equals("admin") && pfSenha.getText().equals("admin")) {
labelTeste.setText("sucess");
} else {
labelTeste.setText("fail");
}
}
}
FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.VBox?>
<BorderPane fx:id="telaLogin" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="333.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.LoginController">
<center>
<VBox alignment="CENTER" prefHeight="408.0" prefWidth="333.0" BorderPane.alignment="TOP_CENTER">
<children>
<TextField fx:id="username" alignment="TOP_CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="25.0" prefWidth="184.0" promptText="Usuáro">
<VBox.margin>
<Insets />
</VBox.margin>
</TextField>
<PasswordField fx:id="pfSenha" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="25.0" prefWidth="184.0" promptText=" Senha">
<VBox.margin>
<Insets top="50.0" />
</VBox.margin>
</PasswordField>
<Button fx:id="btnEntrar" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" text="Button">
<VBox.margin>
<Insets right="25.0" top="50.0" />
</VBox.margin>
</Button>
</children>
</VBox>
</center>
<bottom>
<Label fx:id="labelTeste" prefHeight="23.0" prefWidth="289.0" BorderPane.alignment="CENTER" />
</bottom>
</BorderPane>
Button does nothing because FX does not know it should call login method in your LoginController.
Following this FX GUI tutorial you have to specify called method in onAction attribute. So your button should be defined:
<Button onAction="#login" fx:id="btnEntrar" maxHeight="-Infinity" maxWidth="-Infinity"
minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" text="Button">

Unable to sucessufly create an Gluon project whit Glisten Afterburner on Intelij

I attempted to create a Gluon Mobile application whit the Glisten Afterburner framework on Intelij, however once i create it i cannot even launch it.
If i try to run the program i get the following error:
If i try to use scene builder in any of the fxml files:
My fxml code is the one generated by default:
<?xml version="1.0" encoding="UTF-8"?>
<?import com.gluonhq.charm.glisten.control.Icon?>
<?import com.gluonhq.charm.glisten.mvc.View?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.VBox?>
<View fx:id="primary" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="350.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.gluon.attempt.views.PrimaryPresenter">
<center>
<VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" spacing="15.0" BorderPane.alignment="CENTER">
<children>
<Label fx:id="label" text="%label.text.1" />
<Button mnemonicParsing="false" onAction="#buttonClick" text="%button.text">
<graphic>
<Icon content="LANGUAGE" />
</graphic>
</Button>
</children>
</VBox>
</center>
</View>
StackTrace:
ApplicationCode:
package com.gluon.attempt;
import com.gluon.attempt.views.AppViewManager;
import com.gluonhq.charm.glisten.application.MobileApplication;
import com.gluonhq.charm.glisten.visual.Swatch;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;
public class Attempt extends MobileApplication {
#Override
public void init() {
AppViewManager.registerViewsAndDrawer(this);
}
#Override
public void postInit(Scene scene) {
Swatch.BLUE.assignTo(scene);
((Stage) scene.getWindow()).getIcons().add(new Image(Attempt.class.getResourceAsStream("/icon.png")));
}
}

JavaFX: Button's width in custom gridpane

I would like to have buttons with equal(maximum) width in a gridpane.
When I'm trying to set it directly in FXML - it works perfectly.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.*?>
<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="TestController">
<children>
<GridPane AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.bottomAnchor="0"
AnchorPane.topAnchor="0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" percentWidth="50.0"/>
<ColumnConstraints hgrow="SOMETIMES" percentWidth="50.0"/>
</columnConstraints>
<children>
<Button maxWidth="Infinity" text="Button1" GridPane.columnIndex="0"/>
<Button maxWidth="Infinity" text="Button2" GridPane.columnIndex="1"/>
</children>
</GridPane>
</children>
</AnchorPane>
But when I wanted to separate the whole grid into a custom control, the buttons stopped to fill the available width.
Here's a FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<?import CustomGridPane?>
<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="TestController">
<children>
<CustomGridPane AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.bottomAnchor="0" AnchorPane.topAnchor="0">
</CustomGridPane>
</children>
</AnchorPane>
And an extension:
public class CustomGridPane extends GridPane {
private Button button1 = new Button("button1");
private Button button2 = new Button("button2");
public CustomGridPane() {
super();
button1.maxWidth(Double.MAX_VALUE);
button2.maxWidth(Double.MAX_VALUE);
getColumnConstraints().add(new ColumnConstraints());
getColumnConstraints().add(new ColumnConstraints());
getColumnConstraints().get(0).setPercentWidth(50);
getColumnConstraints().get(0).setHgrow(Priority.SOMETIMES);
getColumnConstraints().get(1).setPercentWidth(50);
getColumnConstraints().get(1).setHgrow(Priority.SOMETIMES);
add(button1, 0, 0);
add(button2, 1, 0);
}
}
Am I missing something?
You are using maxWidth property getter instead of the method setMaxWidth (setter).
Please see the documentation of Button here
public final double maxWidth(double height)
Called during layout to determine the maximum width for this node. Returns the value from computeMaxWidth(forHeight) unless the application overrode the maximum width by setting the maxWidth property.
Replace the two lines with maxWidth(...) by these ones:
button1.setMaxWidth(Double.MAX_VALUE);
button2.setMaxWidth(Double.MAX_VALUE);
This can be achieved inside scene builder also...
I required this, while creating a calculator, with the buttons inside gridpane.
Happy Coding (:

javaFX: styleClass is not working in jar file

It's working fine while I am running the application directly from eclipse. but after building the application using ant, generated jar file it's not working.
However if I removed Styleclass="theme" from fxml it's working fine using jar file as well
Java File
public class MainClass extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().
getResource("/resources/fxmlDocument/Sample.fxml"));
stage.setTitle("SAMPLE");
Scene scene= new Scene(root);
scene.getStylesheets().add(getClass().getClassLoader().
getResource("resources/css/sample.css").toExternalForm());
stage.setScene(scene);
stage.setResizable(false);
stage.show();
}
}
Fxml File:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.collections.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.cell.*?>
<?import javafx.scene.control.cell.PropertyValueFactory?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" styleClass="theme" xmlns:fx="http://javafx.com/fxml" fx:controller="com.integra.test.MainClassController">
<children>
<Label layoutX="300.0" layoutY="184.0" text="Great..!" />
<Button fx:id="clickbutton" layoutX="207.0" layoutY="184.0" mnemonicParsing="false" text="clickme" />
<TextField fx:id="text1" layoutX="207.0" layoutY="220.0" prefWidth="200.0" />
<Button fx:id="closebutton" layoutX="459.0" layoutY="318.0" mnemonicParsing="false" onAction="#closeButtonAction" prefHeight="37.0" prefWidth="75.0" text="Close" />
</children>
</AnchorPane>
You also use this for adding Style sheets to the controls.
control.getStylesheets().add
(MainClass.class.getResource("Sample.css").toExternalForm());
make sure css file in the same package or specify source path.
Second way is to use scene builder and add css using scene builder. You will get tutorial for this.

Resources