logo Getting Started


How to write a persistent table
by the 99 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. The application stores data in XML file, but a modification few lines can switch to the CSV format. We create three classes without a table model class implementation: All three classes contain 99 rows of source code (comments, blank rows and imports are not counted). See the screenshot of the result: Click on the image to run the sample 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) may not be casted to a Double type:
package org;
import org.ujoframework.*;
/** Person BO */ public class Person extends org.ujoframework.implementation.map.MapUjoExt<Person> {
public static final UjoProperty<Person,Integer> ID = newProperty("ID", Integer.class); public static final UjoProperty<Person,String> FIRSTNAME = newProperty("FirstName", String.class); public static final UjoProperty<Person,String> SURNAME = newProperty("Surname", String.class); public static final UjoProperty<Person,Integer> AGE = newProperty("Age" , Integer.class); public static final UjoProperty<Person,Boolean> MALE = newProperty("Male", Boolean.class); public static final UjoProperty<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.*;
import org.ujoframework.extensions.*;
/** Company BO */ public class Company extends org.ujoframework.implementation.map.MapUjoExt<Company> {
public static final UjoProperty<Company,String> NAME = newProperty ("Name" , String.class); public static final ListProperty<Company,Person> PERSONS = newPropertyList("Person", Person.class);
public Company() { set(NAME, "My Company"); // assign a default company name } }

Application window

The application window is an extension of JFrame from the Swing library. A 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 the UjoTableModel class, all visible table colums are ordered by its constructor. Company object is retrieved by a UjoManagerXML class. See the next 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() {
    setTitle("Persons of Company");
    table = new JTable();  
    JPanel panel = new JPanel(new java.awt.GridLayout(6, 1, 0, 1));
    getContentPane().add(new JScrollPane(table), java.awt.BorderLayout.CENTER);
    getContentPane().add(panel, java.awt.BorderLayout.EAST);
    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setBounds(100,200,550,165);

    String[] labels = {"New", "Delete", "Copy", "Add $10", "3 columns", "6 columns"};
    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-2009

Valid XHTML 1.0 Strict