1

I am new to javaFX and I am trying to populate a my clientDataTable with data from the ObservableList clientData. My ConnectionsPane constructor create a test Client object and I am trying to get my ConnectionsPaneController to populate the table. I am new to javaFX and no matter what I do I cannot seem to get to get the table to populate. Can someone help me out??

I will include the files that are used for this process.

I left out the Client.java class. Adding now.

Thanks!

====

Edit - So I implemented the changes requested below. I also looked up the samples resources and tried to use them. I keep coming back to a null excecption error when trying to set the table items at

clientDataTable.setItems(ConnectionsPane.getClientData());

However when I print out ConnectionsPane.getClientData() it does give me an observable list with clients in it.

Edit 2 - So I spent more time looking at the samples and trying to convert it to my setup as I need this specific menu setup. I also looked at the duplicate post and I updated my code so its not static. The code runs fine now and the client object it create and displayed in the console but it still will not display in the table. I think it might be to do with the controller access but not sure. I never thought a table would be this much hassle :) Can anyone help?

MainMenu.java

package io.ironbytes.corkscrew.models;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class MainMenu extends Application {
    Parent root;
    Stage stage;

    @Override
    public void start(Stage primaryStage) {

        try {
            root = FXMLLoader.load(getClass().getResource("../views/MainMenu.fxml"));
            stage = primaryStage;
            stage.setTitle("Welcome");
     
            Scene scene = new Scene(root);
            stage.setScene(scene);
            stage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    public static void main(String[] args) {
      launch(args);
    }   
}

ConnectionsPaneController.java

package io.ironbytes.corkscrew.controllers;

import io.ironbytes.corkscrew.models.Client;
import io.ironbytes.corkscrew.models.ConnectionsPane;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;

public class ConnectionsPaneController {

 @FXML private TableView<Client> clientDataTable;
 @FXML private TableColumn<Client, String> online;
 @FXML private TableColumn<Client, String> username;
 private ConnectionsPane ConnectionsPane;

 public ConnectionsPaneController() {
  
 }
 
    /**
     * Initializes the controller class. This method is automatically called
     * after the fxml file has been loaded.
     */
    @FXML
    private void initialize() {
       username.setCellValueFactory(cellData -> cellData.getValue().getUsername());

    }
    
    /**
     * Is called by the main application to give a reference back to itself.
     * 
     * @param mainApp
     */
    public void setMainApp(ConnectionsPane ConnectionsPane) {
        this.ConnectionsPane = ConnectionsPane;

     // Prints: [Client [clientID=1, isOnline=true, username=StringProperty [value: test], ipAddress=1.1.1.1]]
        System.out.println(ConnectionsPane.getClientData());
     // Add observable list data to the table
        clientDataTable.setItems(ConnectionsPane.getClientData());
        clientDataTable.refresh();
       
    }
 
}

ConnectionsPane.java

package io.ironbytes.corkscrew.models;

import java.io.IOException;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.AnchorPane;

public class ConnectionsPane extends AnchorPane{
 
    /**
     * The data as an observable list of Persons.
     */
    public ObservableList<Client> clientData = FXCollections.observableArrayList();
    

    public ConnectionsPane(){
     
        //Add a test client to the ObservableList
        clientData.add(new Client(1));
        
        System.out.println(getClientData());
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("../views/ConnectionsPane.fxml"));
        
        //Give the controller access to the main app.
        //ConnectionsPaneController controller = fxmlLoader.getController();
        //controller.setMainApp(this);
        
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);

        try {
            fxmlLoader.load();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public ObservableList<Client> getClientData() {
        return clientData;
    
    }

}

ConnectionsPane.fxml

package io.ironbytes.corkscrew.models;

import java.io.IOException;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.AnchorPane;

public class ConnectionsPane extends AnchorPane{
 
    /**
     * The data as an observable list of Persons.
     */
    public ObservableList<Client> clientData = FXCollections.observableArrayList();
    

    public ConnectionsPane(){
     
        //Add a test client to the ObservableList
        clientData.add(new Client(1));
        
        System.out.println(getClientData());
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("../views/ConnectionsPane.fxml"));
        
        //Give the controller access to the main app.
        //ConnectionsPaneController controller = fxmlLoader.getController();
        //controller.setMainApp(this);
        
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);

        try {
            fxmlLoader.load();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public ObservableList<Client> getClientData() {
        return clientData;
    
    }

}

Client.java

package io.ironbytes.corkscrew.models;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Client {
 
 private int clientID;
 private boolean isOnline;
 private StringProperty username;
 private String ipAddress;
 
 public Client() {

 }
 
 public Client(int ClientID) {
  this.clientID=ClientID;
  this.isOnline=true;
  this.ipAddress="1.1.1.1";
  this.username = new SimpleStringProperty("test");
 }

 @Override
 public String toString() {
  return "Client [clientID=" + clientID + ", isOnline=" + isOnline + ", username=" + username + ", ipAddress="
    + ipAddress + "]";
 }

 public int getClientID() {
  return clientID;
 }
 
 public void setClientID(int clientID) {
  this.clientID = clientID;
 }

 public boolean isOnline() {
  return isOnline;
 }

 public void setOnline(boolean isOnline) {
  this.isOnline = isOnline;
 }

 public StringProperty getUsername() {
  return username;
 }

 public void setUsername(StringProperty username) {
  this.username = username;
 }

 public String getIpAddress() {
  return ipAddress;
 }

 public void setIpAddress(String ipAddress) {
  this.ipAddress = ipAddress;
 }


}
d3t0x
  • 432
  • 4
  • 15
  • 1
    As an aside, don't use a `javax.swing.JOptionPane`, JavaFX has a native [TextInputDialog](https://docs.oracle.com/javase/9/docs/api/javafx/scene/control/TextInputDialog.html), which will provide you the functionality of `JOptionPane.showInputDialog("Please enter listening port");`. For usage, see [the Makery JavaFX Dialogs tutorial](http://code.makery.ch/blog/javafx-dialogs-official/). – jewelsea Oct 30 '17 at 20:19
  • Good point. I will update that, thanks. – d3t0x Oct 30 '17 at 20:22
  • There are many issues with this code, and it probably makes this question too broad. I recommend you read up a little on the relationship between FXML and the controller class. Maybe see [this question](https://stackoverflow.com/questions/33881046). Here are some of the issues to address: 1. an fxml file can only have one controller. You seem to be trying to make both `ConnectionsPaneController` and `ConnectionsPane` the controller class (one via `fx:controller="..."`, one via `setController()`). 2. [`@FXML`-injected fields cannot be static](https://stackoverflow.com/questions/23105433) – James_D Oct 30 '17 at 21:50
  • 3. Don't put code in the `main()` method. Use the `start()` method as the entry point to the application. 4. Don't create new instances of controller classes via a constructor call (unless you are passing that instance to `FXMLLoader.setController()`). 5. If you are using `fx:controller="..."` in your FXML file, the specified class must have a no-argument constructor. 6. Don't use `..` in resource names; it won't work when you deploy to a jar file. – James_D Oct 30 '17 at 21:54
  • 7. If you use JavaFX properties in your model classes, use the [correct method names](https://docs.oracle.com/javase/8/javafx/properties-binding-tutorial/binding.htm#JFXBD107) so that the JavaFX machinery will interact with your classes in the correct way. – James_D Oct 30 '17 at 21:57
  • So I recommend you start with something much easier; maybe just a simple table. Get that to work and learn the basic relationship between the FXML file and the controller class, before you start on something as complex as a multithreaded, networked application. – James_D Oct 30 '17 at 21:58
  • The same tutorial jewelsea linked above has a very nice [`TableView` tutorial](http://code.makery.ch/library/javafx-8-tutorial/part2/) which may be helpful. – James_D Oct 30 '17 at 22:09
  • I edited my code, and updated my thread. Still cant get this to populate. Can anyone help me out some more? Cheers! – d3t0x Oct 31 '17 at 00:44
  • I simplified my code and tried to get it working. I explain in more detail in my edit. Can anyone help? – d3t0x Oct 31 '17 at 16:58

0 Answers0