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 Ujorm 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:- 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 keys. Note that result of the method get(CASH) may not be casted to a Double type:package org; import org.ujorm.*;The second business class is called Company, it is a root container of all persistent objects in this sample. The Company object contains two keys only. Note how a company name is assigned to a NAME property.
/** Person BO */ public class Person extends org.ujorm.implementation.map.MapUjoExt<Person> {
public static final Key<Person,Integer> ID = newKey("ID"); public static final Key<Person,String> FIRSTNAME = newKey("FirstName"); public static final Key<Person,String> SURNAME = newKey("Surname"); public static final Key<Person,Integer> AGE = newKey("Age"); public static final Key<Person,Boolean> MALE = newKey("Male"); public static final Key<Person,Double> CASH = newKey("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.ujorm.*; import org.ujorm.extensions.*;
/** Company BO */ public class Company extends org.ujorm.implementation.map.MapUjoExt<Company> {
public static final Key<Company,String> NAME = newKey("Name"); public static final ListKey<Company,Person> PERSONS = newListKey("Person");
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.ujorm.core.UjoManagerXML; import org.ujorm.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 Ujorm description for more informations.
About Author:
- You can write questions or other messages to me by a blog http://ujorm.blogspot.com/.
- A contact e-mail: ponec@ujorm.com
PPone(c) 2007-2009
Getting Started