Whenever SPACE key is pressed, it is registered and processed as a last pressed (focused) button. I cannot capture it as KeyEvent, and it acts as a button.
I want to generate and pass on char from buttons and keyboard keys pressed.
Here is the handler part of my code in the controller class:
public void handleKeys(KeyEvent key) {
char chr = key.getText().charAt(0);
handleSymbols(chr);
key.consume();
}
public void handleBtns(ActionEvent buttonPressed) {
char chr = buttonPressed.getSource().toString().toLowerCase().charAt(buttonPressed.getSource().toString().length() - 2);
handleSymbols(chr);
buttonPressed.consume();
}
Here is the FXML file beginning:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane fx:id="container" prefHeight="500.0" prefWidth="400.0" style="-fx-background-color: #00e600"
stylesheets="/sample/main.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="sample.Controller"
onKeyPressed="#handleKeys">
<left>
<VBox prefHeight="300.0" prefWidth="50.0">
<BorderPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</BorderPane.margin>
<Button onAction="#handleBtns" prefHeight="135.0" prefWidth="50" text="+">
<VBox.margin>
<Insets bottom="20.0" />
</VBox.margin>
</Button>
<Button onAction="#handleBtns" prefHeight="135.0" prefWidth="50" text="-" />
</VBox>
</left>
There is something similar here, but for SWING, so it does not work:Disabling space bar triggering click for JButton
How can i unbind SPACE as a default key for focused buttons? I just don't want SPACE to act as a button.
I added an eventFilter to the stage in the main class and it works
addEventFilter(KeyEvent.KEY_PRESSED, k -> {
if ( k.getCode() == KeyCode.SPACE){
k.consume();
}
});
Related
I have a simple JavaFX app that has a scrolling animation of an image but after running the program a few times it begins to take longer and longer to launch. I figured there was a memory leak or something clogging up my JVM. SimpleDoublePropertyOracle docs gave me this tidbit which I think is my problem.
The ObservableValue stores a strong reference to the listener which will prevent the listener from being garbage collected and may result in a memory leak. It is recommended to either unregister a listener by calling removeListener after use or to use an instance of WeakChangeListener avoid this situation.
How can I implement this fix into my current code?
I'm a little rusty with lambda expressions and am kind of lost on where I would need to make this adjustment.
public class LoginController {
public Region content;
public void initialize() {
DoubleProperty xPosition = new SimpleDoubleProperty(0);
xPosition.addListener((observable, oldValue, newValue) -> setBackgroundPositions(content, xPosition.get()));
Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(xPosition, 0)),
new KeyFrame(Duration.seconds(200), new KeyValue(xPosition, -15000))
);
timeline.play();
}
void setBackgroundPositions(Region region, double xPosition) {
String style = "-fx-background-position: " +
"left " + xPosition/6 + "px bottom," +
"left " + xPosition/5 + "px bottom," +
"left " + xPosition/4 + "px bottom," +
"left " + xPosition/3 + "px bottom," +
"left " + xPosition/2 + "px bottom," +
"left " + xPosition + "px bottom;";
region.setStyle(style);
}
}
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
VBox root = (VBox)FXMLLoader.load(getClass().getResource("Login.fxml"));
Scene scene = new Scene(root,600,600);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
System.out.println("launch");
} catch(Exception e) {
e.printStackTrace();
}
primaryStage.setOnCloseRequest(e -> {
System.out.println("Program closed");
});
}
public static void main(String[] args) {
launch(args);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import java.net.URL?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.Cursor?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<VBox fx:id="content" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="456.0" prefWidth="600.0" styleClass="root" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.LoginController">
<children>
<BorderPane prefHeight="453.0" prefWidth="600.0">
<center>
<AnchorPane prefHeight="200.0" prefWidth="600.0" BorderPane.alignment="CENTER">
<children>
<TextField id="e" layoutX="226.0" layoutY="129.0" />
<PasswordField layoutX="226.0" layoutY="161.0" />
<Label id="userNameLabel" layoutX="115.0" layoutY="130.0" styleClass="userNameLabel" stylesheets="#Moving.css" text="Username : " textFill="#ff0101">
<font>
<Font name="OCR A Extended" size="18.0" />
</font>
</Label>
<Label id="passWordLabel" layoutX="115.0" layoutY="163.0" styleClass="passWordLabel" stylesheets="#Moving.css" text="Password : " textFill="#ff0101">
<font>
<Font name="OCR A Extended" size="18.0" />
</font>
</Label>
<HBox alignment="TOP_CENTER" layoutY="209.0" prefHeight="101.0" prefWidth="600.0" style="-fx-spacing: 10;">
<cursor>
<Cursor fx:constant="DEFAULT" />
</cursor>
<children>
<Button id="loginBtn" fx:id="loginBtn" alignment="CENTER" contentDisplay="CENTER" mnemonicParsing="false" onAction="#buttonPressed" prefWidth="80.0" styleClass="loginBtn" stylesheets="#Moving.css" text="Log In" />
<Button id="registerBtn" fx:id="registerBtn" mnemonicParsing="false" onAction="#buttonPressed" prefWidth="80.0" styleClass="registerBtn" stylesheets="#Moving.css" text="Register" />
</children>
</HBox>
</children>
</AnchorPane>
</center>
<cursor>
<Cursor fx:constant="DEFAULT" />
</cursor>
<opaqueInsets>
<Insets />
</opaqueInsets>
</BorderPane>
</children>
<stylesheets>
<URL value="#application.css" />
<URL value="#Moving.css" />
</stylesheets>
<cursor>
<Cursor fx:constant="DEFAULT" />
</cursor>
</VBox>
Tried replacing xPosition.addlistener functions with a WeakChangeListener but it was not compatible with the current code configuration.
I am trying to implement an events list in one page in JavaFX, and I would like to display 2 lists: one for UPCOMING events and one for PAST events, both relative to the current date.
A lot of searches online lead me to using an ArrayAdaptor, but I am not allowed to use any other libraries except for JavaFX.
I would also like to divide these 2 lists by a header. Right now I am working with a base code:
/**
* Panel containing the list of persons.
*/
public class HomePage extends UiPart<Region> {
private static final String FXML = "home/HomePage.fxml";
private final Logger logger = LogsCenter.getLogger(HomePage.class);
#FXML
private ListView<Trip> tripListView;
public HomePage(ObservableList<Trip> tripList) {
super(FXML);
tripListView.setItems(tripList);
tripListView.setCellFactory(listView -> new TripListViewCell());
}
/**
* Custom {#code ListCell} that displays the graphics of a {#code Trip} using a {#code TripCard}.
*/
class TripListViewCell extends ListCell<Trip> {
#Override
protected void updateItem(Trip trip, boolean empty) {
super.updateItem(trip, empty);
if (empty || trip == null) {
setGraphic(null);
setText(null);
} else {
setGraphic(new HomePageTripCard(trip, getIndex() + 1).getRoot());
}
}
}
}
This is the .fxml code:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<VBox xmlns="http://javafx.com/javafx/11" xmlns:fx="http://javafx.com/fxml/1">
<StackPane prefHeight="30.0" prefWidth="200.0" styleClass="stack-welcome" VBox.vgrow="NEVER">
<children>
<Label styleClass="label-welcome" text="Welcome-Message-Here" />
</children>
</StackPane>
<StackPane prefHeight="15.0" prefWidth="200.0" styleClass="stack-header" VBox.vgrow="NEVER">
<children>
<Label styleClass="label-header" text="TripList" />
</children>
</StackPane>
<StackPane>
<ListView fx:id="tripListView" prefWidth="247.0" VBox.vgrow="ALWAYS" />
<ListView fx:id="tripListView" prefWidth="247.0" VBox.vgrow="ALWAYS" />
</StackPane>
</VBox>
I tried using 2 different list views, for some reason it only shows up with one of the list views.
Does anyone have any tips on how to go about implementing 2 lists in one list view in JavaFX?
I just decided to use 2 list views instead, with each list view having their own list cells, both within a single VBox.
Implementation in the java file
tripListViewUpcoming.setItems(upcoming);
tripListViewUpcoming.setCellFactory(listViewUpcoming -> new TripListViewCellUpcoming());
tripListViewPast.setItems(past);
tripListViewPast.setCellFactory(listViewPast -> new TripListViewCellPast(upcoming.size()));
Implementation in the FXML file
<StackPane prefHeight="15.0" prefWidth="200.0" styleClass="trip-list-header" style="-fx-border-width: 0px 0px 2px 0px" VBox.vgrow="NEVER">
<children>
<Label styleClass="label-header" text="UPCOMING TRIPS" />
</children>
</StackPane>
<ListView fx:id="tripListViewUpcoming" prefWidth="247.0" style="-fx-background-color: #fff;" VBox.vgrow="ALWAYS" />
<StackPane prefHeight="15.0" prefWidth="200.0" styleClass="trip-list-header" style="-fx-border-width: 2px 0px 2px 0px" VBox.vgrow="NEVER">
<children>
<Label styleClass="label-header" text="PAST TRIPS" />
</children>
</StackPane>
<ListView fx:id="tripListViewPast" prefWidth="247.0" style="-fx-background-color: #fff;" VBox.vgrow="ALWAYS" />
The downside is that the second list view does not come immediately after the last cell in the first list view, and both list views scroll interdependently.
first of all: I have tried:
fxml loader exception "root value is already specified" I never specified a root value
javafx exception : Controller value already specified
LoadException: Root value already specified on custom control
But no solution worked for me: I deleted the fx:controller tag from my FXML -> Exception, added fx:root type="BorderPanealways the same Exception:
Caused by: java.lang.RuntimeException: javafx.fxml.LoadException: Root value already specified
When I remove the statement fxmlLoader.setRoot(this) from my custom controller no Exception is thrown but the layout is empty. For better understanding, below are my code snippets from my MainScreenController where I want to add the custom controller as child and my CustomController class ImageContainer
Help is appreciated!
Code snippet MainScreenController (only a snippet):
public class MainScreenController{
public TextField tf_userName;
public ListView lv_listView;
public FlowPane fp_contentFlowPane;
public SplitPane sp_splitPane;
public void onItemClicked(MouseEvent mouseEvent) throws IOException {
int index = lv_listView.getSelectionModel().getSelectedIndex();
if (mouseEvent.getButton().equals(MouseButton.SECONDARY)) {
if (index >= 0) {
lv_listView.getItems().remove(index);
userList.remove(index);
}
}
else{
ImageContainer imgC = new ImageContainer(4,2,"location");
fp_contentFlowPane.getChildren().add(imgC);
}
}}
Code of my Custom controller, ImageContainer:
public class ImageContainer extends Pane {
public HBox hbx_elementContainer;
public Label lb_likeCount;
public Label lb_commentCount;
public Label lb_location;
public Label lb_accountHolder;
public ImageView iv_feedImage;
private String imageLink;
public ImageContainer(int likeCount, int commentCount, String location) {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/image_container.fxml"));
fxmlLoader.setController(this);
fxmlLoader.setRoot(this);
try {
fxmlLoader.load();
} catch (IOException e) {
throw new RuntimeException(e);
}
this.lb_likeCount.setText(String.valueOf(likeCount));
this.lb_commentCount.setText(String.valueOf(commentCount));
this.lb_location.setText(location);
Image image = new Image("/sampleFoto.JPG");
iv_feedImage.setImage(image);
}
}
FXML file of the layout I want to set:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.text.Font?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1">
<bottom>
<HBox fx:id="hbx_elementContainer" prefHeight="31.0" prefWidth="600.0" BorderPane.alignment="CENTER">
<children>
<Label fx:id="lb_likeCount" contentDisplay="TOP" text="Label">
<HBox.margin>
<Insets right="10.0" />
</HBox.margin></Label>
<Label fx:id="lb_commentCount" text="Label">
<HBox.margin>
<Insets right="20.0" />
</HBox.margin></Label>
<Label fx:id="lb_location" text="Label" />
<Label fx:id="lb_accountHolder" text="Label" />
<Button mnemonicParsing="false" text="Download">
<font>
<Font name="Arial Bold" size="11.0" />
</font>
<HBox.margin>
<Insets right="10.0" />
</HBox.margin>
</Button>
</children>
</HBox>
</bottom>
<center>
<AnchorPane prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
<ImageView fx:id="iv_feedImage" fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
</center>
</BorderPane>
I'm trying to pass a String between scenes in JavaFX, I already followed the some answers but it seems that they don't work because the string is null in the new scene.
Here's my MainControler:
public class FXMLDocumentController implements Initializable {
#FXML
private Button btn_signup;
#FXML
private TextField et_username;
#FXML
private PasswordField et_password;
#FXML
private Hyperlink link_login;
Stage prevStage;
public void setPrevStage(Stage stage){
this.prevStage = stage;
}
#FXML
private void handleButtonAction(ActionEvent event) throws IOException {
if(btn_signup == event.getSource()){
Conector conn = new Conector();
if (conn.checkUser(et_username.getText(), et_password.getText())) {
FXMLLoader myLoader = new FXMLLoader(getClass().getResource("FXMLTasker.fxml"));
Pane myPane = (Pane)myLoader.load();
Scene scene = new Scene(myPane);
Stage stage = new Stage();
stage.setResizable(false);
stage.setScene(scene);
FXMLTaskerController controler = new FXMLTaskerController();
controler.setUser(et_username.getText());
myLoader.setController(controler);
prevStage.close();
stage.show();
}else {
JOptionPane.showMessageDialog(null, "Usuario o ContraseƱa incorrecta");
}
}else if (link_login == event.getSource()){
System.out.println("Registrate!");
}
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
Here's the other class controler, the one where i want my String.
public class FXMLTaskerController implements Initializable {
#FXML private ListView list_todo;
#FXML private ListView list_done;
#FXML public String username;
private void handleButtonAction(ActionEvent event) {
}
#Override
public void initialize(URL url, ResourceBundle rb) {
System.out.println(username);
list_todo.setCellFactory(new TaskCellFactory());
list_done.setCellFactory(new TaskCellFactory());
try {
getTasks();
} catch (IOException ex) {
Logger.getLogger(FXMLTaskerController.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void setUser(String username){
this.username = username;
}
public void getTasks() throws IOException{
Conector con = new Conector();
for(Task task: con.obtenerTareas("pepin")){
System.out.println(task);
if(task.isState()){
list_done.getItems().add(task);
}else{
list_todo.getItems().add(task);
}
}
}
}
And here are the fxml files:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Hyperlink?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane prefHeight="400.0" prefWidth="500.0" style="-fx-background-color: #0288D1; -fx-border-color: #01579B; -fx-border-width: 5;" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="desktop_tasker.FXMLDocumentController">
<children>
<Label layoutX="215.0" layoutY="34.0" text="Sign In" textFill="WHITE">
<font>
<Font size="23.0" />
</font>
</Label>
<Hyperlink fx:id="link_login" layoutX="150.0" layoutY="269.0" onAction="#handleButtonAction" text="Not registered yet? Click here." textFill="WHITE" />
<TextField fx:id="et_username" layoutX="21.0" layoutY="102.0" prefHeight="25.0" prefWidth="425.0" promptText="Username" style="-fx-prompt-text-fill: #ffffff; -fx-background-color: #0288D1;" />
<Separator layoutX="27.0" layoutY="126.0" prefHeight="3.0" prefWidth="425.0" />
<Separator layoutX="27.0" layoutY="192.0" prefHeight="3.0" prefWidth="425.0" />
<Button fx:id="btn_signup" layoutX="27.0" layoutY="222.0" mnemonicParsing="false" onAction="#handleButtonAction" prefHeight="23.0" prefWidth="425.0" style="-fx-background-color: #FFA000; -fx-prompt-text-fill: #ffffff;" text="SignUp" textFill="WHITE" />
<PasswordField fx:id="et_password" layoutX="21.0" layoutY="167.0" prefHeight="25.0" prefWidth="425.0" promptText="Password" style="-fx-background-color: #0288D1; -fx-prompt-text-fill: #ffffff;" />
</children>
</AnchorPane>
And the other one:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="557.0" prefWidth="1012.0" style="-fx-background-color: #0288D1;" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="desktop_tasker.FXMLTaskerController">
<children>
<SplitPane dividerPositions="0.5811881188118811" layoutX="-8.0" layoutY="35.0" prefHeight="529.0" prefWidth="1027.0" style="-fx-background-color: #EEEEEE;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="28.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<ListView fx:id="list_todo" layoutY="-8.0" prefHeight="527.0" prefWidth="584.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<ListView fx:id="list_done" layoutY="14.0" prefHeight="527.0" prefWidth="420.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children></AnchorPane>
</items>
</SplitPane>
<MenuBar prefHeight="30.0" prefWidth="1012.0">
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="Close" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Edit">
<items>
<MenuItem mnemonicParsing="false" text="Delete" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About" />
</items>
</Menu>
</menus>
</MenuBar>
</children>
</AnchorPane>
As you can see I tried to use a controler and using a set pasing the String, the problem is that when I open the new scene, his controler resets and the String is no longer there, any idea why or how to solve this?
If you want to set a Controller with myLoader.setController(controler); you must do it before calling Pane myPane = (Pane)myLoader.load(); and also remove fx:controller="desktop_tasker.FXMLTaskerController" from FXMLTasker.fxml, else you get a LoadException: Controller value already specified.
See JavaDoc FXMLLoader.setController(Object controller):
Sets the controller associated with the root object. The value passed to this method is used as the value of the fx:controller attribute. This method must be called prior to loading the document when using controller event handlers when an fx:controller attribute is not specified in the document.
Alternatively you can request the Controller from FXMLLoader:
FXMLTaskerController controler = (FXMLTaskerController)myLoader.getController();
controler.setUser(et_username.getText());
But thereby you can't assume that username is set in initialize(URL url, ResourceBundle rb) and should removed from there.
I am trying to create an HTML editor (learning purposes) and I am trying to make program as dynamic as possible. I want to find FXML variable, like TextField, by it's id and retrieve the text in the textfield when I press the button.
I have 2 Map variables set up
public FXMLDocumentController() {
this.HTMLtags = new HashMap<>();
HTMLtags.put("pressMeButton", "h2.fx-h2");
HTMLtags.put("setNewsMessageButton", "p.fx-message");
this.elementsMap = new HashMap<>();
elementsMap.put("pressMeButton", "newsTitle");
elementsMap.put("setNewsMessageButton", "newsMessage");
}
HTMLtags holds the button ID and HTML tag, which is going to be edited.
elementsMap holds button ID and TextView ID that it suppose to grab text from. Kinda like "binding specific button to specific textfield".
private void changeText(ActionEvent event) throws IOException {
Object source = event.getSource();
Button clickedButton = (Button) source;
System.out.println(HTMLtags.get(clickedButton.getId()));
System.out.println(elementsMap.get(clickedButton.getId()));
writeToHTML(HTMLtags.get(clickedButton.getId()), elementsMap.get(clickedButton.getId()));
}
Method above correctly retrieves IDs of buttons and HTML tags that need to be edited.
Here is the code that sets the text in the HTML
private void writeToHTML(String HTMLTag, String textField) {
File input = new File(filePath);
Document doc;
try {
doc = Jsoup.parse(input, "UTF-8");
Element head = doc.select(HTMLTag).first();
originalText = head.toString();
TextField textFieldName = new TextField();
textFieldName.setId(textField);
head.text(textFieldName.getText());
System.out.println("Original Text is: " + originalText);
System.out.println("Modified Text is: " + head);
Path path = Paths.get(filePath);
Charset charset = StandardCharsets.UTF_8;
String content = new String(Files.readAllBytes(path), charset);
content = content.replaceAll(originalText, head.toString());
Files.write(path, content.getBytes(charset));
} catch (IOException ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
The problem is that I dunno how to find and retrieve text from textfield specifically in this part of code
TextField textFieldName = new TextField();
textFieldName.setId(textField);
head.text(textFieldName.getText());
I want to do it dynamically without declaring each FXML element through
#FXML private TextField "name of the fx:id" and matching each element through loop.
I want to do it similar to the way I get ID/value of the button through ActionEvent.
EDIT:
here is the full FXML btw
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.66" xmlns:fx="http://javafx.com/fxml/1" fx:controller="newsletter.editor.FXMLDocumentController">
<children>
<ScrollPane fitToWidth="true" prefHeight="800.0" prefWidth="1280.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<content>
<VBox alignment="CENTER" prefHeight="450.0">
<children>
<HBox alignment="CENTER">
<children>
<Label alignment="CENTER" minHeight="25.0" minWidth="192.0" prefHeight="50.0" prefWidth="192.0" text="Newsletter Title" wrapText="true">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField id="newsTitle" fx:id="newsTitle" prefHeight="28.0" prefWidth="180.0" promptText="Write here" HBox.hgrow="ALWAYS" />
</children>
</HBox>
<HBox prefHeight="100.0" prefWidth="200.0">
<children>
<TextArea fx:id="newsMessage" prefHeight="100.0" prefWidth="766.0" />
</children>
</HBox>
<HBox prefHeight="100.0" prefWidth="200.0" />
<HBox prefHeight="100.0" prefWidth="200.0" />
<HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
<children>
<Button fx:id="setNewsMessageButton" mnemonicParsing="false" onAction="#changeText" text="MAGIC" />
<Button fx:id="pressMeButton" mnemonicParsing="false" onAction="#changeText" text="Press Me for Magic">
<HBox.margin>
<Insets right="10.0" />
</HBox.margin>
</Button>
<Button fx:id="filePathButton" mnemonicParsing="false" onAction="#filePathSave" text="Select Path">
<HBox.margin>
<Insets right="10.0" />
</HBox.margin>
</Button>
<Button fx:id="popoverButton" mnemonicParsing="false" onAction="#popOverTrigger" text="PopOver Test">
<HBox.margin>
<Insets right="10.0" />
</HBox.margin>
</Button>
</children>
</HBox>
</children>
<padding>
<Insets left="20.0" right="20.0" />
</padding>
</VBox>
</content>
</ScrollPane>
</children>
</AnchorPane>
You can perform an id lookup to find the TextField.
Parent parent = getTextFieldParent(); // the Parent (or Scene) that contains the TextFields
TextField textField = (TextField) parent.lookup("#myTextField");
if (textField != null)
String text = textField.getText();
Yes, your need method lookup(). Not only Parent class has this method, it also has at Panel classes like FlowPane, AnchorPane and many other. Also this method in Scene class.
But! This method looking only after scene show. I don't now, why it happens, but before Scene show(), lookup() only finds top-level panel. And after show() it finds element by id, like scene.lookup("#myId");
Symbol # is required.
Also lookup() method can find element without id, by the type.
Example: scene.lookup("FlowPane"); (without #) will find the first FlowPane in your .fxml file. And scene.lookupAll("ImageView"); will return the massive with all ImageView elements in scene.