Javafx button does nothing - java

I'm creating a simple login GUI form using eclipse, JavaFX and scene builder. I've coded my program so that every time I click the login button, it would switch to another window but it doesn't work. i'm a beginner in java but we've been tasked to create a system in my class so I've only relied on youtube tutorials, any help would be appreciated!
this is my main code
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
Parent root = FXMLLoader.load(getClass().getResource("Main.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
my login form
package application;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
public class Login {
#FXML
private Button button;
#FXML
private PasswordField password;
#FXML
private TextField username;
#FXML
private Label wrongLogin;
#FXML
public void Login(ActionEvent event) {
Stage primaryStage = new Stage();
if (username.getText().equals("admin") && password.getText().equals("admin")) {
try {
Parent root = FXMLLoader.load(getClass().getResource("BookRooms.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
my fxml file
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="345.0" prefWidth="545.0" style="-fx-background-color: #fff2cc;" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Login">
<children>
<AnchorPane layoutX="132.0" layoutY="62.0" prefHeight="221.0" prefWidth="279.0" style="-fx-background-color: #545454; -fx-border-radius: 10;">
<children>
<Label layoutX="34.0" layoutY="60.0" prefHeight="25.0" prefWidth="56.0" text="Username:" textFill="WHITE" />
<Label layoutX="34.0" layoutY="98.0" prefHeight="25.0" prefWidth="56.0" text="Password:" textFill="WHITE" />
<TextField layoutX="106.0" layoutY="60.0" promptText="Enter Username ID:" />
<TextField layoutX="106.0" layoutY="98.0" promptText="Enter Password" />
<Button alignment="CENTER" layoutX="106.0" layoutY="137.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="73.0" style="-fx-background-color: #fff2cc;" text="LOGIN" />
</children></AnchorPane>
<Label layoutX="225.0" layoutY="36.0" text="HOTEL DEL LUNA" />
</children>
</AnchorPane>

Your button in fxml can't call Login() in its controller class because there is no onAction attribute in fxml button tag .
So ,in <Button alignment="CENTER" layoutX="106.0" layoutY="137.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="73.0" style="-fx-background-color: #fff2cc;" text="LOGIN" /> add onAction="#Login" inside Button Tag:
<Button alignment="CENTER" layoutX="106.0" layoutY="137.0" mnemonicParsing="false" onAction="#Login" prefHeight="25.0" prefWidth="73.0" style="-fx-background-color: #fff2cc;" text="LOGIN" />
And , naming a method in a class with exact the same name of that class is concidered a bad practice. Only constructors must match its name with class identifier

Related

How to add a button to a single row in a one column TableView?

I have a TableView with a single Column and I want to have a Button in the last row of that TableView/Column. The Button should be disabled until a row is selected and then it should be enabled. I've done numerous searches on this but everything I've found seems to be adding a button to every row within a multi-column table. Is there a quick way to do this?
Here are some sample images:
TableButtonView.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<AnchorPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="406.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="tablebutton.TableButtonController">
<children>
<VBox layoutX="60.0" layoutY="22.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="100.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<Label alignment="CENTER" maxWidth="1.7976931348623157E308" prefHeight="51.0" prefWidth="200.0" text="Agency Customization">
<font>
<Font name="System Bold" size="13.0" />
</font>
</Label>
<HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="40.0">
<children>
<Label alignment="CENTER_RIGHT" maxHeight="1.7976931348623157E308" prefHeight="30.0" prefWidth="70.0" text="Agency: " />
<TextField fx:id="agencyTextField" maxHeight="1.7976931348623157E308" prefHeight="30.0" prefWidth="45.0" />
<Button fx:id="addButton" maxHeight="1.7976931348623157E308" onAction="#onAdd" prefHeight="30.0" prefWidth="67.0" text="_Add">
<HBox.margin>
<Insets left="10.0" />
</HBox.margin>
</Button>
</children>
<padding>
<Insets bottom="10.0" />
</padding>
</HBox>
<TableView fx:id="agencyTableView" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="276.0">
<columns>
<TableColumn fx:id="agencyColumn" prefWidth="188.0" text="Agency" />
</columns>
<VBox.margin>
<Insets left="5.0" right="5.0" />
</VBox.margin>
</TableView>
<ButtonBar maxWidth="1.7976931348623157E308">
<buttons>
<Button fx:id="okAgencyButton" mnemonicParsing="false" onAction="#onOK" text="OK" />
<Button fx:id="cancelAgencyButton" mnemonicParsing="false" onAction="#onCancel" text="Cancel" />
</buttons>
<padding>
<Insets bottom="5.0" right="20.0" top="5.0" />
</padding>
</ButtonBar>
</children>
</VBox>
</children>
</AnchorPane>
TableButtonController.java:
package tablebutton;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class TableButtonController implements Initializable {
private WebView helpWebView;
#FXML
private TextField agencyTextField;
#FXML
private Button addButton;
#FXML
private TableView<String> agencyTableView;
#FXML
private TableColumn<String, String> agencyColumn;
#FXML
private Button okAgencyButton;
#FXML
private Button cancelAgencyButton;
#Override
public void initialize(URL url, ResourceBundle rb) {
agencyColumn.setCellValueFactory(cellData ->
new ReadOnlyStringWrapper(cellData.getValue())
);
agencyColumn.setStyle( "-fx-alignment: CENTER;");
ObservableList<String> agencies = FXCollections.observableArrayList(
"AA","DL","LH");
agencyTableView.getItems().addAll(agencies);
}
#FXML
private void onAdd(ActionEvent event) {
}
#FXML
private void onOK(ActionEvent event) {
// Just exit for now
Stage stage = (Stage) okAgencyButton.getScene().getWindow();
stage.close();
}
#FXML
private void onCancel(ActionEvent event) {
// Just exit for now
Stage stage = (Stage) cancelAgencyButton.getScene().getWindow();
stage.close();
}
}
TableButton.java:
package tablebutton;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class TableButton extends Application {
#Override
public void start(Stage primaryStage) {
try
{
FXMLLoader loader = new FXMLLoader(getClass().getResource("TableButtonView.fxml"));
Scene scene = new Scene((Parent) loader.load());
primaryStage.setScene(scene);
primaryStage.setTitle("TableView Button Test");
primaryStage.show();
}
catch (IOException ignored)
{
}
}
public static void main(String[] args) {
launch(args);
}
}
Trying to put the button actually inside the TableView is problematic and not recommended. There is a technical difficulty in getting the button to render in the last row of the TableView (this is not trivial), and there are also potential usability issues (what if there are a lot of rows in the table and the table needs to be scrolled, does the remove button just scroll out of view? if so, then how would a user find it if they wanted to remove something).
Instead, don't put the button in the TableView:
Use a VBox which contains the the TableView and the Button.
Set appropriate constraints so that the Button butts right up under the TableView and is sized to the width of the TableView.
Bind the disable property of the Button to an empty selected items set.
Sample code:
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Remover extends Application {
#Override
public void start(Stage stage) throws Exception {
ObservableList<NamedColor> colors = FXCollections.observableArrayList(
new NamedColor("red", Color.RED),
new NamedColor("green", Color.GREEN),
new NamedColor("blue", Color.BLUE),
new NamedColor("indigo", Color.INDIGO)
);
TableView<NamedColor> table = new TableView<>(colors);
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
TableColumn<NamedColor, String> colorNames = new TableColumn<>("Colors");
colorNames.setCellValueFactory(new PropertyValueFactory<>("name"));
table.getColumns().add(colorNames);
Button remove = new Button("Remove");
remove.disableProperty().bind(
Bindings.isEmpty(
table.getSelectionModel().getSelectedItems()
)
);
remove.setMaxWidth(Double.MAX_VALUE);
remove.setOnAction(event ->
table.getItems()
.removeAll(
table.getSelectionModel().getSelectedItems()
)
);
VBox layout = new VBox(table, remove);
layout.setPadding(new Insets(10));
stage.setScene(new Scene(layout));
stage.show();
}
public static void main(String[] args) {
launch(Remover.class);
}
public static class NamedColor {
private String name;
private Color color;
public NamedColor(String name, Color color) {
this.name = name;
this.color = color;
}
public String getName() {
return name;
}
public Color getColor() {
return color;
}
}
}

The controller 'MainController' has no event slot 'PassPhrase' [duplicate]

This question already has answers here:
JavaFx, Problems with #FXML
(2 answers)
Closed 5 years ago.
So im trying to create Action event, to change the text on my status label button, but i keep getting the error listed in the title "The controller 'MainController' has no event slot 'PassPhrase", Im new to this and not quite sure exactly what to do.
Also I want the text entered into my passPhrase field to be saved under a variable called pass, which i think i did correctly if anyone could double check? Thanks.
This is my mainController
package application;
import java.awt.Label;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import javafx.fxml.FXML;
public class MainController {
#FXML
private Label lblStatus;
#FXML
private TextField txtPassPhrase;
String pass = txtPassPhrase.getText();
public void PassPhrase (ActionEvent event) {
if (txtPassPhrase.getText().isEmpty()) {
lblStatus.setText("You must Enter in Characters");
} else {
lblStatus.setText("Your PassPhrase has been accepted.");
}
}
}
Here is my passPhrase FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<fx:root prefHeight="150.0" prefWidth="500.0" type="AnchorPane"
xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="application.MainController">
<children>
<Button layoutX="210.0" layoutY="103.0" mnemonicParsing="false"
onAction="#PassPhrase" text="Submit">
<font>
<Font size="18.0" />
</font>
</Button>
<TextField fx:id="txtPassPhrase" layoutX="152.0" layoutY="56.0"
prefHeight="39.0" prefWidth="199.0" promptText="Enter in a PassPhrase">
<font>
<Font size="18.0" />
</font>
</TextField>
<Label fx:id="lblStatus" layoutX="80.0" layoutY="14.0"
prefHeight="17.0" prefWidth="423.0" text="Press submit once you enter in a
PassPhrase" textFill="#e05858">
<font>
<Font size="18.0" />
</font>
</Label>
</children>
</fx:root>
and my main class
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
Parent root =
FXMLLoader.load(getClass().getResource("/application/passPhrase.fxml"));
Scene scene = new Scene(root,400,400);
scene.getStylesheets().add(getClass().getResource("application.css")
.toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Try changing your imports to `JavaFX' imports.
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.event.ActionEvent;

Javafx/Fxml - Error trying to save a value externally on program close

I'm currently trying to create a basic money saver program for a school project using javafx/fxml so i'm still learning. I am currently trying to set up a way in which when the user closes the program, it runs some code to save the value currently displayed in a textField endGoal. The problem is the Textfield in controller keeps throwing a NullPointException. Is there anyway to un-null it or fix it? problem on line endGoal.setText("This is fake.");.
The Controller:
package sample;
import javafx.application.Platform;
import javafx.animation.*;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import java.io.*;
import java.io.FileReader;
import javafx.application.*;
import javax.annotation.PostConstruct;
public class MainPageController {
#FXML
private Button openPage1;
#FXML
private Button openPage2;
#FXML
private Button generateNewGoal;
#FXML
private Button resetGoal;
#FXML
private TextField moneySaved;
#FXML
private TextField currentGoal;
#FXML
public BorderPane BorderPane;
#FXML
public Stage myStage;
public void initialize() throws Exception{
FileReader reader = new FileReader("Goal.txt");
BufferedReader br = new BufferedReader(reader);
String goal = br.readLine();
currentGoal.setText(goal);
reader.close();
}
#PostConstruct
public void start(Stage stage1)throws Exception{
myStage = stage1;
FXMLLoader loader = new FXMLLoader(getClass().getResource("MainPage.fxml"));
Parent root = loader.load();
loader.getController();
loader.load();
loader.getController();
stage1.getScene().getWindow();
myStage.setOnCloseRequest(e -> onEnd());
}
public void openPage1(ActionEvent event) throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("MandatoryCostCollector.fxml"));
Parent root = (Parent) fxmlLoader.load();
Stage stage = new Stage();
stage.setScene(new Scene(root));
stage.setTitle("Money Saver Program");
stage.show();
((Node) event.getSource()).getScene().getWindow().hide();
}
public void openPage2(ActionEvent event) throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("PayDataCollector.fxml"));
Parent root = (Parent) fxmlLoader.load();
Stage stage = new Stage();
stage.setScene(new Scene(root));
stage.setTitle("Money Saver Program");
stage.show();
((Node) event.getSource()).getScene().getWindow().hide();
}
public void resetGoal(ActionEvent event) throws Exception {
currentGoal.setText("");
}}
public void saveData()throws Exception{
endGoal.setText("This is fake.");
FileWriter writer = new FileWriter("Goal.txt");
String goal = (endGoal.getText());
writer.write(goal);
writer.close();
}
The Main:
package sample;
import com.sun.org.apache.xpath.internal.Arg;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import jdk.nashorn.internal.runtime.regexp.joni.constants.Arguments;
import javax.xml.soap.Text;
import java.io.*;
import java.util.*;
public class Main extends Application {
#FXML
public TextField currentGoal;
File f = new File("Goal.txt");
public String finalGoal;
#Override
public void start(Stage primaryStage)throws Exception {
boolean bool = false;
if (f.exists() )
{
Parent root = FXMLLoader.load(getClass().getResource("MainPage.fxml"));
primaryStage.setTitle("Money Saver Program");
primaryStage.setScene(new Scene(root, 600, 400));
primaryStage.show();
}
else
{
bool = f.createNewFile();
Parent root = FXMLLoader.load(getClass().getResource("OpeningPage.fxml"));
primaryStage.setTitle("Money Saver Program");
primaryStage.setScene(new Scene(root, 638, 400));
primaryStage.show();
}
primaryStage.setOnCloseRequest(e -> closeProgram());
}
public static void main(String[] args) throws Exception {
launch(args);
}
public void closeProgram(){
Platform.exit();
}
public void stop()throws Exception{
mainPageController.saveData();
System.out.print("Goal has been saved!");
}
}
}
The FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<BorderPane fx:id="BorderPane" 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" fx:controller="sample.MainPageController">
<top>
<VBox prefHeight="65.0" prefWidth="600.0" BorderPane.alignment="CENTER">
<children>
<TextField alignment="CENTER" editable="false" prefHeight="68.0" prefWidth="600.0" text="Welcome to the Money Saving Program">
<font>
<Font name="Arial Rounded MT Bold" size="26.0" />
</font>
</TextField>
</children>
</VBox>
</top>
<left>
<VBox prefHeight="335.0" prefWidth="159.0" BorderPane.alignment="CENTER">
<children>
<Button fx:id="openPage1" mnemonicParsing="false" onAction="#openPage1" prefHeight="88.0" prefWidth="167.0" text="1. Open Mandatory Cost Collector" wrapText="true">
<font>
<Font name="Arial" size="18.0" />
</font>
</Button>
<Button fx:id="openPage2" mnemonicParsing="false" onAction="#openPage2" prefHeight="60.0" prefWidth="173.0" text="2. Open Pay Data Collector" wrapText="true">
<font>
<Font name="Arial" size="18.0" />
</font>
</Button>
</children>
</VBox>
</left>
<right>
<VBox prefHeight="335.0" prefWidth="166.0" BorderPane.alignment="CENTER">
<children>
<TextField fx:id="endGoal" promptText="\$">
<font>
<Font name="Arial" size="40.0" />
</font>
</TextField>
<Button fx:id="resetGoal" contentDisplay="RIGHT" mnemonicParsing="false" onAction="#resetGoal" prefHeight="33.0" prefWidth="173.0" text="Reset Goal" wrapText="true">
<font>
<Font name="Arial" size="18.0" />
</font>
</Button>
</children>
</VBox>
</right>
<bottom>
<HBox prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
<Button fx:id="generateNewGoal" mnemonicParsing="false" prefHeight="63.0" prefWidth="161.0" text="3. Generate your new goal" translateY="36.0" wrapText="true">
<font>
<Font name="Arial" size="18.0" />
</font>
</Button>
<TextField alignment="CENTER" editable="false" prefHeight="75.0" prefWidth="221.0" text="Money saved this week" translateX="38.0" translateY="23.0">
<font>
<Font name="Arial" size="18.0" />
</font>
</TextField>
<TextField fx:id="moneySaved" editable="false" prefHeight="75.0" prefWidth="180.0" promptText="\$" translateX="38.0" translateY="23.0">
<font>
<Font name="Arial" size="40.0" />
</font>
</TextField>
</children>
</HBox>
</bottom>
<center>
<VBox prefHeight="200.0" prefWidth="100.0" BorderPane.alignment="CENTER">
<children>
<TextField editable="false" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="68.0" prefWidth="167.0" text="Your current goal" translateX="108.0">
<font>
<Font name="Arial" size="18.0" />
</font>
</TextField>
</children>
</VBox>
</center>
</BorderPane>
The Error:
Exception in Application stop method
Exception in thread "main" java.lang.RuntimeException: Exception in Application stop method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:922)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at sample.MainPageController.saveData(MainPageController.java:99)
at sample.Main.stop(Main.java:73)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$163(LauncherImpl.java:882)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
Try replacing
Parent root = FXMLLoader.load(getClass().getResource("MainPage.fxml"));
by
FXMLLoader loader = new FXMLLoader(getClass().getResource("MainPage.fxml"));
loader.setController(this);
Parent root = loader.load();
The reason you have to do this is that the FXMLLoader will create a new instance of the controller class specified in the fxml file because it can not know if such an object already exists. However, you can specify an object via the setController() method, which will than be populated with your fxml GUI elements.

JavaFX FXML not responding to text input or Click (Events)

I have simple JavaFx project, with main class as eclipse JavaFx project default.
I have defined a controller , it looks like the skeleton generated by SceneBuilder, so everything is pretty much default.
When I run my application, In the UI I can't input data to the two textfields, or see the console output from my button event handlers.
A welcome.fxml file as shown below (deleted all other code to simplify)
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.effect.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.*?>
<?import javafx.scene.canvas.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mouseTransparent="true" prefHeight="720.0" prefWidth="1100.0" style="-fx-background-color: #000000;" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Welcome_Controller">
<children>
<Button alignment="CENTER" contentDisplay="CENTER" depthTest="ENABLE" graphicTextGap="10.0" layoutX="496.0" layoutY="360.0" mouseTransparent="true" onAction="#OnSignInClick" opacity="0.82" prefHeight="38.0" prefWidth="109.0" style="-fx-background-radius: 100;" text="Sign In" textAlignment="CENTER" />
<Button alignment="CENTER" contentDisplay="CENTER" layoutX="496.0" layoutY="409.0" mnemonicParsing="false" opacity="0.82" prefHeight="38.0" prefWidth="109.0" style="-fx-background-radius: 1000;" text="Sign Up" textAlignment="CENTER" />
<Text fill="WHITE" layoutX="899.0" layoutY="702.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Copyright 2015, Dawood and Irtiza." />
<TextField fx:id="tf_username" layoutX="427.0" layoutY="277.0" prefHeight="25.0" prefWidth="279.0" promptText="Enter new Username if you dont have an account " />
<TextField fx:id="tf_password" layoutX="427.0" layoutY="312.0" prefHeight="25.0" prefWidth="279.0" promptText="Enter new password if you dont have an account" />
<Label layoutX="355.0" layoutY="281.0" text="Username :" textFill="WHITE">
<font>
<Font size="14.0" />
</font>
</Label>
<Label layoutX="355.0" layoutY="315.0" text="Password :" textFill="WHITE">
<font>
<Font size="14.0" />
</font>
</Label>
</children>
</Pane>
Welcome_controller.java looks like a default skeleton generated by scene builder, code below
package application;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
public class Welcome_Controller implements Initializable {
#FXML // fx:id="btn_xxx"
private Button btn_signin; // Value injected by FXMLLoader
#FXML
private Button btn_signup;
#FXML
private TextField tf_username;
#FXML
private TextField tf_password;
#Override // This method is called by the FXMLLoader when initialization is complete
public void initialize(URL fxmlFileLocation, ResourceBundle resources)
{
//assert btn_signin != null : "fx:id=\"btn_signin\" was not injected: check your FXML file 'welcome.fxml'.";
//assert btn_signup != null : "fx:id=\"btn_signup\" was not injected: check your FXML file 'welcome.fxml'.";
// initialize your logic here: all #FXML variables will have been injected
}
#FXML private void OnSignInClick(ActionEvent event) throws IOException
{
System.out.println("clicked");
}
#FXML
void OnSignupClick(ActionEvent event) {
System.out.println("clicked 2");
}
}
EDIT : This is the class with the main method.
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
Pane root = (Pane) FXMLLoader.load(Main.class.getResource("welcome.fxml"));
Scene scene_1 = new Scene(root,1100,720);
//scene_1.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
//we can set the different scenes when it need to
primaryStage.setScene(scene_1);
primaryStage.setTitle("Translate Messenger");
primaryStage.show();
} catch(Exception e) {
System.out.println("main may exception");
e.printStackTrace();
}
}
public static void main(String[] args)
{
launch(args);
}
}
When I run my application, In the UI I can't input data to the two textfields, or see the console output from my button event handlers.
Any help would be appreciated.
You have made the root pane transparent to the mouse with mouseTransparent="true". This means that any mouse clicks on the root pane, or any of its descendent nodes (i.e. the whole UI) will be ignored. Consequently you cannot click the buttons or put focus on the text fields using the mouse. (Notice though you can navigate the UI using the tab key, and use the space key to generate a button click when it has the focus.)
Remove mouseTransparent="true" from the pane and from the "Sign In" button and it will work fine.

How to send Message from FXML controller class to Main Application class

Hello stackoverflowers,
I have a question "I have an fxml file "CrawlerView.fxml" and its controller "CrawlerController.java" and a main Application class I want to send Message(database insert) from controller class to main Application class(because i cant do business logic in GUI/fxml controller class) . So my question is: Is it possible to send message from fxml controller class to main application class"
code is below
any help
thanx in advance`
Crawler.java
package app.model.main;
import java.io.IOException;
import java.sql.Statement;
import java.util.Stack;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Crawler extends Application {
private Stage MStage;
private BorderPane rootLayout;
#FXML Button SEARCH;
#FXML TextField URL;
static Conection conection;
static url_entries URLS;//self implemented classes
static word_count count;//self implemented classes
static Statement stmt;
//static public Stack DATABASE;
public static void test(){}
public static void main(String[] args)
{
launch(args);
}
#Override
public void start(Stage MStage)
{
try {
FXMLLoader RootLoader = new FXMLLoader();
FXMLLoader CrawlerLoader = new FXMLLoader();
RootLoader.setLocation(Crawler.class.getResource("view/RootView.fxml"));
CrawlerLoader.setLocation(Crawler.class.getResource("view/CrawlerView.fxml"));
rootLayout = (BorderPane) RootLoader.load();
AnchorPane CV = (AnchorPane) CrawlerLoader.load();
rootLayout.setCenter(CV);
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
MStage.setScene(scene);
MStage.show();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
CrawlerView.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.effect.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="628.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="app.model.main.CrawlerController">
<children>
<SplitPane dividerPositions="0.14424635332252836" layoutX="8.0" layoutY="-2.0" orientation="VERTICAL" prefHeight="628.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<Label layoutX="105.0" layoutY="14.0" prefHeight="52.0" prefWidth="388.0" text="Khurasani Web Crawler" textFill="#792323">
<font>
<Font name="Bauhaus 93" size="34.0" />
</font>
</Label>
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<TextField id="URL" fx:id="URL" alignment="CENTER" blendMode="DARKEN" layoutX="110.0" layoutY="25.0" prefHeight="34.0" prefWidth="359.0" text="Enter URL">
<font>
<Font name="Berlin Sans FB Demi Bold" size="17.0" />
</font>
<effect>
<InnerShadow choke="0.56" color="#722424" height="26.93" radius="12.965" width="26.93" />
</effect>
</TextField>
<Button id="SEARCH" fx:id="SEARCH" layoutX="247.0" layoutY="82.0" mnemonicParsing="false" prefHeight="27.0" prefWidth="79.0" text="Search" textFill="#5e2929">
<font>
<Font name="Arial Black" size="15.0" />
</font>
</Button>
</children>
</AnchorPane>
</items>
</SplitPane>
CrawlerController
package app.model.main;
import java.net.URL;
import java.sql.Statement;
import java.util.ResourceBundle;
import java.util.Stack;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
public class CrawlerController implements Initializable
{
#FXML Button SEARCH;
#FXML TextField URL;
#Override // This method is called by the FXMLLoader when initialization is complete
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
assert SEARCH != null : "fx:id=\"myButton\" was not injected: check your FXML file 'simple.fxml'.";
SEARCH.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event)
{
//How to send message to main application class
}
});}
}

Categories