Click here to close now.

Welcome!

AJAX & REA Authors: Jason Bloomberg, Kevin Jackson, Carmen Gonzalez, Elizabeth White, Hovhannes Avoyan

Related Topics: Web 2.0, AJAX & REA

Web 2.0: Blog Feed Post

Three Steps to Build a Killer WebSocket App with JavaFX

The app I wanted to build consumes the same data source as the lightning fast Kaazing portfolio demo


Here’s the source for my Sample.fxml file:

 

<?xml version="1.0" encoding="UTF-8"?>

<?import fxmltableview.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.collections.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.cell.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<?import javafxapplication4.*?>

<AnchorPane id="AnchorPane" prefHeight="443.999755859375" prefWidth="656.9998779296875" xmlns:fx="http://javafx.com/fxml" fx:controller="javafxapplication4.SampleController">
  <children>
    <BorderPane prefHeight="706.0" prefWidth="717.0" snapToPixel="false" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="0.0">
      <right>
        <TableView fx:id="tableView" editable="true" prefHeight="393.999755859375" prefWidth="555.9998779296875">
          <columns>
            <TableColumn prefWidth="240.0" text="Company" fx:id="company">
              <cellValueFactory>
                <PropertyValueFactory property="company" />
              </cellValueFactory>
            </TableColumn>
            <TableColumn prefWidth="100.0" text="Ticker" fx:id="ticker">
              <cellValueFactory>
                <PropertyValueFactory property="ticker" />
              </cellValueFactory>
            </TableColumn>
            <TableColumn prefWidth="100.0" text="Price" fx:id="price">
              <cellValueFactory>
                <PropertyValueFactory property="price" />
              </cellValueFactory>
            </TableColumn>
            <TableColumn prefWidth="100.0" text="Change" fx:id="change">
              <cellValueFactory>
                <PropertyValueFactory property="change" />
              </cellValueFactory>
            </TableColumn>
          </columns>
          <BorderPane.margin>
            <Insets bottom="50.0" left="50.0" right="50.0" top="50.0" />
          </BorderPane.margin>
        </TableView>
      </right>
      <top>
        <Pane prefHeight="32.0" prefWidth="745.0">
          <children>
            <Label alignment="CENTER" contentDisplay="CENTER" layoutX="14.0" layoutY="5.0" prefWidth="614.9998779296875" text="WebSocket Portfolio Demo" textAlignment="CENTER" textFill="#cc6200">
              <font>
                <Font name="System Bold" size="24.0" />
              </font>
            </Label>
          </children>
        </Pane>
      </top>
    </BorderPane>
  </children>
</AnchorPane>

 

Then, I defined the data model driving my TableView. I created a JavaBean, called Stock, with four private variables. The first three: company, ticker, and price, represent the first three columns of my TableView. The fourth one is a computed value, displaying the change of the price of a stock.

 

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javafxapplication4;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

/**
 *
 * @author pmoskovi
 */
public class Stock {

    private SimpleStringProperty company;
    private SimpleStringProperty ticker;
    private SimpleStringProperty price;
    private SimpleStringProperty change;

    public Stock () {
        setCompany("");
        setTicker("");
        setPrice("");
    }

    public Stock(String company, String ticker, String price, String shares, String value) {
        setCompany(company);
        setTicker (ticker);
        setPrice (price);
    }

    public String getCompany() {
        return companyProperty().get();
    }

    public void setCompany(String company) {
        companyProperty().set(company);
    }

    public StringProperty companyProperty() {
        if (company == null) {
            company = new SimpleStringProperty(this, "company");
        }
         return company;
    }

    public String getTicker() {
        return tickerProperty().get();
    }

    public void setTicker(String ticker) {
        tickerProperty().set(ticker);
    }

    public StringProperty tickerProperty() {
        if (ticker == null) {
            ticker = new SimpleStringProperty(this, "ticker");
        }
         return ticker;
    }

    public String getPrice() {
        return priceProperty().get();
    }

    public void setPrice(String price) {
        priceProperty().set(price);
    }

    public StringProperty priceProperty() {
        if (price == null) {
            price = new SimpleStringProperty(this, "price");
        }
         return price;
    }

    public String getChange() {
        return changeProperty().get();
    }

    public void setChange(String change) {
        changeProperty().set(change);
    }

    public StringProperty changeProperty() {
        if (change == null) {
            change = new SimpleStringProperty(this, "change");
        }
         return change;
    }
}

 

Step 3 – Feeding the application with data through WebSockets

Lastly, by simply following the How to Build Java Client Using Kaazing WebSocket Gateway I created the WebSocket connection, subscribed to the stock data feed, and updated my model which in turn refreshed the TableView in the screen.

The app uses the JMS Edition of Kaazing WebSocket Gateway, allowing you to invoke JMS APIs directly in the JavaFX application code.

 

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javafxapplication4;

import java.net.URL;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.naming.Context;
import javax.naming.InitialContext;

/**
 *
 * @author pmoskovi
 */
public class SampleController implements Initializable {

    private ObservableList data;
    @FXML
    private Label label;
    @FXML
    private TableView tableView;
    @FXML
    private TableColumn<Stock, String> change;
    ListIterator it;

    public void startRendering() {

        addStock("3mCo", "MMM", "", "", "");
        addStock("AT&T Inc", "T", "", "", "");
        addStock("Boeing Co", "BA", "", "", "");
        addStock("Citigroup", "C", "", "", "");
        addStock("Hewlett-Packard Co", "HPQ", "", "", "");
        addStock("Intel Corporation", "INTC", "", "", "");
        addStock("International Business Machines", "IBM", "", "", "");
        addStock("McDonald's Cororation", "MCD", "", "", "");
        addStock("Microsoft Corporation", "MSFT", "", "", "");
        addStock("Verizon Communications", "VZ", "", "", "");
        addStock("Wal-Mart Stores Inc", "WMT", "", "", "");

        doConnect();
    }

    protected void addStock(String company, String ticker, String price, String shares, String value) {
        ObservableList data = tableView.getItems();
        data.add(new Stock(company, ticker, price, shares, value));
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        startRendering();
    }

    protected void doConnect() {
        Properties props = new Properties();
        props.put(InitialContext.INITIAL_CONTEXT_FACTORY,
                "com.kaazing.gateway.jms.client.stomp.StompInitialContextFactory");

        //WebSocket end-point
        props.put(Context.PROVIDER_URL, "ws://demo.kaazing.com/jms");
        InitialContext ctx;
        final ObservableList data = tableView.getItems();

        try {
            ctx = new InitialContext(props);
            ConnectionFactory connectionFactory;
            connectionFactory = (ConnectionFactory) ctx.lookup("ConnectionFactory");

            //Creating WebSocket connection
            Connection connection = connectionFactory.createConnection(null, null);
            connection.setExceptionListener(new ExceptionListener() {
                @Override
                public void onException(JMSException jmse) {
                    jmse.printStackTrace();
                }
            });

            //Creating JMS session
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            //Creating JMS topic
            Topic topic = (Topic) ctx.lookup("/topic/portfolioStock");

            //Creating JMS consumer
            MessageConsumer consumer = session.createConsumer(topic);
            consumer.setMessageListener(new MessageListener() {
                @Override
                public void onMessage(Message msg) {
                    it = data.listIterator();

                    try {
                        // Creating a String array out of the incoming message: ticker, company, price
                        String[] stockMsgArr = parseList(((TextMessage) msg).getText(), ":");

//                        System.out.println(stockMsgArr[0] + ":" + stockMsgArr[1] + ":" + stockMsgArr[2]);
                        // Loop through all the elements of the viewTable model
                        while (it.hasNext()) {
                            // st holds the current row of tableView
                            Stock st = (Stock)it.next();
//                            System.out.println("st.getTicker() " + st.getTicker() + " | " + "stockMsgArr[1] " + stockMsgArr[1]);

                            if (st.getTicker().equals(stockMsgArr[1])) {
                                Float oldValue, newValue;
                                newValue = Float.parseFloat(stockMsgArr[2]);
                                oldValue = Float.parseFloat((st.getPrice().equals("")) ? "0" : st.getPrice());
//                                System.out.println ("oldValue: " + oldValue + " | newValue: " + newValue);
                                ((Stock)(it.previous())).setChange(new DecimalFormat("#.##").format((newValue-oldValue)));
                                st.setPrice (newValue.toString());
                                break;
                            }
                        }
                    } catch (JMSException e) {
                        e.printStackTrace();
                    }
                }
            });
            connection.start();
        } catch (Exception ex) {
            Logger.getLogger(SampleController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static String[] parseList(String list, String delim) {
        List result = new ArrayList();
        StringTokenizer tokenizer = new StringTokenizer(list, delim);
        while (tokenizer.hasMoreTokens()) {
            result.add(tokenizer.nextToken());
        }
        return (String[]) result.toArray(new String[0]);
    }

}

 

If you’re attending JavaOne this year, come to our session for goodies and cool demos on WebSockets.

To learn more about the JMS APIs exposed to Web clients, or if you want to see step-by-step instructions on building a true HTML5 WebSocket app using the JavaScript API, check out these Kaazing tutorials.


Read the original blog entry...

More Stories By Jonas Jacobi

Jonas has 21 years of experience leading the development of innovative technology products and services. Together with Kaazing’s Co-Founder & CTO John Fallows, he pioneered and championed the groundbreaking HTML5 WebSocket standard. Prior to co-founding Kaazing he served as VP of Product Management for Brane Corporation, a Silicon Valley startup dedicated to developing a market-leading enterprise platform for building model-driven apps. Before Brane, he spent 8+ years at Oracle where he served as a Java EE and open source Evangelist, and was Product Manager in the Oracle Application Server division for JavaServer Faces, Oracle ADF Faces, and Oracle ADF Faces Rich Client. He is a frequent speaker at international conferences on accelerating and scaling secure enterprise-grade WebComms (Web Communications).

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


@CloudExpo Stories
SYS-CON Events announced today that Site24x7, the cloud infrastructure monitoring service, will exhibit at SYS-CON's 16th International Cloud Expo®, which will take place on June 9-11, 2015, at the Javits Center in New York City, NY. Site24x7 is a cloud infrastructure monitoring service that helps monitor the uptime and performance of websites, online applications, servers, mobile websites and custom APIs. The monitoring is done from 50+ locations across the world and from various wireless carr...
Sonus Networks introduced the Sonus WebRTC Services Solution, a virtualized Web Real-Time Communications (WebRTC) offer, purpose-built for the Cloud. The WebRTC Services Solution provides signaling from WebRTC-to-WebRTC applications and interworking from WebRTC-to-Session Initiation Protocol (SIP), delivering advanced real-time communications capabilities on mobile applications and on websites, which are accessible via a browser.
SYS-CON Events announced today that Intelligent Systems Services will exhibit at SYS-CON's 16th International Cloud Expo®, which will take place on June 9-11, 2015, at the Javits Center in New York City, NY. Established in 1994, Intelligent Systems Services Inc. is located near Washington, DC, with representatives and partners nationwide. ISS’s well-established track record is based on the continuous pursuit of excellence in designing, implementing and supporting nationwide clients’ mission-cri...
SYS-CON Events announced today that B2Cloud, a provider of enterprise resource planning software, will exhibit at SYS-CON's 16th International Cloud Expo®, which will take place on June 9-11, 2015, at the Javits Center in New York City, NY. B2cloud develops the software you need. They have the ideal tools to help you work with your clients. B2Cloud’s main solutions include AGIS – ERP, CLOHC, AGIS – Invoice, and IZUM
SYS-CON Events announced today that Tufin, the market-leading provider of Security Policy Orchestration Solutions, will exhibit at SYS-CON's 16th International Cloud Expo®, which will take place on June 9-11, 2015, at the Javits Center in New York City, NY. As the market leader of Security Policy Orchestration, Tufin automates and accelerates network configuration changes while maintaining security and compliance. Tufin's award-winning Orchestration Suite™ gives IT organizations the power and a...
SYS-CON Events announced today that Cloudian, Inc., the leading provider of hybrid cloud storage solutions, will exhibit at SYS-CON's 16th International Cloud Expo®, which will take place on June 9-11, 2015, at the Javits Center in New York City, NY. Cloudian, Inc., is a Foster City, California - based software company specializing in cloud storage software. The main product is Cloudian, an Amazon S3-compliant cloud object storage platform, the bedrock of cloud computing systems, that enables c...
SYS-CON Events announced today that Gridstore™, the leader in hyper-converged infrastructure purpose-built to optimize Microsoft workloads, will exhibit at SYS-CON's 16th International Cloud Expo®, which will take place on June 9-11, 2015, at the Javits Center in New York City, NY. Gridstore™ is the leader in hyper-converged infrastructure purpose-built for Microsoft workloads and designed to accelerate applications in virtualized environments. Gridstore’s hyper-converged infrastructure is the ...
SYS-CON Events announced today that IDenticard will exhibit at SYS-CON's 16th International Cloud Expo®, which will take place on June 9-11, 2015, at the Javits Center in New York City, NY. IDenticard™ is the security division of Brady Corp (NYSE: BRC), a $1.5 billion manufacturer of identification products. We have small-company values with the strength and stability of a major corporation. IDenticard offers local sales, support and service to our customers across the United States and Canada...
SYS-CON Events announced today that On the Avenue Marketing Group, a sales and marketing firm that utilizes events to market and sell products to consumers, will exhibit at SYS-CON's 16th International Cloud Expo®, which will take place on June 9-11, 2015, at the Javits Center in New York City, NY. On the Avenue Marketing Group (OTA) is a sales and marketing firm that utilizes events to market and sell products to consumers. On behalf of our clients, we attend thousands of fairs, festivals, exp...
Containers and microservices have become topics of intense interest throughout the cloud developer and enterprise IT communities. Accordingly, attendees at the upcoming 16th Cloud Expo at the Javits Center in New York June 9-11 will find fresh new content in a new track called PaaS | Containers & Microservices Containers are not being considered for the first time by the cloud community, but a current era of re-consideration has pushed them to the top of the cloud agenda. With the launch ...
While DevOps most critically and famously fosters collaboration, communication, and integration through cultural change, culture is more of an output than an input. In order to actively drive cultural evolution, organizations must make substantial organizational and process changes, and adopt new technologies, to encourage a DevOps culture. Moderated by Andi Mann, panelists will discuss how to balance these three pillars of DevOps, where to focus attention (and resources), where organizations m...
“In the past year we've seen a lot of stabilization of WebRTC. You can now use it in production with a far greater degree of certainty. A lot of the real developments in the past year have been in things like the data channel, which will enable a whole new type of application," explained Peter Dunkley, Technical Director at Acision, in this SYS-CON.tv interview at @ThingsExpo, held Nov 4–6, 2014, at the Santa Clara Convention Center in Santa Clara, CA.
of cloud, colocation, managed services and disaster recovery solutions, will exhibit at SYS-CON's 16th International Cloud Expo®, which will take place on June 9-11, 2015, at the Javits Center in New York City, NY. TierPoint, LLC, is a leading national provider of information technology and data center services, including cloud, colocation, disaster recovery and managed IT services, with corporate headquarters in St. Louis, MO. TierPoint was formed through the strategic combination of some of t...
SYS-CON Events announced today that Column Technologies, a global technology solutions company, will exhibit at SYS-CON's DevOps Summit 2015 New York, which will take place June 9-11, 2015, at the Javits Center in New York City, NY. Established in 1998, Column Technologies is a leader in application performance and infrastructure management for commercial and federal markets. The company is headquartered in the United States, with a diverse and talented team of more than 350 employees around th...
Health care systems across the globe are under enormous strain, as facilities reach capacity and costs continue to rise. M2M and the Internet of Things have the potential to transform the industry through connected health solutions that can make care more efficient while reducing costs. In fact, Vodafone's annual M2M Barometer Report forecasts M2M applications rising to 57 percent in health care and life sciences by 2016. Lively is one of Vodafone's health care partners, whose solutions enable o...
SYS-CON Events announced today that Ciqada will exhibit at SYS-CON's @ThingsExpo, which will take place on June 9-11, 2015, at the Javits Center in New York City, NY. Ciqada™ makes it easy to connect your products to the Internet. By integrating key components - hardware, servers, dashboards, and mobile apps - into an easy-to-use, configurable system, your products can quickly and securely join the internet of things. With remote monitoring, control, and alert messaging capability, you will mee...
SYS-CON Media announced today that @WebRTCSummit Blog, the largest WebRTC resource in the world, has been launched. @WebRTCSummit Blog offers top articles, news stories, and blog posts from the world's well-known experts and guarantees better exposure for its authors than any other publication. @WebRTCSummit Blog can be bookmarked ▸ Here @WebRTCSummit conference site can be bookmarked ▸ Here
SYS-CON Events announced today that GENBAND, a leading developer of real time communications software solutions, has been named “Silver Sponsor” of SYS-CON's WebRTC Summit, which will take place on June 9-11, 2015, at the Javits Center in New York City, NY. The GENBAND team will be on hand to demonstrate their newest product, Kandy. Kandy is a communications Platform-as-a-Service (PaaS) that enables companies to seamlessly integrate more human communications into their Web and mobile applicatio...
Public Cloud IaaS started it's life in the developer and startup communities and has grown rapidly to a $20B+ industry, but it still pales in comparison to how much is spent worldwide on IT: $3.6 trillion. In fact, there are 8.6 million data centers worldwide, the reality is many small and medium sized business have server closets and colocation footprints filled with servers and storage gear. While on-premise environment virtualization may have peaked at 75%, the Public Cloud has lagged in ado...
Dave will share his insights on how Internet of Things for Enterprises are transforming and making more productive and efficient operations and maintenance (O&M) procedures in the cleantech industry and beyond. Speaker Bio: Dave Landa is chief operating officer of Cybozu Corp (kintone US). Based in the San Francisco Bay Area, Dave has been on the forefront of the Cloud revolution driving strategic business development on the executive teams of multiple leading Software as a Services (SaaS) ap...