How to set font for label in JavaFx from root folder? - javafx

I have stored fonts for my project at *>root* directory inside *>font* directory.
I've tried using following code:
public class NewController implements Initializable {
#FXML
private Label titleLabel;
#Override
public void initialize(URL url, ResourceBundle rb) {
titleLabel.setFont(Font.loadFont("fonts/Archivo-Regular.ttf", 30));
}
}
But it can not set font.

You can add the font to the scene as Stylesheet
Your Class
scene.getStylesheets().add(getClass().getResource("/font.css").toExternalForm());
CSS File
#font-face {
font-family: 'Archivo';
src: url('font/Archivo-Regular.ttf');
}
After that you can easily add the font to the elements in the CSS
.label {
-fx-font-family: 'Archivo';
}
Or you can load the font in the Class. But load the font before using the style.
Class
Font.loadFont(NewController.class.getResource("Archivo-Regular.ttf").toExternalForm(), 30);
Edit
#FXML
Here is a little Example from this site.
#Override
public void initialize(URL url, ResourceBundle rb) {
text.setText("My Text!");
text.setFill(Color.RED);
text.setFont(Font.font("Arial", FontWeight.BOLD, FontPosture.ITALIC, 24));
}

Related

mvvmFX: Changing Part of a Scene on Runtime

I'm building a JavaFX Application with mvvmFX.
I have a scene with two panes. Both panes should include any.fxml . I would like to change the included panes at runtime.
So I've found this solution: JavaFX/SceneBuilder - Changing only PART of a Scene and tried to apply it.
So far, so good. Pane2 is displaying any.fxml, but unfortunately, the controller/viewModel is not getting loaded. At least it seems so, any.fxml contains a label which should get modified by the viewModel.
If O add fx:controller="anyVM" to any.fxml and include it via fx:include source="any.fxml" in pane2.fxml everything is working fine. But it's important for me to change it on runtime.
I would be glad if somebody knows a solution how to achieve this.
This is the View of my Main-Scene:
public class Scene implements FxmlView<SceneVM>, Initializable {
#FXML
private BorderPane pane2;
#InjectViewModel
private SceneVM sceneVM;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("any.fxml"));
loader.setController(anyVM.class);
try {
pane2.setCenter(loader.load());
} catch (IOException e) {
e.printStackTrace();
}
}
}
This is pane2 in scene.fxml:
<BorderPane fx:id="pane2" layoutX="846.0" prefHeight="547.0" prefWidth="521.0">
<center> <!--<fx:include source="any.fxml" />-->
</center>
</BorderPane>
This is the ViewModel / Controller
#Singleton
public class anyVM implements ViewModel {
private StringProperty lbl = new SimpleStringProperty("27");
public StringProperty getLbl(){
return basementViewKesselTempLbl;
}
public void setLbl(String message){
lbl.set(message);
}
}
In your example code of initialize you are using FXMLLoader which is part of standard JavaFX. However, to load a mvvmFX View with all setup logic you have to use mvvmFX's FluentViewLoader.
The FluentViewLoader uses FXMLLoader internally but does a whole lot more operations like injecting ViewModels into their Views.
So your code should look like this:
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
ViewTuple<AnyView, AnyViewModel> viewTuple = FluentViewLoader.fxmlView(AnyView.class).load();
pane2.setCenter(viewTuple.getView());
}

accessing a Pane from another class in javafx

I am unable to access from another class, I have created two pane with different controllers in one FXML File, second pane has to move around the first pane, on Click Action, and I have loaded an FXML file in second pane, also successfully moved the pane one time, but the second time I want to move it from second controller, but it is giving me an NullPointerException.
this is my main controller where I have moved the pane:
public class MainController implements Initializable {
#FXML
private Pane searchPane;
#FXML
private Pane secondPane;
private TranslateTransition nextTransition;
public Pane getSecondPane() {
return secondPane; // Accessing Pane with this getter method
}
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
}
#FXML
private void nextBtnAction(ActionEvent event) {
try {
Parent pessFxml = FXMLLoader.load(getClass().getResource("firstPane.fxml"));
secondPane.getChildren().add(pessFxml);
nextTransition = new TranslateTransition(Duration.millis(300), secondPane);
nextTransition.setToX(searchPane.getLayoutX()-secondPane.getLayoutX());
nextTransition.play();
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Form does not found" ,ex.toString(),0);
}
}
}
this is SecondController where I am accessing the pane to move it back smoothly, but its throwing NullPointerException:
please tell me how to solve this
public class SecondController implements Initializable {
MainController mainControll;
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
}
#FXML
private void backBtnPessAction(ActionEvent event) {
//here i am putting the second pane to move back
TranslateTransition back = new TranslateTransition(Duration.millis(300), mainControll.getSecondPane());
back.setToX(mainControll.getSecondPane().getLayoutX()-750);
back.play();
}
}
MainController is never initialized in SecondController. You should pass it when creating second controller in nextBtnAction.
MainController code:
private void nextBtnAction(ActionEvent event) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("firstPane.fxml"));
Parent pessFxml = loader.load();
SecondController controller = (SecondController)loader.getController();
controller.setMainController(this);
secondPane.getChildren().add(pessFxml);
nextTransition = new TranslateTransition(Duration.millis(300), secondPane);
nextTransition.setToX(searchPane.getLayoutX()-secondPane.getLayoutX());
nextTransition.play();
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Form does not found" ,ex.toString(),0);
}
}
SecondController:
public void setMainController(MainController controller) {
this.mainControll = controller;
}

JavaFx event like Onload

like on Click for buttons , wanna do the the same thing for the load of my screen , i'am using scene builder.
Here is my code:
public class CModifierBoutique implements ControlledScreen{
#FXML
ChoiceBox<String> box;
ScreensController myController;
#Override
public void setScreenParent(ScreensController screenPage) {
myController = screenPage;
}
#FXML
private void goToMain(ActionEvent event){
myController.setScreen(ScreensFramework.screen1ID);
}
#FXML
private void inialize(ActionEvent event){
System.out.println(" there is the method who must be start on load this screen ");
System.out.println("my code is requesting the data base and the result");
System.out.println("will be added to my choisebox");
BoutiqueDao dao=new BoutiqueDao();
List<Boutique> li=dao.DisplayAll();
}
}
I think you are just looking for the initialize() method. Either your controller can implement the Initializable interface and do
public class CModifierBoutique implements ControlledScreen, Initializable {
// existing code..
#Override
public void initialize(URL location, ResourceBundle resources) {
// initialization code here...
}
}
or you can just include a no-argument method called initialize():
public class CModifierBoutique implements ControlledScreen {
// existing code..
public void initialize() {
// initialization code here...
}
}

Changing the text of a label from a different class in JavaFX

This question was already asked here but was not able to find any answers. I have reproduced a similar situation where I would like to change the text of a label from another class using the controller
FXMLDocumentController.java
public class FXMLDocumentController implements Initializable {
#FXML
private Label label;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("FXMLDocumentController.#handleButtonAction");
label.setText("Hello World!");
Connector.Connecting();
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
public void setLabelText(String text)
{
System.out.println("FXMLDocumentController.setLabelText(): Called");
label.setText(text);
}
}
FXMLDocument.fxml
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="demo5.FXMLDocumentController">
<children>
<Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
<Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
</children>
</AnchorPane>
Demo5.java
public class Demo5 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);
}
}
Connector.java
public class Connector {
public static void Connecting() {
try {
System.out.println("Connector.Connecting(): Called");
FXMLLoader loader = new FXMLLoader(FXMLDocumentController.class.getResource("FXMLDocument.fxml"));
loader.load();
FXMLDocumentController controller = (FXMLDocumentController) loader.getController();
controller.setLabelText("Bye World");
} catch (IOException ex) {
Logger.getLogger(Connector.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Output at Console
Connector.Connecting(): Called
FXMLDocumentController.setLabelText(): Called
But could see no changes in the label. Am I missing something major here ?
You can change your Connector class to receive the Controller instance:
public class Connector {
public static void Connecting(FXMLDocumentController controller) {
try {
System.out.println("Connector.Connecting(): Called");
controller.setLabelText("Bye World");
} catch (IOException ex) {
Logger.getLogger(Connector.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public class FXMLDocumentController implements Initializable {
#FXML
private Label label;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("FXMLDocumentController.#handleButtonAction");
label.setText("Hello World!");
Connector.Connecting(this);
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
public void setLabelText(String text)
{
System.out.println("FXMLDocumentController.setLabelText(): Called");
label.setText(text);
}
}
Note:
If your Connector is going to take longer to execute whatever it needs to, you might want to use a Task, so you don't freeze your UI. To update the Label, you have to bind the text property and then update the Text value using the updateMessage() method.
public class FXMLDocumentController implements Initializable {
#FXML
private Label label;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("FXMLDocumentController.#handleButtonAction");
label.setText("Hello World!");
Task<Boolean> connectorTask = new ConnectorTask();
label.textProperty().bind(connectorTask.messageProperty());
connectorTask.setOnSucceeded(e -> {
// this is going to be called if the task ends up without error
label.textProperty().unbind();
});
new Thread(connectorTask).start();
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
//public void setLabelText(String text)
//{
// System.out.println("FXMLDocumentController.setLabelText(): Called");
// label.setText(text);
//}
public class ConnectorTask extends Task<Boolean> {
#Override
protected Boolean call() throws Exception {
// ... do whatever you need here
// then you call this method to update the TextProperty from the Label that was bound.
updateMessage("Bye World");
return Boolean.TRUE;
}
}
}
Your Demo5 class and Connector class are both creating unique instances of the FXMLDocumentController via the call to FXMLLoader.load(). The instance in the Demo5 class is being placed in the scene graph and becomes visible. The instance in the connector is not being made visible. When you call setLabelText() it is changing the text for an unseen label. What you may want to do is get the FXMLDocumentController instance in Demo5 and provide it to the Connector class through the constructor or a setter method. You may need to change some things around depending on what the Connector class is used for. Alternatively, you could use the connector class to load the FXML root and controller and provide methods for accessing them, then use those methods in Demo5 to make the scene visible.
I made it in a simple way by defining the Label as static in the FXMLDocumentController.java:
#FXML GridPane myGridPane;
public static Label totLabel = new Label("Total");
and add it to myGridPane in the initialize method of FXMLDocumentController class:
#Override
public void initialize(URL url, ResourceBundle rb) {
myGridPane.add(totLabel, 0, 3);
}
and at any other class you can call the setText() of this label like this:
String message = "this message will appear in the total label";//your string
FXMLDocumentController.totLabel.setText(message);

#FXML public static vars in javafx? [duplicate]

This question already has an answer here:
javafx 8 compatibility issues - FXML static fields
(1 answer)
Closed 8 years ago.
I'm introducing in javafx and i found it very interesting. But I have got a problem that i can't solve.
In the simplest case of a Hello World I can't put a #FXML public static var like this:
public class FXMLDocumentController implements Initializable
{
#FXML
public static Label label;
#FXML
private void handleButtonAction(ActionEvent event)
{
System.out.println("You clicked me!");
label.setText("Hello World!");
}
}
If I change it to private it works.
The cause of that I want to made this vars publics is because I'm using diferents controllers for diferents views (in my real app) and i want to communicate between theirs.
PS: Sorry for my bad english
You should not use a static field here. Your controller belongs to one view and every time the view is created by the FXML Loader new instances of all nodes in the view will be created. SO by calling the FXML Loader 2 times you will receive 2 instances of the view. In addition a new instance of your controller class will be created whenever you load the view by using the FXML viewer. By using a static field you will override values of old controller instances and this will end in horrible bugs. Here is a short introduction to the static keyword: What does the 'static' keyword do in a class?
If you just remove "static" it will work.
Instead of using public fields you should add getter and setter methods to your controller class and mark the field as private: Why use getters and setters?
I want to do something similar like this:
I'm working with tabs and i have this two controllers:
FXML_Tab1Controller.java:
public class FXML_Tab1Controller implements Initializable {
FXML_Tab2Controller tab2controller;
#FXML public Label Label1;
#FXML public TextField TextField1;
#FXML public Button Button1;
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
#FXML private void actionButton1(ActionEvent event)
{
Label1.setText(tab2controller.TextField2.getText());
}
}
FXML_Tab2Controller.java:
public class FXML_Tab2Controller implements Initializable {
FXML_Tab1Controller tab1controller;
#FXML public Label Label2;
#FXML public TextField TextField2;
#FXML public Button Button2;
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
#FXML private void actionButton2(ActionEvent event){
Label2.setText(tab1controller.TextField1.getText());
}
}
something similar like that video:
https://www.youtube.com/watch?v=XLVx46ycxco

Resources