Unable to get textfield input [JavaFX] - javafx

I am unable to extract user input from textfield in javafx.
When I click the button, I want the text from the textfield should be printed in console but it displays nothing. Here is a screenshot: 1
Controller Class:
public class FXMLDocumentController implements Initializable {
#FXML
private Label label;
#FXML
private TextField textField;
#FXML
private Button button;
#FXML
private void handleButtonAction(ActionEvent event) {
textField = new TextField();
System.out.println("You clicked me!" + textField.getText());
label.setText("Hello World!");
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
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="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="javafxapplication4.FXMLDocumentController">
<children>
<Button fx:id="button" layoutX="126" layoutY="90"
onAction="#handleButtonAction" text="Click Me!" />
<Label fx:id="label" layoutX="126" layoutY="120" minHeight="16"
minWidth="69" />
<TextField fx:id="textField" layoutX="86.0" layoutY="137.0" />
</children>
</AnchorPane>
What is the mistake, and can you provide an explanation if possible?
Thank You.

The problem is here textField = new TextField(); you are redefining the textField instance that's why you're getting empty value, but you're already instanciating the TextField with the #FXML annotation so to retrieve the text inside that textField (already defined before) change your method to this :
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!" + textField.getText());
label.setText("Hello World!");
}

Related

JavaFX (Scene builder) arrow keys OnKeyPressed

I'm in the middle of a school project, but I'm stuck...
In Scene Builder there is an OnKeyPressed and an OnKeyReleased 'method', and when I assign my own method (See code further down) I want to check if I'm pressing the left or right arrow key.
The problem is, OnKeyReleased works fine, but the OnKeyPressed only works when I hold down shift!
Does anyone know the cause of this issue? and if so, how it can be fixed/worked around?
(I'm on a MacBook, could this have anything to do with it?)
Thanks :)
Method for OnKeyPressed:
#FXML
private void Input(KeyEvent e)
{
if(e.getCode().equals(KeyCode.LEFT))
{
System.out.println("Pressed left arrow key");
}
}
FullCode:
package seasweeper.seasweeper;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
public class SecondaryController implements Initializable {
#FXML
private Label Label_Character;
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
#FXML
private void switchToPrimary() throws IOException
{
App.setRoot("primary");
}
#FXML
private void Input(KeyEvent e)
{
if(e.getCode().equals(KeyCode.LEFT))
{
System.out.println("Pressed left");
}
System.out.println("KeyCode: " + e.getCode());
}
}
FXML code:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onKeyPressed="#moveLeft" onKeyReleased="#moveLeft" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seasweeper.seasweeper.PacificController">
<children>
<Button layoutX="422.0" layoutY="64.0" mnemonicParsing="false" onAction="#switchToPrimary" prefHeight="27.0" prefWidth="164.0" text="Switch to Primary" />
<Label layoutX="489.0" layoutY="31.0" text="Pacific" />
<Label fx:id="Label_Character" layoutX="273.0" layoutY="192.0" text="Character" />
</children>
</AnchorPane>
Other Scene Controller:
package seasweeper.seasweeper;
import java.io.IOException;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
public class PrimaryController {
#FXML
private Button Button_Arctic;
#FXML
private Button Button_Southern;
#FXML
private Button Button_Pacific;
#FXML
private Button Button_Atlantic;
#FXML
private Button Button_Indian;
#FXML
private Button Button_Pacific1;
#FXML
private void switchToPacific() throws IOException {
App.setRoot("pacific");
}
#FXML
private void switchToSouthern() throws IOException {
App.setRoot("southern");
}
#FXML
private void switchToAtlantic() throws IOException {
App.setRoot("atlantic");
}
#FXML
private void switchToIndian() throws IOException {
App.setRoot("indian");
}
#FXML
private void switchToArctic() throws IOException {
App.setRoot("arctic");
}
}
Other FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seasweeper.seasweeper.PrimaryController">
<children>
<Button fx:id="Button_Arctic" layoutX="226.0" layoutY="14.0" mnemonicParsing="false" onAction="#switchToArctic" prefHeight="77.0" prefWidth="148.0" text="Arctic" />
<Button fx:id="Button_Southern" layoutX="226.0" layoutY="309.0" mnemonicParsing="false" onAction="#switchToSouthern" prefHeight="77.0" prefWidth="148.0" text="Southern" />
<Button fx:id="Button_Pacific" layoutX="14.0" layoutY="162.0" mnemonicParsing="false" onAction="#switchToPacific" prefHeight="77.0" prefWidth="148.0" text="Pacific" />
<Button fx:id="Button_Atlantic" layoutX="226.0" layoutY="162.0" mnemonicParsing="false" onAction="#switchToAtlantic" prefHeight="77.0" prefWidth="148.0" text="Atlantic" />
<Button fx:id="Button_Indian" layoutX="438.0" layoutY="162.0" mnemonicParsing="false" onAction="#switchToIndian" prefHeight="77.0" prefWidth="148.0" text="Indian" />
<Button fx:id="Button_Shop" layoutX="556.0" layoutY="14.0" mnemonicParsing="false" prefHeight="30.0" prefWidth="30.0" text="\$" textFill="#009712" />
</children>
</AnchorPane>
On the same issue I changed OnKeyPressed from AnchorPane to some Button on that AnchorPane and OnKeyPressed works fine with arrows :)
#Override
public void initialize(URL location, ResourceBundle resources) {
someButton.addEventHandler(KeyEvent.KEY_PRESSED,
new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
switch (event.getCode().toString()) {
// your logic here
}
event.consume();
}
});
}
This one is a little tricky, but still relatively simple:
Node node = null;
node.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
if (event.getCode() == KeyCode.KP_UP) { // KeyPressed_UP
// Do something
}
if (event.getCode() == KeyCode.KP_DOWN) { // KeyPressed_DOWN
// Do something
}
if (event.getCode() == KeyCode.KP_LEFT) { // KeyPressed_LEFT
// Do something
}
if (event.getCode() == KeyCode.KP_RIGHT) { // KeyPressed_RIGHT
// Do something
}
}
});
Remember to change "node" with your object (it could be a Scene, AnchorPane -or any kind of pane-, buttons, etc).

ListSelectionView not displaying contents of ObservableList

I have a ListSelectionView (from the ControlsFX library) in JavaFX and I need it to display a set of values when a particular button is clicked. It displays the values when I place the add the contents into it in the initialize method. But when I place the same code in the event action method of a button it doesn't display. I have another method which gets the Source items and Target items from the ListSelectionView and displays them. Even though the ListSelectionView isn't displaying anything, the getSourceItems() method returns a set of values which are then displayed.
public class FXMLDocumentController implements Initializable {
#FXML
private Label label;
#FXML
private Button button;
#FXML
private JFXListView<Label> listv;
#FXML
private ListSelectionView<Label> abc;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
label.setText("Hello World!");
}
#Override
public void initialize(URL url, ResourceBundle rb) {
}
#FXML
private void handleToggle(MouseEvent event) {
ObservableList<Label> users = FXCollections.observableArrayList();
abc.setSourceHeader(new Label("Present"));
abc.setTargetHeader(new Label("Absent"));
for (int i=0; i<4;i++)
{
users.add(new Label("Name "+i));
}
abc.setSourceItems(users);
abc.setDisable(false);
for (int i=0; i<4;i++)
{
Label k = new Label("Hello"+i);
listv.getItems().add(k);
}
}
#FXML
private void handlenewNOde(MouseEvent event) {
ObservableList<Label> users1 =abc.getSourceItems();
System.out.println("Source items");
for(int i =0; i<users1.size(); i++)
{
Label k=users1.get(i);
System.out.println(k.getText());
}
System.out.println("Target items");
ObservableList<Label> users12 =abc.getTargetItems();
for(int i =0; i<users12.size(); i++)
{
Label k=users12.get(i);
System.out.println(k.getText());
}
}
}
.fxml :
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXButton?>
<?import com.jfoenix.controls.JFXListView?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import org.controlsfx.control.ListSelectionView?>
<AnchorPane id="AnchorPane" prefHeight="680.0" prefWidth="914.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.141" fx:controller="listselectionviewtryout.FXMLDocumentController">
<children>
<Button fx:id="button" layoutX="14.0" layoutY="21.0" onAction="#handleButtonAction" text="Click Me!" />
<Label fx:id="label" layoutX="17.0" layoutY="54.0" minHeight="16" minWidth="69" />
<JFXListView fx:id="listv" layoutX="131.0" layoutY="35.0" prefHeight="237.0" prefWidth="75.0" />
<JFXButton layoutX="413.0" layoutY="58.0" onMouseClicked="#handleToggle" text="Toggle Extension" />
<JFXButton layoutX="445.0" layoutY="134.0" onMouseClicked="#handlenewNOde" text="new Node" />
<ListSelectionView fx:id="abc" layoutX="226.0" layoutY="262.0" />
</children>
</AnchorPane>
Ignore the JFXListView.
Output:
Source items
Name 0
Name 1
Name 2
Name 3
Target items
Should
abc.setSourceItems(users);
be
abc.getSourceItems().addAll(users);

Slider above the x axis in a chart?

I am trying to implement a Slider that has an XYChart below and is supposed to slider along the values of the x-axis. New values for the y-axis are to be dynamilcally added, so the chart may grow vertically. That's why I decided, it has to be inside a ScrollPane.
Now the question is:
How can I reliably position a slider above and with the same length of the x-axis?
I have tried to bind properties concerning the width and position of the Slider and the NumberAxis in fxml and java. See minimal (not) working (as desired) example below:
MainView.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.chart.*?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.Slider?>
<VBox fx:id="timeBox" prefHeight="600" prefWidth="800" maxHeight="600" maxWidth="800"
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Slider fx:id="timeSlider" blockIncrement="30.0" max="360.0" />
<HBox fx:id="scrollBox" fitwidth="${timeBox.width}" VBox.vgrow="ALWAYS">
<children>
<ScrollPane fx:id="timeScrollPane" fitToHeight="true"
fitToWidth="true" fitwidth="${scrollBox.width}" HBox.hgrow="SOMETIMES">
<content>
<LineChart fx:id="timeChart">
<xAxis>
<NumberAxis fx:id="timeAxis" minorTickCount="1"
minorTickLength="1.0" side="TOP" tickLabelGap="30.0"
tickLength="1.0" tickUnit="1.0" upperBound="360.0" />
</xAxis>
<yAxis>
<CategoryAxis fx:id="appearanceAxis" prefWidth="160.0"
side="LEFT" />
</yAxis>
</LineChart>
</content>
</ScrollPane>
</children>
</HBox>
</children>
</VBox>
MainViewController
public class MainViewController implements Initializable {
#FXML private VBox timeBox;
#FXML private HBox sliderBox;
#FXML private Slider timeSlider;
#FXML private HBox scrollBox;
#FXML private ScrollPane timeScrollPane;
#FXML private NumberAxis timeAxis;
#FXML private CategoryAxis appearanceAxis;
#FXML private LineChart<Number, String> timeChart;
#Override
public void initialize(URL location, ResourceBundle resources) {
// idea: set the same x value, but it does not change anything
timeSlider.setLayoutX(timeAxis.getLayoutX());
// idea: bind the width, but it stays longer
timeSlider.prefWidthProperty().bind(timeAxis.widthProperty());
}
}
Main.java
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("MainView.fxml"));
Parent root = loader.load();
Scene scene = new Scene(root,800,600);
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);
}
}
I know, what I have tried so far is not really much, but I just don't have an idea how to fix that.
The chart is meant to show the start-to-stop time of a video file on the x-axis and annotations with their appearance intervals on the y-axis.
Thanks for reading this…

JAVAFX - Change specific Pane only using 1 window

Can you Help me how to change the Spesific pane in 1 scene.
So when i want to click the Menu A. The Content will change to content A.
And when i click the menu B. The Content will be change to Content B
i try with the 2 FXML and using normal method like load screen A an screen B
But the result only change the window. i want to change the content with 1 window only.
Is there any suggestion how to change the specific pane in 1 window?
As an option.
Make FXML and controller for any "Content" and when the some button is clicked to delete the old "Content" and upload new.
Working example below (edited according to James_D comment):
Main.java
public class Main extends Application {
Parent root;
Stage stage;
#Override
public void start(Stage primaryStage) {
try {
root = FXMLLoader.load(getClass().getResource("Main.fxml"));
stage = primaryStage;
stage.setTitle("Stage");
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Main.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<BorderPane fx:id="mainPane" 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="application.Controller">
<left>
<ToolBar orientation="VERTICAL" BorderPane.alignment="CENTER">
<items>
<Button mnemonicParsing="false" onAction="#onBtnAClick" text="A" />
<Button mnemonicParsing="false" onAction="#onBtnBClick" text="B" />
<Button mnemonicParsing="false" onAction="#onBtnCClick" text="C" />
</items>
</ToolBar>
</left>
</BorderPane>
Controller.java
import javafx.fxml.FXML;
import javafx.scene.layout.BorderPane;
public class Controller {
#FXML
BorderPane mainPane;
#FXML
public void onBtnAClick(){
ContentA contentA = new ContentA();
mainPane.setCenter(contentA);
}
#FXML
public void onBtnBClick(){
ContentB contentB = new ContentB();
mainPane.setCenter(contentB);
}
#FXML
public void onBtnCClick(){
ContentC contentC = new ContentC();
mainPane.setCenter(contentC);
}
}
And some sample of Content:
ContentA.java
public class ContentA extends AnchorPane{
public ContentA(){
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("ContentA.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ContentA.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<fx:root prefHeight="200.0" prefWidth="300.0" type="AnchorPane" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<ListView layoutX="50.0" layoutY="-26.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</fx:root>
try to use this, its easy
Parent root = null;
try {
root=FXMLLoader.load(getClass().getResource("your_FXML_File.fxml"));
} catch (Exception e) {
}
borderpane.setCenter(root);

JavaFX. Communication between controllers

Hello I'm starting in JavaFX and I've got some problems.
I want to communicate two controlles from two diferents views. How can I do it?
I'm working with tabs and i have this two controllers and i want to do something similar like this:
Application.java:
public class JavaFXApplication6 extends Application
{
#Override
public void start(Stage primaryStage)
{
try
{
Parent root = FXMLLoader.load(getClass().getResource(
"/view/FXML_Main.fxml"));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e){
e.printStackTrace();
}
primaryStage.setTitle("Back-end GUI");
}
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
launch(args);
}
}
FXML_Main.fxml:
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0"
xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8"
fx:controller="controller.FXML_MainController">
<children>
<TabPane layoutX="61.0" layoutY="30.0" prefHeight="400.0" prefWidth="600.0"
tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="0.0"
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0">
<tabs>
<Tab text="Untitled Tab 1">
<content>
<fx:include source="FXML_Tab1.fxml" />
</content>
</Tab>
<Tab text="Untitled Tab 2">
<content>
<fx:include source="FXML_Tab2.fxml" />
</content>
</Tab>
</tabs>
</TabPane>
</children>
</AnchorPane>
FXML_MainController.java:
public class FXML_MainController implements Initializable {
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
FXML_Tab1.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="400.0" prefWidth="600.0"
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="controller.FXML_Tab1Controller">
<children>
<Label fx:id="Label1" layoutX="282.0" layoutY="108.0" text="Label" />
<TextField fx:id="FextField1" layoutX="215.0" layoutY="146.0" />
<Button fx:id="Button1" layoutX="269.0" layoutY="197.0" mnemonicParsing="false"
onAction="#actionButton1" text="Button" />
</children>
</AnchorPane>
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_Tab2.fxml:
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0"
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="controller.FXML_Tab2Controller">
<children>
<Label fx:id="Label2" layoutX="282.0" layoutY="99.0" text="Label" />
<TextField fx:id="TextField2" layoutX="215.0" layoutY="149.0" />
<Button fx:id="Button2" layoutX="270.0" layoutY="200.0" mnemonicParsing="false"
onAction="#actionButton2" text="Button" />
</children>
</AnchorPane>
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
Add an fx:id to each of your <fx:include> tags:
<tabs>
<Tab text="Untitled Tab 1">
<content>
<fx:include source="FXML_Tab1.fxml" fx:id="tab1" />
</content>
</Tab>
<Tab text="Untitled Tab 2">
<content>
<fx:include source="FXML_Tab2.fxml" fx:id="tab2" />
</content>
</Tab>
</tabs>
This will allow you to inject the corresponding controllers into your FXML_MainController:
public class FXML_MainController {
#FXML
private FXML_Tab1Controller tab1Controller ;
#FXML
private FXML_Tab2Controller tab2Controller ;
}
The variable naming is very important here: the fields must be named xController where x is the value for the fx:id attribute in the fx:include. See the Introduction to FXML documentation for details.
Now in your main controller's initialize() method, you can establish the relationship between the two controllers:
public class FXML_MainController {
#FXML
private FXML_Tab1Controller tab1Controller ;
#FXML
private FXML_Tab2Controller tab2Controller ;
public void initialize() {
tab1Controller.tab2Controller = tab2Controller ;
tab2Controller.tab1Controller = tab1Controller ;
}
}

Resources