Friday 24 August 2012

Read XML Files


Hi
In this post, I will show you how to create a simple Java project using Eclipse RCP.
This simple project will allow you to load an xml file and fill its contents in a table.
It will also show you how to structure the project packages skeleton, how to create model classes, service layer, utility classes, GUI components and other parts which we might need.

1 - First step will be creating the project. The name is important because using a descriptive name will help you (after some time) and others to know what the purpose of the project is.
Because we are going to load an xml file, which is the main purpose of the project, we are going to call it:
(XML Reader Application).

Go ahead and from the main menu of Eclipse, select File\New\Java Project:


A new window will appear where you can type in the project name:



Click finish, and the new project will be created in the area of eclipse, which is called       Package Explorer:


The package explorer tab contains:
1-     Something called (src) package, which is created by default, and will contain all other packages we will need.
2-     The JRE System Library contains all default java libraries; which will be needed by our application to create the GUI (Graphical User Interface) and other need libraries, which we don’t care about right now.

2- Second step will be finding out what packages we need to create the skeleton of our application.
          Now, let us see what we have:
1-     We need a GUI, which contains a button for loading the XML file, a table which; will show data and some label to describe what these components mean for the user. These components can be put in a package called ui, gui, or gui_components, whatever name you choose is correct as long it describes what is going to be in this package.
2-     We need a class which; will open and read the XML file. Classes like so, are most of the time called utility classes, because they perform a common task. Therefore, we will create a util or a utility package.
3-     We will also need an object(s) to store data from the XML file into, and then send this data to the table. These types of objects are called DTO (Data Transfer Object), VO (Value Object) or Models, so we are going to create a package called models to store these classes in.
4-      There is always a service layer which will play as an interface between different packages or layers, we don’t want to mix everything up. If the GUI classes, needs something to show a file content, or get data from the data base, let it use the service layer, but not directly to “talk” to the utility classes, or use any other packages. Let the separation concept rule for now.

After applying what we said in the above three points, we will have this:


3- Third step is to start with the GUI, select the gui package and go to the icon that has a plus and a down arrow next to it and select Swing\JFrame:



A new window will popup where you can put the name of the new JFrame class, we are going to call it MainFrame (Remember that no spaces are allowed in the class name):


After you click finish, the new class will be created, and Eclipse will open it in the class editor:


Note: this is only part of the class, but we will explain other parts later.
Let’s click on the design tab and take a look at the GUI we have:


In this image, we see:
1.      Structure – Components (on your left), this is a tree, which shows all the components we have:
a.       A JFrame which; is the main window that will appear when you run the application.
b.      The contentPane, which; is a layer where we can add all our GUI components.
2.      Structure – Properties (on you down-left), this window, contains properties of each component in the Structure-Components window, when you click contentPane you will see its properties in this window, like background color, font and other things.
3.      Palette (in the middle), this window simply contains any GUI element you need; you can click it and point the mouse to the main frame on the right and add the component you just selected. Building the GUI will be drag and drop.
4.      The main frame, this is your application GUI part, it will appear as you construct it here.

Let’s build our main frame window:

First of all we are going choose a layout for our frame, the layout helps as to order our components as we like. For now we are going to use an absolute layout, which means that we can put our components anywhere we want and resize them anyway we like, so in the structure-components part, click the contentPane component and go to structrue-properteis, select layout and from the dropdown menu choose Absolute Layout.


Now, let’s add a button, click on the button component from the palette, drag it anywhere you like on the frame, but for me, we are going to put it at the top-left:


Now, while the button is selected (if not, just select it with the left mouse button), go to properties, click btnNewButton (next to Variable) and change the name to : (loadXMLBtn).
Go to text and change New button to (Load XML):


Now, lets leave the GUI for a while, and talk about other parts.

4- Forth Step creating the models and the xml reader classes:
            Before creating the table, we are going to create the xml reader, the models we need, and load data to these models, and then we will create the table and show data in it.

Lets say we are going to read data about students from an xml file (Students.xml) , the xml file will be like this:

<?xml version="1.0" encoding="UTF-8"?>
<students>
                <student name="John">
                                <facnum>3432</facnum>
                                <age>22</age>
                </student>
                <student name="Mark">
                                <facnum>3355</facnum>
                                <age>24</age>
                </student>
</students>

First lets create the models:
A model is an object from real life, transformed into a java class. The real world object here is the xml file, we must create object classes, exactly as we see them in the xml file.
So we have a students root element and sub-elements student with their sub-elements facnum and age and an attribute name.
So we need a class called Students with a field List<Student>, and a class called student with fields name, age and facnum:

Here is the Students class:

package models;

import java.util.List;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="students")
public class Students {

      private List<Student> studentsList;

      public Students() {

      }

      public List<Student> getStudentsList() {
            return studentsList;
      }

      @XmlElement(name = "student")
      public void setStudentsList(List<Student> studentsList) {
            this.studentsList = studentsList;
      }

}
 As you can see form this class, the root element must be announced at the top of the class, with the same name as the root element in the xml file, and because the root element has sub-elements student, it must has a list of students.

And here is the Student class:

package models;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;

public class Student {

      private String name;
      private int facnum;
      private int age;

      public Student() {

      }

      public String getName() {
            return name;
      }

      @XmlAttribute(name = "name")
      public void setName(String name) {
            this.name = name;
      }

      public int getFacnum() {
            return facnum;
      }

      @XmlElement(name = "facnum")
      public void setFacnum(int facnum) {
            this.facnum = facnum;
      }

      public int getAge() {
            return age;
      }

      @XmlElement(name = "age")
      public void setAge(int age) {
            this.age = age;
      }

}


As you can see, the class fields are the same attributes or elements of the xml file, the new thing about this is that before each setter we have a new statement; which will tell the class that this is an attribute or an element from the xml file.
Click on the models package, and select the class creator icon and add a class called Students, copy all the content of the class Students above and paste it there (do the same for class Student):



And you package explorer will look like this:



We are going to use a java built in technology called, JAXB. Click on the util package, and create a new class called XMLReader, the code for this class will be like this:


package util;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import models.Students;

public class XMLReader {

public static Students getStudents() {

Students students = null;
try {

File file = new File("Your file path");

JAXBContext jaxbContext = JAXBContext.newInstance(Students.class);

Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

students = (Students) jaxbUnmarshaller.unmarshal(file);

} catch (JAXBException e) {
e.printStackTrace();
}

return students;
}

}


As you can see from this class, it has a method which returns the Students object, which we will use later to fill the table.

5-      Step Five:  Creating the service layer class.
Create a class called XMLService, in the service package:
package service;

import util.XMLReader;
import models.Students;

public class XMLService {

      public Students getStudents() {

            return XMLReader.getStudents();

      }
}

Let’s get back to the GUI layer:

The table we are going to create is called JTable, here is the code:

final JTable studentsTable = new JTable(new Object[0][],getTableColumns());
JScrollPane tablePane = new JScrollPane(studentsTable);
tablePane.setBounds(10, 40, 400, 160);
contentPane.add(tablePane);

The constructor of the table (JTable(new Object[0][],getTableColumns());)
Has two arguments, a 2D array of objects (the data which will fill the table) and for now we will create an empty one because we have no data.
And the second one is an array of strings, which contains the names of the columns.
Here is the data method:

              private Object[][] getTableData() {

XMLService xmlService = new XMLService();

Students students = xmlService.getStudents();

Object[][] data = new Object[students.getStudentsList().size()][];

for (int i = 0; i < data.length; i++) {

Student student = students.getStudentsList().get(i);

data[i] = new Object[] { student.getName(), student.getFacnum(),
student.getAge() };
}

return data;
}

And here is the column names method:
private String[] getTableColumns() {
            return new String[] { "Name", "Facultiy No.", "Age" };
     }

After the user clicks the load xml button, we will load the data this way:
loadXMLBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
DefaultTableModel model = new DefaultTableModel(getTableData(),            getTableColumns());
              studentsTable.setModel(model);

                     }
             });

When you run the application and click the load xml button the result will be:

Here is the project archive and the xml file:
https://sourceforge.net/projects/xmlreaderapplic/files/?



1 comment:

Patrick Forhan said...

Thanks, I hadn't read XML via JAXB for a long time, this was a great refresher.