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:- business class Person
- business class Company
- window component extends a JFrame class.
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.*;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.
/** 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); } }
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:
- You can write questions or other messages to me by a blog http://ujoframework.blogspot.com/.
- There exists some more free applications on an authors home page http://ponec.net/ .
- A contact e-mail: ujoframework@gmail.com
PPone(c) 2007-2008
Getting Started