What do I want to do?
I am facing a problem with a fxml based javafx application. I want to create a simple form sheet to enter some numerical values that are supposed to be stored in a file uppon confirmation.
What is the problem?
The form does perfectly what it is supposed to do, except that I cannot mouse click the elements within the two GridPanes. I can enter the values via switching TextFields by pressing the tab button, but that is of course not the ideal way. I have already added TextFields and CheckBoxes within the AnchorPane directly, and they are clickable, but within the GridPanes this does not work. The FlowPane within the same AnchorPane also works perfectly fine.
To me it seems that the GridPanes act as if it was set to mouseTransparent="true", but this is not the case and I already tried explicitly setting it to false as well. I cannot find the reason for this behavior so perhaps somebody of you has an idea.
EDIT: After playing around with an addtional GridPane in the same tab I found out that it is not a general GridPane issue in this file. For a GridPane with only checkboxes and only one Anchor the element can be accessed. Is there some overlap preventing accessability via mouse?
Within an initializer function of a separate class the scene is set:
BorderPane root = FXMLLoader.load(getClass().getResource("..\\initializeSeason\\InitializeSeason.fxml"));
Scene scene = new Scene(root,600,900);
stage.setScene(scene);
stage.show();
The xfml file is build as follows (I'm sorry for the German names):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.layout.FlowPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.text.Text?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.control.RadioButton?>
<?import javafx.scene.control.CheckBox?>
<BorderPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.LeagueRulesController" >
<center>
<TabPane tabClosingPolicy="UNAVAILABLE" >
<tabs>
<Tab style="-fx-font-weight:bold" text="Liga Regeln" >
<AnchorPane >
<children>
<GridPane AnchorPane.topAnchor="10.0" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" hgap="15" vgap="15" >
<columnConstraints>
<ColumnConstraints hgrow="ALWAYS" />
</columnConstraints>
<children>
<Label text="Anzahl der Zeichen im Teamnamen: " GridPane.columnIndex="0" GridPane.rowIndex="0"/>
<TextField fx:id="numberOfShortNameChars" alignment="BASELINE_RIGHT" prefWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="0"/>
<Label text="Anzahl der Touchdown Differenz Einträge: " GridPane.columnIndex="0" GridPane.rowIndex="1"/>
<TextField fx:id="numberOfTDDiffEntries" alignment="BASELINE_RIGHT" prefWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
<GridPane fx:id="tdDiffEntrys" hgap="15" vgap="15" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Label text="Erhält Gewinnerteam bei Spielaufgabe maximale Punktzahl?:" GridPane.columnIndex="0" GridPane.rowIndex="3"/>
<CheckBox fx:id="isConcedeMaxWin" GridPane.columnIndex="1" GridPane.rowIndex="3"></CheckBox>
</children>
</GridPane>
<FlowPane orientation="HORIZONTAL" alignment="BOTTOM_RIGHT" hgap="5" AnchorPane.topAnchor="10.0" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0">
<Button fx:id="okButton" text="OK" onAction="#handleOK"> </Button>
<Button fx:id="abbrechenButton" text="Abbrechen" onAction="#handleAbbrechen"> </Button>
</FlowPane>
</children>
</AnchorPane>
</Tab>
<Tab style="-fx-font-weight:bold" text="Teams verwalten">
</Tab>
</tabs>
</TabPane>
</center>
</BorderPane>
Although I am sure the problem can be found within the .fxml file I also add the LeagueRulesController class.
package application;
import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class LeagueRulesController implements Initializable{
private ArrayList<TextField> tdDiffs;
private ArrayList<TextField> points;
@FXML
private CheckBox isConcedeMaxWin;
@FXML
private Button okButton;
@FXML
private Button abbrechenButton;
@FXML
private void handleAbbrechen(ActionEvent actionEvet) {
Stage stage = (Stage) abbrechenButton.getScene().getWindow();
// do what you have to do
stage.close();
}
@FXML
private void handleOK(ActionEvent actionEvet) {
Stage stage = (Stage) abbrechenButton.getScene().getWindow();
stage.close();
}
@FXML
private TextField numberOfShortNameChars;
@FXML
private TextField numberOfTDDiffEntries;
@FXML
private GridPane tdDiffEntrys;
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
numberOfShortNameChars.setText("25");
numberOfShortNameChars.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
numberFieldListener(numberOfShortNameChars, oldValue,newValue);
}
});
numberOfTDDiffEntries.setText("5");
initializeTDDiffArray();
numberOfTDDiffEntries.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
numberFieldListener(numberOfTDDiffEntries, oldValue,newValue);
initializeTDDiffArray();
}
});
}
private void initializeTDDiffArray() {
tdDiffEntrys.getChildren().clear();
tdDiffs = new ArrayList<>();
points = new ArrayList<>();
tdDiffEntrys.add(new Label("TD Diff"), 0, 0);
tdDiffEntrys.add(new Label("Punkte"), 1, 0);
int numberOfTDDiffEntriesInt;
if(numberOfTDDiffEntries.getText().equals(""))
numberOfTDDiffEntriesInt = 1;
else
numberOfTDDiffEntriesInt =Integer.parseInt(numberOfTDDiffEntries.getText());
for (int i = 0; i < numberOfTDDiffEntriesInt; i++) {
tdDiffs.add(new TextField());
points.add(new TextField());
tdDiffs.get(tdDiffs.size()-1).setText(Integer.toString(i-numberOfTDDiffEntriesInt/2));
points.get(points.size()-1).setText(Integer.toString(i+1));
tdDiffs.get(tdDiffs.size()-1).setAlignment(Pos.BASELINE_RIGHT);
points.get(points.size()-1).setAlignment(Pos.BASELINE_RIGHT);
tdDiffs.get(tdDiffs.size()-1).setPrefWidth(1);
points.get(points.size()-1).setPrefWidth(1);
tdDiffs.get(tdDiffs.size()-1).textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
numberFieldListener(tdDiffs.get(tdDiffs.size()-1), oldValue,newValue);
}
});
points.get(points.size()-1).textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
numberFieldListener(points.get(points.size()-1), oldValue,newValue);
}
});
tdDiffEntrys.add(tdDiffs.get(tdDiffs.size()-1), 0, i+1);
tdDiffEntrys.add(points.get(points.size()-1), 1, i+1);
}
}
private void numberFieldListener(TextField textField, String oldValue,String newValue) {
if(!newValue.matches("\\d*")) {
textField.setText(newValue.replaceAll("[^\\d]", ""));
}
}
}
Thanks in advance, for taking the time.