Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Integrate JavaFX, Hibernate and PostgreSQL with the MVC Pattern-2 : Page 2


JavaFX / Hibernate / PostgreSQL Project Structure

Our project will follow the MVC pattern and the structure will look like Figure 2.

JavaFX Hibernate PostgreSQL
Figure 2. Project Structure: Here is the structure of the JavaFX / Hibernate / PostgreSQL project.

Hibernate Configuration

The class HibernateUtil.java contains all the configuration requirements for our project to interact with the database. The Hibernate configuration can also be established through XML, but in this case I used annotation-based configuration.

package org.contact.entity; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.SessionFactoryObserver; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistryBuilder; public class HibernateUtil {      private static final SessionFactory sessionFactory;      private static final ServiceRegistry serviceRegistry;      static {           try {                Configuration config = getConfiguration();                serviceRegistry = new ServiceRegistryBuilder().applySettings(                          config.getProperties()).buildServiceRegistry();                config.setSessionFactoryObserver(new SessionFactoryObserver() {                     private static final long serialVersionUID = 1L;                     @Override                     public void sessionFactoryCreated(SessionFactory factory) {                     }                     @Override                     public void sessionFactoryClosed(SessionFactory factory) {                          ServiceRegistryBuilder.destroy(serviceRegistry);                     }                });                sessionFactory = config.buildSessionFactory(serviceRegistry);           } catch (Throwable ex) {                System.err.println("Initial SessionFactory creation failed." + ex);                throw new ExceptionInInitializerError(ex);           }      }      public static Session openSession() {           return sessionFactory.openSession();      }      private static Configuration getConfiguration() {           Configuration cfg = new Configuration();           cfg.addAnnotatedClass(Contact.class );           cfg.setProperty("hibernate.connection.driver_class",     "org.postgresql.Driver");           cfg.setProperty("hibernate.connection.url","jdbc:postgresql://");           cfg.setProperty("hibernate.connection.username", "postgres");           cfg.setProperty("hibernate.connection.password", "postgres");           cfg.setProperty("hibernate.show_sql", "true");           cfg.setProperty("hibernate.dialect","org.hibernate.dialect.PostgreSQLDialect");           cfg.setProperty("hibernate.hbm2ddl.auto", "update");           cfg.setProperty("hibernate.cache.provider_class","org.hibernate.cache.NoCacheProvider");           cfg.setProperty("hibernate.current_session_context_class", "thread");           return cfg;      } }

Model Layer: Entity Class

The model layer implements the domain logic of the application with strong separation from the way that the user requests and sees results. Contact.java is our annotation-based entity class for creating the Contacts database table.

@Entity @Table(name="CONTACTS") public class Contact {      @Id      @GeneratedValue      @Column(name="CONTACTID")      private Integer contactId;      @Column(name="FIRSTNAME")      private String firstName;      @Column(name="LASTNAME")      private String lastName;      @Column(name="EMAIL")      private String email;      @Column(name="PHONE")      private String phone;            public Contact() {           super();                }            public Contact(Integer contactId, String firstName, String lastName, String email, String phone) {           super();           this.contactId = contactId;           this.firstName = firstName;           this.lastName = lastName;           this.email = email;           this.phone = phone;      }            public Integer getContactId() {           return contactId;      }      public void setContactId(Integer contactId) {           this.contactId = contactId;      }      public String getFirstName() {           return firstName;      }      public void setFirstName(String firstName) {           this.firstName = firstName;      }      public String getLastName() {           return lastName;      }      public void setLastName(String lastName) {           this.lastName = lastName;      }      public String getEmail() {           return email;      }      public void setEmail(String email) {           this.email = email;      }      public String getPhone() {           return phone;      }      public void setPhone(String phone) {           this.phone = phone;      }      }

Model Layer: Data Access Objects

ContactDAO.java is an abstract interface of our persistence mechanism. It supports operation without exposing any details of the database. This interface provides a mapping from application calls to the persistence layer.

package org.contact.dao; import java.util.List; import org.contact.entity.Contact; public interface ContactDAO { public void addContact(Contact contact); public List<Contact> listContact(); public void removeContact(Integer id); public void updateContact(Contact contact); }

A concrete implementation of this interface is provided by the ContactDAOImpl.java class. This approach isolates domain-specific objects and data types, abstracting the application needs and how they are satisfied.

package org.contact.dao; import java.util.ArrayList; import java.util.List; import org.contact.entity.Contact; import org.contact.entity.HibernateUtil; import org.hibernate.Session; public class ContactDAOImpl implements ContactDAO{      @Override      public void addContact(Contact contact) {           Session s=HibernateUtil.openSession();           s.beginTransaction();           s.save(contact);           s.getTransaction().commit();           s.close();      }      @Override      public List<Contact> listContact() {           List<Contact> list=new ArrayList<>();           Session s=HibernateUtil.openSession();           s.beginTransaction();           list=s.createQuery("from Contact").list();           s.getTransaction().commit();           s.close();           return list;      }      @Override      public void removeContact(Integer id) {           Session s=HibernateUtil.openSession();           s.beginTransaction();           Contact c=(Contact)s.load(Contact.class , id);           s.delete(c);           s.getTransaction().commit();           s.close();                }      @Override      public void updateContact(Contact contact) {                     Session s=HibernateUtil.openSession();           s.beginTransaction();           s.update(contact);           s.getTransaction().commit();           s.close();                } }

Model Layer: Services

The ContactService.java interface provides cohesive, high-level logic for related parts of the application. This layer is invoked directly by the Controller and View layers.

package org.contact.service; import java.util.List; import org.contact.entity.Contact; public interface ContactService {      public void addContact(Contact contact); public List<Contact> listContact(); public void removeContact(Integer id); public void updateContact(Contact contact); }

ContactServiceImpl.java is the concrete implementation of the ContactService.java interface. It provides a public interface of underlying model objects.

package org.contact.service; import java.util.List; import org.contact.dao.ContactDAO; import org.contact.dao.ContactDAOImpl; import org.contact.entity.Contact; public class ContactServiceImpl implements ContactService{            private ContactDAO contactDAO=new ContactDAOImpl();            @Override      public void addContact(Contact contact) {           contactDAO.addContact(contact);                }      @Override      public List<Contact> listContact() {           return contactDAO.listContact();                }      @Override      public void removeContact(Integer id) {           contactDAO.removeContact(id);                }      @Override      public void updateContact(Contact contact) {           contactDAO.updateContact(contact);                }       }

Controller Layer: Controller

The Controller translates requests coming from the View layer into outgoing responses. In order to do this, ContactController.java takes request data and passes it to the service layer. The service layer then returns data that the Controller injects into a View for rendering. This view may be HTML for a standard Web request or JSON (JavaScript Object Notation) for a RESTful API request. In our case, it is a JavaFX UI.

package org.contact.app; import java.util.List; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import org.contact.entity.Contact; import org.contact.service.ContactService; import org.contact.service.ContactServiceImpl; public class ContactController {      private ContactService contactService=new ContactServiceImpl();      private ObservableList<Contact> contactList=FXCollections.observableArrayList();            public void addContact(Contact contact){           contactService.addContact(contact);      }            public ObservableList<Contact> getContactList(){           if(!contactList.isEmpty())                contactList.clear();                               contactList = FXCollections.observableList((List<Contact>) contactService.listContact());           return contactList;      }            public void removeContact(Integer id)     {           contactService.removeContact(id);      }            public void updateContact(Contact contact){           contactService.updateContact(contact);      }      }

View Layer of MVC

Our front-end object is implemented in JavaFX. Main.java acts as a View layer for our application. The View layer translates data for visual rendering in response to the client. The data is supplied primarily by the Controller, ContactController.java in this case.

Main.java package org.contact.app; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.TextField; import javafx.scene.control.Tooltip; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.layout.BorderPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Pane; import javafx.stage.Stage; import org.contact.entity.Contact; public class Main extends Application {      String bgcolor = "-fx-background-color: #f0f0f0";      String style = "-fx-font-weight:normal; -fx-color: #f0f0f0; -fx-font-size:11; -fx-font-family: Verdana;";      private TableView<Contact> table = new TableView<>();      private String buttonCaption[] = { "Add New", "Update", "Delete", "|<",                "<<", ">>", ">|" };      private String label[] = { "Contact ID", "First Name", "Lat Name", "Email",                "Phone" };      private String fields[] = { "contactId", "firstName", "lastName", "email",                "phone" };      private Button button[] = new Button[7];      private TextField textField[] = new TextField[5];      private ContactController controller = new ContactController();      private static int index;      public static void main(String[] args) throws Exception {           Application.launch(args);      }      @Override      public void start(Stage stage) throws Exception {           stage.setTitle("Contact Manager");           BorderPane border = new BorderPane();           border.setTop(createButtonBox());           border.setCenter(createForm());           border.setBottom(table);           border.setStyle(bgcolor);           border.setPadding(new Insets(10, 10, 10, 10));           populateForm(0);           populateTable();           stage.setScene(new Scene(border, 800, 650));           stage.show();      }      private Pane createForm() {           GridPane grid = new GridPane();           grid.setAlignment(Pos. CENTER);           grid.setPadding(new Insets(10, 10, 10, 10));           grid.setHgap(20);           grid.setStyle(style);           grid.setVgap(2);           for (int i = 0; i < label.length; i++) {                grid.add(new Label(label[i] + " :"), 1, i);                textField[i] = new TextField();                grid.add(textField[i], 2, i);           }           textField[0].setEditable(false);           textField[0].setTooltip(new Tooltip(                     "This field is automatically generated hence not editable"));           return grid;      }      private Pane createButtonBox() {           int width = 100;           HBox box = new HBox();           box.setAlignment(Pos. CENTER);           box.setSpacing(5);           for (int i = 0; i < buttonCaption.length; i++) {                button[i] = new Button(buttonCaption[i]);                button[i].setStyle(style);                button[i].setMinWidth(width);                button[i].setOnAction(new ButtonHandler());                box.getChildren().add(button[i]);           }           return box;      }      private class ButtonHandler implements EventHandler<ActionEvent> {           @Override           public void handle(ActionEvent event) {                if (event.getSource().equals(button[0])) {                     Contact c = new Contact(111, textField[1].getText(),                               textField[2].getText(), textField[3].getText(),                               textField[4].getText());                     controller.addContact(c);                } else if (event.getSource().equals(button[1])) {                     Contact c = new Contact(                               Integer.parseInt(textField[0].getText()),                               textField[1].getText(), textField[2].getText(),                               textField[3].getText(), textField[4].getText());                     controller.updateContact(c);                     System.out.println("update button clicked");                } else if (event.getSource().equals(button[2])) {                     Contact c = (Contact) controller.getContactList().get(index);                     controller.removeContact(c.getContactId());                } else if (event.getSource().equals(button[4])) {                     if (index > 0) {                          index--;                     } else                          event.consume();                } else if (event.getSource().equals(button[3])) {                     index = 0;                } else if (event.getSource().equals(button[5])) {                     if (index < controller.getContactList().size() - 1) {                          index++;                     } else                          event.consume();                } else if (event.getSource().equals(button[6])) {                     index = controller.getContactList().size() - 1;                }                populateForm(index);                populateTable();           }      }      private void populateForm(int i) {           if (controller.getContactList().isEmpty())                return;           Contact c = (Contact) controller.getContactList().get(i);           textField[0].setText(c.getContactId().toString());           textField[1].setText(c.getFirstName());           textField[2].setText(c.getLastName());           textField[3].setText(c.getEmail());           textField[4].setText(c.getPhone());      }      private void populateTable() {           table.getItems().clear();           table.setStyle(style);                table.setItems(controller.getContactList());           TableColumn<Contact, Integer> contactIdCol = new TableColumn<Contact, Integer>(     "Contact ID");           contactIdCol.setCellValueFactory(new PropertyValueFactory<Contact, Integer>("contactId"));           TableColumn<Contact, String> firstNameCol = new TableColumn<Contact, String>("First Name");           firstNameCol.setCellValueFactory(new PropertyValueFactory<Contact, String>("firstName"));           TableColumn<Contact, String> lastNameCol = new TableColumn<Contact, String>("Last Name");           lastNameCol.setCellValueFactory(new PropertyValueFactory<Contact, String>("lastName"));           TableColumn<Contact, String> emailCol = new TableColumn<Contact, String>("Email");           emailCol.setCellValueFactory(new PropertyValueFactory<Contact, String>("email"));           TableColumn<Contact, String> phoneCol = new TableColumn<Contact, String>("Phone");           phoneCol.setCellValueFactory(new PropertyValueFactory<Contact, String>("phone"));           table.getColumns().setAll(contactIdCol, firstNameCol, lastNameCol,emailCol, phoneCol);      } }

Compile and Run the Application

We are now ready to compile and run our JavaFX / Hibernate / PostgreSQL app. To do so, just follow these two steps in Eclipse:

  1. Right click on Main.java from Project Explorer
  2. Select Run As and choose Java Application

The application will then compile and run. Figure 3 shows the application's output.

JavaFX Hibernate PostgreSQL
Figure 3. Application Output: Here is the output after running our application.

Manoj Debnath is a Java programmer with more than seven years of software development experience.
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.