Jestino Sam Jestino Sam - 2 months ago 48
Java Question

JavaFX - Populate FXML TableView with data from XML

I am trying to populate TableView in JavaFX with the data from XML. Basically, I am parsing the data from XML & trying to set the tableview with the data from XML.
However, I am facing issues in the code that I have come up with. Below is the format of my XML file.

XML File

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Root>
<xpression>
<Environment>
<ProjectName>ABC</ProjectName>
<EnvironmentName>ABC Server</EnvironmentName>
<ServerURL>abcc.com:8080</ServerURL>
<SetDefault>Yes</SetDefault>
</Environment>
<Environment>
<ProjectName>XYZ</ProjectName>
<EnvironmentName>XYZ Server</EnvironmentName>
<ServerURL>xyz.com:8080</ServerURL>
<SetDefault>No</SetDefault>
</Environment>
</xpression>
</Root>


Below is my XML Parsing Code:

XML Parser

public void parseXml() throws ParserConfigurationException, SAXException, IOException{
DocumentBuilderFactory db = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = db.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
doc.getDocumentElement().normalize();
ObservableList<DataSource> data = FXCollections.observableArrayList();
NodeList nList = doc.getElementsByTagName("Environment");
DataSource ds = new DataSource();

int j = 1;
for(int i = 0; i < nList.getLength(); i++){
Node nNode = nList.item(i);
System.out.println("\nCurrent Element :"
+ nNode.getNodeName());

if (nNode.getNodeType() == Node.ELEMENT_NODE){
Element element = (Element) nNode;
ds.setProjectName(element
.getElementsByTagName("ProjectName")
.item(0)
.getTextContent());
System.out.println(element
.getElementsByTagName("ProjectName")
.item(0)
.getTextContent());

ds.setEnvironment(element
.getElementsByTagName("EnvironmentName")
.item(0)
.getTextContent());
System.out.println(element
.getElementsByTagName("EnvironmentName")
.item(0)
.getTextContent());

ds.setServerURL(element
.getElementsByTagName("ServerURL")
.item(0)
.getTextContent());
System.out.println(element
.getElementsByTagName("ServerURL")
.item(0)
.getTextContent());

ds.setDefaultValue(element
.getElementsByTagName("SetDefault")
.item(0)
.getTextContent());
System.out.println(element
.getElementsByTagName("SetDefault")
.item(0)
.getTextContent());

ds.setSerialNo(j);
++j;
}
//list.add(ds);
data.add(ds);
}
//data = FXCollections.observableArrayList(list);
tblDetails.setItems(data);
}


DataSource(POJO) File:

public class DataSource {
public SimpleIntegerProperty serialNo = new SimpleIntegerProperty();
public SimpleStringProperty projectName = new SimpleStringProperty("");
public SimpleStringProperty environment = new SimpleStringProperty("");
public SimpleStringProperty serverURL = new SimpleStringProperty("");
public SimpleStringProperty defaultValue = new SimpleStringProperty("");

public DataSource(){
this(1,"","","","");
}

public DataSource(int serial, String projectName,String envName, String serverURL, String defaultValue){
setSerialNo(serial);
setEnvironment(envName);
setProjectName(projectName);
setServerURL(serverURL);
setDefaultValue(defaultValue);
}

public Integer getSerialNo(){
return serialNo.get();
}

public void setSerialNo(Integer serialNum){
serialNo.set(serialNum);
}

public String getProjectName(){
return projectName.get();
}

public void setProjectName(String prjName){
projectName.set(prjName);
}

public String getEnvironment(){
return environment.get();
}

public void setEnvironment(String envName){
environment.set(envName);
}

public String getServerURL(){
return serverURL.get();
}

public void setServerURL(String serverUrl){
serverURL.set(serverUrl);
}

public String getDefaultValue(){
return defaultValue.get();
}

public void setDefaultValue(String defaultInd){
defaultValue.set(defaultInd);
}
}


Basically what is happening is , when I am trying to set the table data in my parseXML(), it is setting the values of 2nd instance of Environment tag from the XML file in the TableView, skipping the first instance. See the below screenshot:
enter image description here

I tried various things, but nothing worked. Can someone point out the mistake or probably give solution for populating the JavaFX TableView with XML values??

Answer

You need to create a new instance of DataSource in your for loop otherwise you will always add the same reference to your ObservableList.

Do this:

for(int i = 0; i < nList.getLength(); i++){
    DataSource ds = new DataSource();

Instead of:

DataSource ds = new DataSource();
...
for(int i = 0; i < nList.getLength(); i++){
Comments