Meaningful HTML/Java DukeScript Framework Applications (Part 2)

OK, so now the application I started working on is even more meaningful.

Firstly, what is it all about? Well, with the DukeScript Framework, you use Java to write application logic, with HTML5 to render the UI. No Swing. No JavaFX. HTML takes the place of those toolkits. Then you can manipulate the HTML page from Java, use REST or WebSockets, and do anything else with Java that you might want to do.

So here's the state of my CRUD app right now, i.e., still only R, but with improved code (thanks Jarda), and now the selected customer is displayed when a row is selected. 

Let's start by looking at the HTML file that defines the above.

<html>
    <body>
        <h1>Sample Database</h1>
        <table border="1">
            <thead>
                <tr>
                    <th>Name</th>
                    <th>City</th>
                    <th>State</th>
                    <th>Mail</th>
                </tr>
            </thead>
            <tbody data-bind="foreach: customers">
                <tr data-bind="click: $root.selectCustomer" style="cursor: pointer">
                    <td data-bind="text: name"></td>
                    <td data-bind="text: city"></td>
                    <td data-bind="text: state"></td>
                    <td data-bind="text: email"></td>
                </tr>
            </tbody>
        </table>
        <br/>
        <b>Current Selection</b>
        <p data-bind="with: selectedCustomer">
            <font color="red">Name</font>: <span data-bind="text: name"> </span>
            <br/>
            <font color="red">City</font>: <span data-bind="text: city"> </span>
        </p>
    </body>
</html>

What you see here is plain HTML together with Knockout bindings. The rows in the table are bound to properties in the model. When a row is selected, a method in the model is called that changes a property, which is bound with the Knockout "with" binding so that the currently selected name and city are shown.

Here's the definition of the Main class, which is annotated with the @Model annotation, and can be understood as a singleton:

@Model(className = "CrudApp", properties = {
    @Property(name = "selectedCustomer", type = CustomerData.class),
})
public final class Main {
    @ComputedProperty
    static java.util.List<CustomerData> customers() {
        EntityManager entityManager
                = Persistence.createEntityManagerFactory("myPU").
                createEntityManager();
        Query query = entityManager.createNamedQuery("Customer.findAll");
        List<CustomerData> arr = new ArrayList<>();
        for (Object object : query.getResultList()) {
            arr.add(((Customer) object).getData());
        }
        return arr;
    }
    @Function
    static void selectCustomer(CrudApp myModel, CustomerData data) {
        myModel.setSelectedCustomer(data);
    }
    private Main() {
    }
    /**
     * Launches the browser
     */
    public static void main(String... args) throws Exception {
        BrowserBuilder.newBrowser().
                loadPage("pages/index.html").
                loadClass(Main.class).
                invoke("onPageLoad", args).
                showAndWait();
        System.exit(0);
    }
    /**
     * Called when page is ready
     */
    public static void onPageLoad(String... args) throws Exception {
        new CrudApp().applyBindings();
    }
}

There's also a Customer POJO, i.e., a JPA entity, which in addition to the JPA annotations is annotated as follows:

@Model(className = "CustomerData", properties = {
    @Property(name = "name", type = String.class),
    @Property(name = "addressline1", type = String.class),
    @Property(name = "addressline2", type = String.class),
    @Property(name = "city", type = String.class),
    @Property(name = "state", type = String.class),
    @Property(name = "phone", type = String.class),
    @Property(name = "fax", type = String.class),
    @Property(name = "email", type = String.class),
    @Property(name = "creditLimit", type = int.class)
})

Plus, there's a getter that returns the CustomerData, so that the "customers()" method in the Main class can build up the list of customers.

The next step is to persist the data back into the database. Weird to be manipulating the DOM from Java but, obviously, great. 

Comments:

Thanks for this enlightening series. A general-purpose, multi-device way to use Java with a HTML UI would be extremely useful. As you pointed out earlier, the project does need better communication. When I first heard about "DukeScript" I assumed it was probably some way to script NetBeans applications...

Posted by Christoph Nahr on April 24, 2014 at 09:55 PM PDT #

Next step is to replace

<span data-bind="text: name"> </span>

with

<input data-bind="value: name"> </input>

possibly also clone the current user data (to not influence the data in primary table before submitting):

myModel.setSelectedCustomer(data.clone());

Posted by guest on April 25, 2014 at 12:37 AM PDT #

Now there is a CRUD wizard: http://wiki.apidesign.org/wiki/CRUD

Posted by Jaroslav Tulach on September 15, 2014 at 09:45 PM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.

Search

Archives
« March 2015
SunMonTueWedThuFriSat
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
    
       
Today