logo Getting Started


How to write a persistent table
by 110 rows of source code on the desktop?

Motivation:

The document learns to you, how to create a simple Swing application with a persistent table by the UJO Framework and Java 5.0 SE. We will create three classes without any table model class implementation: All classes contain approximately 110 rows of source code (comments and blank rows was not counted). See the target screenshot: screen2.png Click on the image to run the sample by Java Web Start

Business objects

The first business class is called Person. Every one static property constant represents a one attribute so that a type safe property access is performed by the related constant. A property CASH have got a default value set to zero. The class have got one method to demonstration a work with UJO properties. Note that result of the method get(CASH) can't be casted to a Double type:
package org;
import org.ujoframework.implementation.map.*;
/** Person BO */ public class Person extends MapUjoExt<Person> {
public static final MapProperty<Person,Integer> ID = newProperty("ID", Integer.class); public static final MapProperty<Person,String> FIRSTNAME = newProperty("FirstName", String.class); public static final MapProperty<Person,String> SURNAME = newProperty("Surname", String.class); public static final MapProperty<Person,Integer> AGE = newProperty("Age" , Integer.class); public static final MapProperty<Person,Boolean> MALE = newProperty("Male", Boolean.class); public static final MapProperty<Person,Double> CASH = newProperty("Cash", 0d);
public void addCash(double cash) { double newCash = get(CASH) + cash; set(CASH, newCash); } }
The second business class is called Company, it is a root container of all persistent objects in this sample. The Company object contains two properties only. Note how a company name is assigned to a NAME property.
You can verify that a Java compilator disclose a data type different from the String in the set method.
package org;
import org.ujoframework.implementation.map.*;
/** Company BO */ public class Company extends MapUjoExt<Company> {
public static final MapProperty<Company,String> NAME = newProperty ("Name" , String.class); public static final MapPropertyList<Company,Person> PERSONS = newPropertyList("Person", Person.class);
public Company() { set(NAME, "My Company"); // assign a default company name } }

Window implementation

A main window is an extension of JFrame from a Swing library. The Source code is very simple to learn, however some areas are not written by a code guideline.

Take note, how an instance of table model is created by a UjoTableModel class, all visible table columss are ordered by its constructor. Company object is retrieved by a UjoManagerXML class.
See a source code for details.

package org;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
import java.io.File;
import org.ujoframework.core.UjoManagerXML;
import org.ujoframework.swing.UjoTableModel;
import static org.Company.*;
import static org.Person.*;

/** Simple Table Frame. */
public class TableFrame extends JFrame implements ActionListener, Runnable  {
    
  private File dataFile = new File(System.getProperty("user.home"),"ujo-company.xml");
  private Company company;
  private UjoTableModel<Person> model;
  private JTable table;
  
  /** Creates a new instance of TableFrame */
  public TableFrame() {
    initComponents();
    
    // Create a TableModel with Columns:
    model = new UjoTableModel<Person>(ID, FIRSTNAME, SURNAME, AGE, CASH, MALE);
    // ... or use simply:
    // model = new UjoTableModel<Person>(Person.class);
    table.setModel(model);
    
    // Assing Data into TableModel:
    company = loadCompany();
    List<Person> persons = company.list(PERSONS); // returns a not null list always
    model.setRows(persons);
    
    // Register a Close Listener:    
    Runtime.getRuntime().addShutdownHook(new Thread(this));    
  }
  
  public void run() {
    saveCompany();     
  }
  
  /** Load company from file. */
  private Company loadCompany() {
    if (dataFile.isFile()) try {
      return UjoManagerXML.getInstance().parseXML(dataFile, Company.class, "Load company");
    } catch (Throwable e) {
      e.printStackTrace();
    }
    return new Company();
  }
  
  /** Save company to file. */
  private void saveCompany() {
    try {
      String defaultXmlHeader = null;
      UjoManagerXML.getInstance().saveXML(dataFile, company, defaultXmlHeader, "Save company");
    } catch (Throwable e) {
      e.printStackTrace();
    }
  }
  
  /** Button Actions */
  public void actionPerformed(ActionEvent e) {
    String label = ((JButton)e.getSource()).getText();
    int index = table.getSelectedRow();
    
    if ("New".equals(label)) {
      model.addRow(new Person());  
      // Very primitive ID generator:    
      model.getRowLast().set(ID, model.getRowCount());
    }
    if ("Delete".equals(label) && index>=0) {
      model.deleteRow(index);
    }
    if ("Copy".equals(label) && index>=0) {
      int depth = 2;
      model.cloneRow(index, depth, this);
    }
    if ("Add $10".equals(label) && index>=0) {
      model.getRow(index).addCash(10d);
      model.fireTableColumnUpdated(Person.CASH);
    }
    if ("3 columns".equals(label)) {
      model.setColumns(ID, SURNAME, CASH);
    }
    if ("6 columns".equals(label)) {
      model.setColumns(ID, FIRSTNAME, SURNAME, AGE, CASH, MALE);
    }
  }
  
  /** Init GUI Components */
  private void initComponents() {
    table = new JTable();  
    getContentPane().add(new JScrollPane(table), java.awt.BorderLayout.CENTER);
    JPanel panel = new JPanel(new java.awt.GridLayout(6, 1, 0, 1));
    getContentPane().add(panel, java.awt.BorderLayout.EAST);
    addButtons(panel, "New", "Delete", "Copy", "Add $10", "3 columns", "6 columns");
    
    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setTitle("Persons of Company");
    setBounds(100,200,550,165);
  }
  
  private void addButtons(JPanel panel, String... labels) {
    for(String label: labels) {
      JButton button = new JButton(label);
      button.addActionListener(this);
      panel.add(button);
    }
  }

  public static void main(String args[]) {
    new TableFrame().setVisible(true);
  }   
}

XML file:

The content of the XML file is here:
<?xml version="1.0" encoding="UTF-8"?>
<body>
  <Name>My Company</Name>  
  <Person>
    <ID>1</ID>
    <FirstName>John</FirstName>
    <Surname>Brown</Surname>
    <Age>22</Age>
    <Cash>175.0</Cash>
    <Male>true</Male>
  </Person>    
  <Person>
    <ID>2</ID>
    <FirstName>Susan</FirstName>
    <Surname>Smith</Surname>
    <Age>50</Age>
    <Cash>180.0</Cash>
    <Male>false</Male>
  </Person>
  . . . 
</body>

Download

Cut and paste the sample code from HTML page to 3 files in a org folder via system clipboard.
See a UJO Framework description for more informations.

About Author:


PPone(c) 2007-2008

Valid XHTML 1.0 Strict