JavaFX - How to set value to a textfield inside a tab? - java

I am trying to set value to a text field which is inside a Tab. I am having multiple tabs and I want to set value to text field inside each tab.
Any idea as to how to set the text for textfield inside the tab?
I am using the below code to update the value for the textfield, but nothing's happening while trying to do the same.
Code:
public class FXMLController {
#FXML
private Button inputXmlFileBtn;
#FXML
private TextField inputXmlName;
#FXML
private TabPane xmlData;
#FXML
private Tab vendorHeaderFb;
#FXML
private TextField vendorHeader1;
Label label;
public String inputXmlFileChooser() throws ParserConfigurationException,
SAXException, IOException, JAXBException {
FileChooser fileChooser = new FileChooser();
// Set extension filter
fileChooser.getExtensionFilters().addAll(
new ExtensionFilter("XML files (*.xml)", "*.xml"));
// Open Dialog
File file = fileChooser.showOpenDialog(null);
String xmlPath = "";
xmlPath = file.getPath();
// Set the path for inputXmlName text field
if (file != null) {
inputXmlName.setText(xmlPath);
}
//Unmarshall
label = this.unmarshallXml();
System.out.println(label.getVendorHeader1());
vendorHeaderFb = new Tab();
vendorHeader1 = new TextField();
vendorHeader1.setText(label.getVendorHeader1());
vendorHeaderFb.setContent(vendorHeader1);
return xmlPath;
}
Updated Code including the Pojo class for FXML.
public class FXMLController {
#FXML
private Button inputXmlFileBtn;
#FXML
private TextField inputXmlName;
#FXML
private TabPane xmlData;
#FXML
private Tab vendorHeaderFb;
#FXML
private TextField VendorHeader1;
Label label;
public String inputXmlFileChooser() throws ParserConfigurationException,
SAXException, IOException, JAXBException {
FileChooser fileChooser = new FileChooser();
// Set extension filter
fileChooser.getExtensionFilters().addAll(
new ExtensionFilter("XML files (*.xml)", "*.xml"));
// Open Dialog
File file = fileChooser.showOpenDialog(null);
String xmlPath = "";
xmlPath = file.getPath();
// Set the path for inputXmlName text field
if (file != null) {
inputXmlName.setText(xmlPath);
}
//Unmarshall
label = this.unmarshallXml();
System.out.println(label.getVendorHeader1());
FXMLProps fxmlProps = new FXMLProps();
fxmlProps.setVendorHeader1(label.getVendorHeader1());
System.out.println(fxmlProps.getVendorHeader1());
VendorHeader1 = new TextField();
VendorHeader1.setText(fxmlProps.getVendorHeader1());
//vendorHeaderFb.setContent(vendorHeader1);
//vendorHeader1.setText(label.getVendorHeader1());
//vendorHeaderFb.setContent(vendorHeader1);
return xmlPath;
}
POJO/Property Class
public class FXMLProps {
private final SimpleStringProperty VendorHeader1 = new SimpleStringProperty(
"");
public FXMLProps() {
}
public FXMLProps(String VendorHeader1) {
setVendorHeader1(VendorHeader1);
}
public String getVendorHeader1() {
return VendorHeader1.get();
}
public void setVendorHeader1(String vH1) {
VendorHeader1.set(vH1);
}
}
I am still not able to set the value for text field vendorHeader1.
Can someone point out what's going wrong?

You have to apply a Binding between the text property of the TextField and the SimpleStringProperty that is used for the value. You will have to make the vendor header property of your FXMLProps public in a way that enables Binding options in other classes:
public class FXMLProps {
private final SimpleStringProperty vendorHeader = new SimpleStringProperty("");
public FXMLProps() {}
public FXMLProps(String vendorHeader) {
setVendorHeader(vendorHeader);
}
public String getVendorHeader() {
return VendorHeader1.get();
}
public void setVendorHeader(String vendorHeaderText) {
vendorHeader.set(vendorHeaderText);
}
// this is needed for the Binding
public final SimpleStringProperty vendorHeaderProperty() {
return vendorHeader;
}
}
Then somewhere in your application (maybe in start()) you need to create the Binding like
// bind those two properties (TextField, SimpleStringProperty)
Bindings.bindBidirectional(vendorHeader1.textProperty(), fxmlProps.vendorHeaderProperty());

Related

java: no suitable method found for addAll(java.util.List<java.lang.String>)

I want to pass an array list. I think the error is caused by the search list. i know The addAll method works with collections. Thats why its saying my searchlist can’t be converted to a collection, how can i solve thisThis is the error
my seacrh controller
#FXML
private ListView<?> ListView;
#FXML
private TextField searchbar;
#FXML
private Button searchbtn;
HelloController hc = new HelloController();
public void initialize(URL url, ResourceBundle resourceBundle){
ListView.getItems().addAll();
}
public void searchbtn(ActionEvent actionEvent) throws IOException {
ListView.getItems().clear();
ListView.getItems().addAll(hc.searchList(searchbar.getText(),blxckie));//error is detected
here :java: no suitable method found for addAll(java.util.List<java.lang.String>)
}
}
My Hello controller with searchlist
#FXML
private Button btnhome;
#FXML
private Button btnsearch;
#FXML
private Button btnview;
#FXML
private ImageView image;
#FXML
private TextField numfeild;
#FXML
public TextField timefeild;
private static String lope;
public static ArrayList<String> blxckie = new ArrayList<String>();
#FXML
public <sel> File singleFileChooser(ActionEvent event) throws IOException {
FileChooser fc = new FileChooser();
File selectedFile = fc.showOpenDialog(null);
if (selectedFile != null) {
File sel = new File(selectedFile.getAbsolutePath());
String lope = String.valueOf(sel);
int countofwords = wordcount(sel);
System.out.println("words are : " + countofwords);
//numfeild.setText(Integer.toString(().throwDice()));
getRandomWord(String.valueOf(sel));
numfeild.setText(numfeild.getText() + countofwords);
numfeild.setStyle("-fx-text-inner-color: blue");// to change text-field color
return sel;
} else {
System.out.println("hmmm, atleast it works but still invalid file");
}
return null;
}
public int wordcount(File sel) {
long start = System.currentTimeMillis();
int countofwords = 0;
try {
BufferedReader br = new BufferedReader(new FileReader(sel));
String lineStr = null;
String wordsArr[] = null;
while ((lineStr = br.readLine()) != null) {
wordsArr = lineStr.split(" ");
countofwords = countofwords + wordsArr.length;
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
long time = end - start;
System.out.println(time);
timefeild.setText(timefeild.getText() + time);
timefeild.setStyle("-fx-text-inner-color: blue");// to change text-field color
return countofwords;
}
public String getRandomWord(String sel ) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(sel))) {
String line;
while ((line = reader.readLine()) != null) {
String[] wordline = line.split("\\s+");
if (blxckie.size() < 20) {
for (String word : wordline) {
blxckie.add(word);
System.out.println(blxckie);
}
}
}
Random rand = new Random();
return blxckie.get(rand.nextInt(blxckie.size()));
}
}
#FXML
void searchpg(ActionEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("search.fxml"));
Parent root = loader.load();
SearchController searchControllera = loader.getController();
Stage stage = new Stage();
stage.setScene(new Scene(root));
stage.show();
}
public List<String> searchList(String searchWords, List<String> listOfStrings) {//searchlist
List<String> searchWordsArray = Arrays.asList(searchWords.trim().split(""));
return listOfStrings.stream().filter(input ->{
return searchWordsArray.stream().allMatch(word ->
input.toLowerCase().contains(word.toLowerCase()));
}).collect(Collectors.toList());
}
Anyform of help will be muchly appriciated
JavaFx uses observable objects so you cannot set a List as items for your ListView.
But you can wrap your List with FXCollections.observableArrayList(list).
And as khelwood commented, you have to declare the generics of your view as ListView<String>.
Note that you have to add/remove the elements to/from the ObservableList to see the modification in your UI.
If you can change the return type in the controller's searchList you can also use another Collector to directly get the ObersvableList: Collectors.toCollection(FXCollections::observableArrayList)

JavaFX TableView Issues Adding Rows + Organizing Multi Controller and FXML App

I'm new to JavaFX and I've been at this code for about 8 hours now and I've become a bit delusional with the code. My two main problems are:
Can't add new items to the TableView using my popUp box display().
Feels messy and unorganized. Any tips for better communication between FXML and Controllers? (Again I'm new so it could be that I've stared too long at it)
My main class
public class Main extends Application {
public static Stage primaryStage;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage window) throws Exception {
try {
primaryStage = new Stage();
window = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("Fissto.fxml"));
Scene scene = new Scene(root);
window.setTitle("Fissto - the File Storage App!");
window.setScene(scene);
window.show();
}catch(Exception e){
e.printStackTrace();
}
// C.setLibraryStage();
}
}
My main Controller class (I have two sub ones that connect in the Fissto.fxml)
public class Controller implements Initializable{
Main main;
#FXML LibraryController libraryController = new LibraryController();
#FXML MergePageController mergePageController = new MergePageController();
private AddImageController addImageController = new AddImageController();
#FXML public void initialize(URL location, ResourceBundle resources){
System.out.println("View is now loaded!");
main = new Main();
libraryController.init(this);
mergePageController.init(this);
addImageController.init(this);
}
//Interface Initialization
public void setMergeStage() throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("Controllers/MergePage.fxml"));
Scene scene = new Scene(root);
main.primaryStage.setScene(scene);
}
public void setLibraryStage() throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("Controllers/LibraryPage.fxml"));
Scene scene = new Scene(root);
main.primaryStage.setScene(scene);
}
//Closing a window
public void closeWindow(){
main.primaryStage.close();
}
}
And finally the controller for the page that holds the TableView
public class LibraryController {
private Controller main;
//Library TableView Controllers
#FXML public TableView<Image> library;
#FXML private TableColumn<Image, String> NameColumn = new TableColumn<>();
#FXML private TableColumn<Image, ArrayList<String>> TagsColumn = new TableColumn<>();
#FXML private TableColumn<Image, String> CommentsColumn = new TableColumn<>();
#FXML private TableColumn<Image, String> FileLocationColumn = new TableColumn<>();
#FXML private TableColumn<Image, Integer> PointsColumn = new TableColumn<>();
public void init(Controller main){
System.out.println("LibraryPage Loading");
this.main = main;
addDataToColumns();
library = new TableView<>();
library.getItems().setAll(getImages());
System.out.println("LibraryPage Loaded");
}
//Initializes the column titles
private void addDataToColumns(){
NameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
TagsColumn.setCellValueFactory(new PropertyValueFactory<>("tags")); //TODO Convert to String format
CommentsColumn.setCellValueFactory(new PropertyValueFactory<>("comments"));
FileLocationColumn.setCellValueFactory(new PropertyValueFactory<>("filelocation"));
PointsColumn.setCellValueFactory(new PropertyValueFactory<>("points"));
}
//Gets all of the images
private ObservableList<Image> getImages() {
//TODO: Add where to actually get the data from
ObservableList<Image> images = FXCollections.observableArrayList();
String s = "Dog, Cat, Jumping Jack,";
ArrayList<String> list = Image.getTagOrganizer(',', s);
images.add(new Image("Test", list, "Comment", "No File Location, yet!", 10));
String k = "Calculus, Complex Numbers, Hard dude,";
ArrayList<String> list2 = Image.getTagOrganizer(',', k);
images.add(new Image("Number2", list2, "I love MathClub", "No File Location, yet!", -10));
return images;
}
This last class is the popup menu that takes in input to put in the GridPane
public class AddImageController {
private Controller main;
public void init(Controller main){
System.out.println("ImagePage Loaded");
this.main = main;
}
//Submitting an image to the library from the AddImagePage
public TextField nameInput;
public TextField tagsInput;
public TextField commentInput;
public TextField pointsInput;
public Label errorMessage;
/** TODO: Make it so that it writes to file then theoretically, the main controller should read from file every so often
* Main functionality for adding the information from the form to the database */
public void submitImage(){
if(!(nameInput.getText().trim().isEmpty()) && !(tagsInput.getText().trim().isEmpty()) && !(pointsInput.getText().trim().isEmpty())) {
if (isInt(pointsInput)) {
// System.out.print("Sent to database, *whoosh!*");
LibraryController c = new LibraryController();
ArrayList<String> s = Image.getTagOrganizer(',', tagsInput.getText());
Image image = new Image(nameInput.getText(), s, commentInput.getText(),"Location Needed", Integer.parseInt(pointsInput.getText()));
c.library.getItems().add(image);
clearInputs();
}
}else {
errorMessage.setText("Fill every field");
}
}
//Clears the input fields in the AddImagePage
public void clearInputs(){
nameInput.clear();
tagsInput.clear();
commentInput.clear();
pointsInput.clear();
errorMessage.setText("");
}
//Submission format verifiers
private boolean isInt(TextField input){
try{
int i = Integer.parseInt(input.getText());
errorMessage.setText("");
return true;
}catch (NumberFormatException e){
System.out.println("Oh no: " + input.getText() + " is not an integer");
errorMessage.setText("Points must be a number");
return false;
}
}
//Image Selection Handler
public void imageSelectionHandler(){
}
}
I understand it may be hard to read, so any feedback on how to make it easier to read in the future is much appreciated.

Changing TextArea in another class

There is a class FXMLDocumentController.
There is a class ThreadForFile which has been inheriting from class Thread (which I read data from a file)
After I pressed the button (in the class FXMLDocumentController) I create a flow of class ThreadForFile.
I need to in the class ThreadForFile, when reading, the string displayed in the TextArea. But I can not figure out if I pass a parameter TextArea, and change it in the constructor, then there is a change in this component.But if I assign the class field this TextArea, it displays an error :
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
ThreadForFile extends Thread
private String path;
private long ms;
private int id;
private String name;
private boolean stop = false;
private HTMLEditor web;
private DB db = new DB();
private Button doc;
public void setMS(long ms){
System.out.print(ms);
this.ms =ms;
}
public ThreadForFile(String name,String path,long ms,int id,Button doc) {
this.path = new String();
this.path = path;
this.ms = ms;
this.id = id;
this.name = name;
this.doc = new Button();
this.doc = doc;
}
public void Stop(boolean stop){
this.stop = stop;
}
public void run( ) {
try {
doc.setText("Zsczsc");
System.out.print("asdasd");
File file = new File(path);
File file1 = new File("C:\\out.txt");
BufferedReader br = new BufferedReader (new InputStreamReader(new FileInputStream(file), "UTF-8"));
String line = null;
while( (line = br.readLine()) != null){
if(!Thread.interrupted()) //Проверка прерывания
{
if(!stop){
PrintWriter out = new PrintWriter(file1.getAbsoluteFile());
try {
sytem.out.print(line+"\n");
} finally {
out.close();
}
Thread.sleep(db.getParam().getMS()*1000);
System.out.print("ms" + db.getParam().getMS());
}
}else{
return;
}
}
} catch (Exception ex) {
System.out.print(ex.toString());
Logger.getLogger(ThreadForFile.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void read()throws FileNotFoundException, IOException
{
}
FXMLDocumentController
<!-- language: JavaFX -->
public class FXMLDocumentController implements Initializable {
private long ms = 5;
private ObservableList<ThreadForFile> threadForFile = FXCollections.observableArrayList();
private ObservableList<threadFile> threadFile = FXCollections.observableArrayList();
private int index ;
private DB db = new DB();
private Parametrs param = new Parametrs();
#FXML
private Button btnAdd;
#FXML
private Button btnStop;
#FXML
public Button btnDel;
#FXML
private Button btnStart;
#FXML
private TextField textFValueText;
#FXML
private TextField textFMs;
#FXML
private Button btnUpdate;
#FXML
public static TextArea textArea;
#FXML
private Label nameLabel;
#FXML
private Label pathLabel;
#FXML
private TextField textFName;
#FXML
private TextField textFPath;
#FXML
private TableColumn nameCol;
#FXML
private TableColumn pathCol;
#FXML
private TableColumn statCol;
public static FXMLDocumentController doc;
private ResourceBundle bundle;
#FXML
private TableView table;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
}
#Override
public void initialize(URL url, ResourceBundle rb) {
bundle = rb;
System.out.println("You clicked me!");
FileRead file = new FileRead(FXMLDocumentController.this);
Tab1();
Tab2();
Tab3();
param = db.getParam();
System.out.print(param.getMS() + " " + param.getValue());
}
public void Tab1()
{
}
public void Tab2()
{
//root.getChildren().addAll(btn,table,btnStop,btnStart,btnDel,nameField,pathField,name,path);
btnAdd.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
threadFile.add(new threadFile(textFName.getText(),textFPath.getText(),1));
threadForFile.add(new ThreadForFile(threadFile.get(threadFile.size()-1).getName(),threadFile.get(threadFile.size()-1).getPath(),ms,threadFile.size(),btnAdd));
threadForFile.get(threadForFile.size()-1).start();
index = table.getSelectionModel().getSelectedIndex();
System.out.print(index+ "\n");
}
});
.
.
.
.
.
.
.
.
.
.
}
You are trying to access a JavaFX Control outside the JavaFX Application thread.
Never use your controls, out of your Controller or pass them as a parameter to other methods. Instead, try to pass data to the controller, which in turn will set it to the controls inside the controller.
Some useful links are on passing data to the Controller :
Passing Parameters JavaFX FXML
How to have constructor with arguments for controller?
Some useful links on multi-threading in JavaFX:
How do I safely modify JavaFX GUI nodes from my own Thread?
JavaFX working with threads and GUI

How to set String Or Text in JavaFX TextField Controller from another JavaFX Controller

In my javafx Application we have two FXML files first.fxml and second.fxml, same firstController.java and secondController.java now the main problem is first.fxml contain TextField name and on Button
when user will click on that button second.fxml display in second.fxml I have one ComboBox and one Button when user click second.fxml button I want to set that combobox value to first.fxml name TextField.
I am finding solution on Google from last three days but didn't get proper solution. In Java swing I was doing this using static public field that allowed me to access JFrame from another JFrame.
Eagerly waiting for helpful reply.
Expose a StringProperty from your SecondController. When the button is pressed, set its value:
public class SecondController {
private final StringProperty selectedValue = new SimpleStringProperty(this, "selectedValue", "");
public final StringProperty selectedValueProperty() {
return selectedValue ;
}
public final void setSelectedValue(String value) {
selectedValue.set(value);
}
public final String getSelectedValue() {
return selectedValue.get();
}
#FXML
private final ComboBox<String> comboBox ;
#FXML
private void handleButtonPress() {
selectedValue.set(comboBox.getValue());
}
}
In your FirstController, provide a method for setting the text:
public class FirstController {
#FXML
private TextField textField ;
public void setText(String text) {
textField.setText(text);
}
}
Now when you load the FXML files, just observe the property in the SecondController and call the method in FirstController when it changes:
FXMLLoader firstLoader = new FXMLLoader(getClass().getResource("first.fxml"));
Parent first = firstLoader.load();
FirstController firstController = firstLoader.getController();
FXMLLoader secondLoader = new FXMLLoader(getClass().getResource("second.fxml"));
Parent second = secondLoader.load();
SecondController secondController = secondLoader.getController();
secondController.selectedValueProperty().addListener((obs, oldValue, newValue) ->
firstController.setText(newValue));

JavaFX custom component get action from button in custom component

I want to get the event of two buttons in my custom component.
the component is a imageview with two buttons to move between images, but I need to get the position of the image that is currently displayed, Im storing the key of the image, but I need to know when a button have been pressed outside the custom component, so I can change a Label outside the custom component.
public class TransitionSlider extends AnchorPane {
#FXML
private AnchorPane transitionSliderPane;
#FXML
private ImageView transitionSliderImageView;
#FXML
private Button prevButton;
#FXML
private Button nextButton;
private Map<Integer,Image> imageMap;
private Image currentImage;
private DropShadow imageViewDropShadow;
private int currentKey = 1;
private Image[] images;
public TransitionSlider() {
FXMLLoader loader = new FXMLLoader();
loader.setRoot(this);
loader.setController(this);
loader.setLocation(this.getClass().getResource("TransitionSlider.fxml"));
loader.setClassLoader(this.getClass().getClassLoader());
try {
loader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
prevButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
if(currentKey <= 1){
currentKey = currentKey + 1;
currentImage = imageMap.get(currentKey);
createTransition(transitionSliderImageView, currentImage);
}
}
});
nextButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
if(currentKey <= imageMap.size()){
currentKey = currentKey - 1;
currentImage = imageMap.get(currentKey);
createTransition(transitionSliderImageView, currentImage);
}
}
});
}
// more code here...
}
I want a way to capture the event and get variables inside the component and change a label outside the custom component...
for example:
public class Gallery extends Application {
#FXML
TransitionSlider ts;
Label label;
#Override
public void start(Stage stage) throws Exception {
label = new Label();
TransitionSlider ts = new TransitionSlider();
ts.captureButtonEvent(){ // need a way to capture this
label.setText(ts.getCurrentKey());
}
// more code here....
}
If I understood your question correctly, you want a binding.. Follow these steps:
1) Put bindable field and its getter/setter into TransitionSlider:
private IntegerProperty currentKey = new SimpleIntegerProperty(1);
public int getCurrentKey() {
return currentKey.get();
}
public void setCurrentKey(int val) {
return currentKey.set(val);
}
public IntegerProperty currentKeyProperty() {
return currentKey;
}
2) Bind this property to label's text in Gallery:
label = new Label();
TransitionSlider ts = new TransitionSlider();
label.textProperty.bind(ts.currentKeyProperty().asString());
Alternatively, if you want to do stuff more than just changing label's text, you can add a change listener to currentKeyProperty:
ts.currentKeyProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> observable,
Number oldValue, Number newValue) {
label.setText(newValue);
// do other stuff according to "oldValue" and "newValue".
}
});

Categories