Java FX fxml on Action - java

I want to add a method to a button which is defined in my Controller class
in the console is only an error which tells me that it couldn't find the method
here is the code
sample.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.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml" fx:controller="sample.Controller">
<children>
<Button layoutX="126" layoutY="90" text="lololol" onAction="#test" fx:id="button" />
</children>
</AnchorPane>
and the Controller.java
package sample;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import java.awt.event.ActionEvent;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable
{
#Override
public void initialize(URL url, ResourceBundle resourceBundle)
{
}
#FXML
private void test(ActionEvent event)
{
System.out.println("lollolol");
}
}

Replace:
import java.awt.event.ActionEvent;
with:
import javafx.event.ActionEvent;

Related

Why does my controller seem to not have the event slot 'onShowClick'? [duplicate]

I want to add a method to a button which is defined in my Controller class
in the console is only an error which tells me that it couldn't find the method
here is the code
sample.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.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml" fx:controller="sample.Controller">
<children>
<Button layoutX="126" layoutY="90" text="lololol" onAction="#test" fx:id="button" />
</children>
</AnchorPane>
and the Controller.java
package sample;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import java.awt.event.ActionEvent;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable
{
#Override
public void initialize(URL url, ResourceBundle resourceBundle)
{
}
#FXML
private void test(ActionEvent event)
{
System.out.println("lollolol");
}
}
Replace:
import java.awt.event.ActionEvent;
with:
import javafx.event.ActionEvent;

JavaFx - Dynamic JXML, add Pane element on Initialize

i am new in JavaFX, and as any newcomer, i am flood with doubts.
So i have to populate an <AnchorPane> with children <Pane> like this FXML code:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<AnchorPane fx:id="anchor" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="300.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<children>
<!-- Add multiple Panels here-->
</children>
</AnchorPane>
My Controller looks like this:
package sample;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable {
#FXML javafx.scene.layout.AnchorPane anchor;
#FXML javafx.scene.layout.Pane pane;
#Override
public void initialize(URL location, ResourceBundle resources) {
pane.prefHeight(100);
pane.prefWidth(300);
pane.setStyle("-fx-background-color: aqua");
for(int i = 0; i < 3; i++) {
anchor.getChildren().add(pane);
pane.setLayoutY(i*100);
}
}
}
Hope someone can help me... Thank You!!
The solution for it is...
The FXML code:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<AnchorPane fx:id="anchor" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="300.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<children>
<ScrollPane prefHeight="400.0" prefWidth="300.0">
<content>
<GridPane fx:id="gridPane" prefHeight="410.0" prefWidth="294.0"></GridPane>
</content>
</ScrollPane>
</children>
</AnchorPane>
The Controller Class:
package sample;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.text.Font;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable {
#FXML private GridPane gridPane;
private Pane paneContainer;
private Label paneLabel;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
for(int i = 0; i<4; i++) {
paneLabel = new Label();
paneLabel.setText("it is..." + i);
paneContainer = new Pane();
paneContainer.setStyle("-fx-background-color: aqua; -fx-border-style: solid; -fx-border-width: 1px; -fx-border-color:#000; ");
paneContainer.setPrefWidth(200);
paneContainer.setPrefHeight(100);
paneContainer.getChildren().add(paneLabel);
gridPane.add(paneContainer, 0, i);
}
}
}
Use GridPane is the easiest way to do it!

Javafx: Error resolving onAction // eventHandler not in the namespace

I am a complete beginner, messing around with javafx. My first try:
[FXML]
<?import javafx.scene.web.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<AnchorPane fx:controller="sample.Controller" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" >
<children>
<Button fx:id="but0" layoutX="208.0" layoutY="146.0" mnemonicParsing="false" onAction="#Handle" text="Button" />
</children>
</AnchorPane>
And the controller class:
package sample;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
public class Controller {
#FXML
private Button but0;
#FXML
private void Handle(EventHandler e){
but0.setText("Bla");
}
}
which results in the following error:
Error resolving onAction='#Handle', either the event handler is not in the Namespace or there is an error in the script.
Although my Controller class is clearly set as controller for the parent AnchorPane.
The parameter of the handler method either needs to be a Event or it needs to be absent. The following 2 versions should both work:
#FXML
private void Handle(){
but0.setText("Bla");
}
#FXML
private void Handle(ActionEvent e){
but0.setText("Bla");
}
Your controller needs to implement Initializable, like so: (this is just the NetBeans default FXMLController, I'm assuming you load it with FXMLLoader.load() )
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;
public class FXMLDocumentController implements Initializable { // notice this
#FXML
private Button but0;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked the button!");
}
#Override // and this
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
Also, methods should start with a lowercase letter, "handle" instead of "Handle" ;) while the second version works, too, it is not considered good style.

How to change fxml lable text by id

I have Label on my fxml file:
<children>
<Label fx:id="lblTest" text="Label" />
</children>
How can i change the text from "Label" to "Hello" from the main/controller java file?
I just started to learn the basics of JavaFX and i am not sure if it possible
Problem
You want to set the text on a label that is part of FXML/Controller/MainApp
Solution
Normally you have three files:
FXML-Document
FXML-Controller
Class that extends Application and overrides the start method
A little Example:
LabelText.java
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class LabelText 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();
}
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.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.40" fx:controller="labeltext.FXMLDocumentController">
<children>
<Label fx:id="lblTest" layoutX="126.0" layoutY="92.0" minHeight="16" minWidth="69" />
</children>
</AnchorPane>
FXMLDocumentController.java
package labeltext;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
public class FXMLDocumentController {
#FXML
private Label lblTest;
#FXML
private void initialize() {
lblTest.setText("I'm a Label.");
}
}
And that's it.
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
Label lblData = (Label) root.lookup("#lblTest");
if (lblData!=null) lblData.setText("bye");

What is wrong with this JavaFX/FXML custom component?

I am learning to write FXML custom components for use with JavaFX 8 and Scene Builder.
I wrote the FXML file shown below but Scene Builder will not open it, giving me the message "Open operation has failed" due to the exception:
java.io.IOException: javafx.fxml.LoadException: mycustomcomponent.TicoTeco is not a valid type.
/C:/Users/xxxxx/Documents/NetBeansProjects/MyCustomComponent/src/mycustomcomponent/TicoTeco.fxml:9
at com.oracle.javafx.scenebuilder.kit.fxom.FXOMLoader.load(FXOMLoader.java:92)
at com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument.(FXOMDocument.java:80)
at com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument.(FXOMDocument.java:95)
...
Why am I getting this exception?
Here's the FXML file:
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<fx:root type="mycustomcomponent.TicoTeco" prefHeight="93.0" prefWidth="304.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<BorderPane layoutX="61.0" prefHeight="115.0" prefWidth="200.0">
<left>
<Button fx:id="tico" mnemonicParsing="false" text="Tico" BorderPane.alignment="CENTER" />
</left>
<right>
<Button fx:id="teco" mnemonicParsing="false" text="Teco" BorderPane.alignment="CENTER" />
</right>
</BorderPane>
</children>
</fx:root>
And here are the Java files for TicoTeco.java and Main.java:
package mycustomcomponent;
import java.io.IOException;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
public class TicoTeco extends AnchorPane {
#FXML
Button tico;
#FXML
Button teco;
public TicoTeco() throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(TicoTeco.class.getResource("TicoTeco.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
fxmlLoader.load();
}
#FXML
public void initialize() {
final EventHandler<ActionEvent> onAction =
event -> System.out.println("Hi, I'm " + (event.getSource() == tico? "Tico" : "Teco") + "!");
tico.setOnAction(onAction);
teco.setOnAction(onAction);
}
}
package mycustomcomponent;
import java.io.IOException;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws IOException {
Scene scene = new Scene(new TicoTeco());
primaryStage.setTitle("Here are Tico and Teco!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
It's a bit tricky. So your fxml have a little mistake:
Your custom class is extending AnchorPane, so this should be the root in your fxml:
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<fx:root type="AnchorPane" prefHeight="93.0" prefWidth="304.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<BorderPane layoutX="61.0" prefHeight="115.0" prefWidth="200.0">
<left>
<Button fx:id="tico" mnemonicParsing="false" text="Tico" BorderPane.alignment="CENTER" />
</left>
<right>
<Button fx:id="teco" mnemonicParsing="false" text="Teco" BorderPane.alignment="CENTER" />
</right>
</BorderPane>
</children>
</fx:root>
After that, you have to make a jar of it, because you have a fxml and a java class. This is the tricky part in Netbeans, so follow up:
First: Create an own Library Project for the component that looks like this with your copied source files:
Second: Delete the copied Main (where the main method is in) file
Third: Do a "Clean and Build" at the project. The generated .jar file will be in the subfolder "dist" in your Project directory.
Fourth: Open Scene Builder and import your CustomComponent .jar file like this:
Now you are able to use the component as you want. But be aware of changes to the component are not dynamicaly refresh the imported jar, you have to do the whole thing again.

Categories

Resources