Rapid Prototyping of Eclipse RCP Applications So, you want to create a quick RCP prototype for a client?
About us • Speaker • Patrik Suzzi, www.itemis.ch Software Engineer Eclipse Platform Committer • Audience • Are you familiar with JAXB, JPA? • Eclipse E4 and WindowBuilder?
IDE and Tools • Eclipse IDE for RCP and RAP development (Oxygen.1a) + Nebula Widgets (to use XY Graph) http://download.eclipse.org/nebula/releases/latest + WindowBuilder (if not already installed in Eclipse IDE for RCP..) http://download.eclipse.org/windowbuilder/WB/integration/4.8/ • Libraries + EclipseLink (JPA and JAXB) https://www.eclipse.org/eclipselink/downloads/ + Database (Derby) https://db.apache.org/derby/
Getting started – build a RCP prototype • Build your Data Model • Add Xml/DB persistence • Test the datamodel • Build your E4 Application • Start with a Simple UI • Evolve it in a Complex UI • Run your prototype
Data Model Customer customers -firstName: String -lastName: String * -address: String • Bank customers accounts * * • Customer recipientAccount Account Bank accounts sourceAccount -creationDate: Date • Account * -balance: double • Transaction transactions * • Subtypes transactions Transaction * #amount: double #confirmed: boolean • Use property change #processed: boolean listeners! Deposit Charge Transfer Withdrawal
Test Data Model Bank bank = new Bank(); // test mock data assertEquals("Nr. of Customers", 6, bank.getCustomers().size()); // create customers assertEquals("Nr. of Accounts", 7, bank.getAccounts().size()); Customer c1 = new Customer("Tom", "Jones", "Garden Street 8"); assertEquals("Nr. of Transactions", 10, bank.getTransactions().size()); Customer c2 = new Customer("Diana", "Jones", "Garden Street 8"); Customer c3 = new Customer("Mark", "Reuters", "Maple Street 122"); Customer c4 = new Customer("Spencer", "White", "Avenue Pontida 1"); // test containment Customer c5 = new Customer("Alex", "Michaelson", "Red Square 14b"); assertThat("Account's customer", a1.getCustomers().contains(c1)); Customer c6 = new Customer("Francois", "Berger", "Frederickstrasse 87"); assertThat("Customer's account", c1.getAccounts().contains(a1)); bank.addCustomers(c1,c2,c3,c4,c5,c6); assertThat("Transaction's account", t1.getSourceAccount().equals(a1)); // add accounts and link to customers Account a1 = new Account().link(c1); Account a2 = new Account().link(c1, c2); • Test the validity of your data! Account a3 = new Account().link(c3); Account a4 = new Account().link(c4); Account a5 = new Account().link(c5); Account a6 = new Account().link(c6); Account a7 = new Account().link(c6); bank.addAccounts(a1,a2,a3,a4,a5,a6,a7); // add transactions Transaction t1 = new Deposit().create(5000, a1).confirm("2016-02-20").process(); Transaction t2 = new Charge().create(250, a1).confirm("2016-03-10").process(); Transaction t3 = new Transfer().create(1000, a1, a2).confirm("2016-04-05").process(); Transaction t4 = new Deposit().create(10000, a3).confirm("2016-04-06").process(); Transaction t5 = new Deposit().create(5000, a3).confirm("2016-04-10").process(); Transaction t6 = new Deposit().create(5000, a3).confirm("2016-06-21").process(); Transaction t7 = new Deposit().create(10000, a3).confirm("2016-06-23").process(); Transaction t8 = new Withdrawal().create(2500, a3).confirm("2016-07-01").process(); Transaction t9 = new Charge().create(1500, a3).confirm("2016-07-03").process(); Transaction t10 = new Transfer().create(1000, a3, a2).confirm("2016-07-05").process(); bank.addTransactions(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10);
Add JAXB Annotations • XML tags @XmlRootElement public class Bank {...} @XmlAttribute • Attribute representing ID @XmlID public String getId() {...} • XML Aggregation, as list of IDs @XmlList @XmlIDREF referencing entities public List<Account> getAccounts() { ... } • Subclasses implementing abstract @XmlSeeAlso({Deposit.class, Charge.class, Withdrawal.class, Transfer.class}) superclass @XmlRootElement public abstract class Transaction {...}
XML Persistence Test ID attribute Aggregation ID list • Save and Load with JAXB <bank id="59340"> <customers id="2711"> <accounts>143365 170217</accounts> public static void persistXml(File xmlFile, Bank bank) { <address>Garden Street 8</address> JAXBContext jaxbContext = JAXBContext. newInstance (Bank. class ); <firstName>Tom</firstName> Marshaller marshaller = jaxbContext.createMarshaller(); <lastName>Jones</lastName> Subclass marshaller.setProperty(Marshaller. JAXB_FORMATTED_OUTPUT , true ); </customers> marshaller.marshal(bank, xmlFile); <accounts id="143365"> } <balance>3750.0</balance> <creationDate>2016-02-01T00:00:00+01:00</creationDate> <customers>2711</customers> public static Bank loadXml(File xmlFile) { <transactions>110290 79075 91111</transactions> JAXBContext jaxbContext = JAXBContext. newInstance (Bank. class ); </accounts> Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); <transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema- Bank bank = (Bank) unmarshaller.unmarshal(xmlFile); instance" xsi:type="deposit" id="110290"> return bank; <amount>5000.0</amount> } <confirmed>true</confirmed> <confirmedDate>2016-02-20T00:00:00+01:00</confirmedDate> <processed>true</processed> <processedDate>2016-02-20T00:00:00+01:00</processedDate> <sourceAccount>143365</sourceAccount> </transactions> Usage: TestPersistence.java </bank>
Add JPA2 Annotations • Superclass with no table defined for it @MappedSuperclass public class BaseModel {...} @Entity • Entity with a table defined for it public class Bank extends BaseModel{...} @OneToMany @JoinColumn(name="BANK_ID") • One way association with reference public List<Customer> getCustomers() {...} @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) • Single table inheritance, by @Table(name="T_TRANSACTION") discriminating column @DiscriminatorColumn(name="T_TYPE") public abstract class Transaction {...} @Entity @DiscriminatorValue("D") • Subclass with given discriminator public class Deposit extends Transaction {...}
DB Persistence Test • Persist and Load with JPA public static void persistDB(Bank bank){ EntityManager em = instance ().getEntityManager(); em.getTransaction().begin(); em.merge(bank); em.flush(); em.getTransaction().commit(); } public static Bank loadDB() throws JAXBException { EntityManager em = instance ().getEntityManager(); em.getTransaction().begin(); TypedQuery<Bank> query = em.createQuery( SELECT_BANK , Bank. class ); Bank bank = query.getSingleResult(); return bank; } Usage: TestPersistence.java
E4 RCP Application • Plugin project • Rich Client Application • E4 RCP Template • Model Editor • Application Structure • Perspectives • Customers • Accounts • Transactions
Setting the Data Model • Application @Execute public void execute(MApplication app, IEventBroker eventBroker) • Model change { Bank bank = new Bank(); app.getContext().set(Bank.class, bank); • Trigger Events eventBroker.send(EventConstants.TOPIC_MODEL_MODIFIED, bank); } • User Interface @Inject @Optional private void modelModified(@UIEventTopic( • Framework triggers EventConstants.TOPIC_MODEL_MODIFIED) Bank model) { • Initialize UI setModel(model); }
The E4 Model Editor Handlers Commands MenuItems Perspectives Sash Containers View Parts Controls
Example - Customers perspective • Search edit Filter/search • Select select • Edit user • Model change • UI Update
UI - Simple UI with Window Builder • Visual Designer • Drag and drop • Layouting • Data Binding • UI <-> Model • UI Interaction • Initialize Model • Model changes • Selection changes • Widget events
Demo – Simple UI
UI Interaction - model public void setModel(Bank model) { • Initialize UI Model if(model==null) return; • Reset bindings disposeBindings(m_bindingContext); super.setModel(model); • Update UI if(listViewer==null) return; m_bindingContext = initDataBindings(); update(); } • Model Changes @Inject @Optional private void modelModified(@UIEventTopic( • Update UI EventConstants.TOPIC_MODEL_MODIFIED) Account account) { update(); }
UI Interaction - events • Selection Changes @Inject protected ESelectionService selectionService; • Reset bindings listViewer.addSelectionChangedListener((e)->{ • Update UI selectionService.setSelection( listViewer.getStructuredSelection().getFirstElement()); }); btnSearch.addSelectionListener(new SelectionAdapter() { • Widget Events public void widgetSelected(SelectionEvent e) { update(); • Update UI } });
UI - Complex UI with Window Builder • Canvas • Table Data Binding • Custom code private void update() { tableViewer.refresh(); tableViewer_1.refresh(); resizeColumns (table); resizeColumns (table_1); ChartHelper. generateGraph (lws, getModel()); }
Recommend
More recommend