Click here to close now.

Welcome!

IoT User Interface Authors: Elizabeth White, Hovhannes Avoyan, AppDynamics Blog, Sematext Blog, Liz McMillan

Related Topics: Agile Computing, IoT User Interface

Agile Computing: 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
The 4th International Internet of @ThingsExpo, co-located with the 17th International Cloud Expo - to be held November 3-5, 2015, at the Santa Clara Convention Center in Santa Clara, CA - announces that its Call for Papers is open. The Internet of Things (IoT) is the biggest idea since the creation of the Worldwide Web more than 20 years ago.
T-Mobile has been transforming the wireless industry with its “Uncarrier” initiatives. Today as T-Mobile’s IT organization works to transform itself in a like manner, technical foundations built over the last couple of years are now key to their drive for more Agile delivery practices. In his session at DevOps Summit, Martin Krienke, Sr Development Manager at T-Mobile, will discuss where they started their Continuous Delivery journey, where they are today, and where they are going in an effort ...
As the Internet of Things unfolds, mobile and wearable devices are blurring the line between physical and digital, integrating ever more closely with our interests, our routines, our daily lives. Contextual computing and smart, sensor-equipped spaces bring the potential to walk through a world that recognizes us and responds accordingly. We become continuous transmitters and receivers of data. In his session at @ThingsExpo, Andrew Bolwell, Director of Innovation for HP's Printing and Personal S...
SYS-CON Events announced today that BMC 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. BMC delivers software solutions that help IT transform digital enterprises for the ultimate competitive business advantage. BMC has worked with thousands of leading companies to create and deliver powerful IT management services. From mainframe to cloud to mobile, BMC pairs high-speed digital innovation with robust...
All major researchers estimate there will be tens of billions devices - computers, smartphones, tablets, and sensors - connected to the Internet by 2020. This number will continue to grow at a rapid pace for the next several decades. With major technology companies and startups seriously embracing IoT strategies, now is the perfect time to attend @ThingsExpo, June 9-11, 2015, at the Javits Center in New York City. Learn what is going on, contribute to the discussions, and ensure that your enter...
SYS-CON Events announced today that SUSE, a pioneer in open source software, 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. SUSE provides reliable, interoperable Linux, cloud infrastructure and storage solutions that give enterprises greater control and flexibility. More than 20 years of engineering excellence, exceptional service and an unrivaled partner ecosystem power the products and support that help ...
SYS-CON Events announced today that MetraTech, now part of Ericsson, has been named “Silver Sponsor” of SYS-CON's 16th International Cloud Expo®, which will take place on June 9–11, 2015, at the Javits Center in New York, NY. Ericsson is the driving force behind the Networked Society- a world leader in communications infrastructure, software and services. Some 40% of the world’s mobile traffic runs through networks Ericsson has supplied, serving more than 2.5 billion subscribers.
Enterprises are fast realizing the importance of integrating SaaS/Cloud applications, API and on-premises data and processes, to unleash hidden value. This webinar explores how managers can use a Microservice-centric approach to aggressively tackle the unexpected new integration challenges posed by proliferation of cloud, mobile, social and big data projects. Industry analyst and SOA expert Jason Bloomberg will strip away the hype from microservices, and clearly identify their advantages and d...
The multi-trillion economic opportunity around the "Internet of Things" (IoT) is emerging as the hottest topic for investors in 2015. As we connect the physical world with information technology, data from actions, processes and the environment can increase sales, improve efficiencies, automate daily activities and minimize risk. In his session at @ThingsExpo, Ed Maguire, Senior Analyst at CLSA Americas, will describe what is new and different about IoT, explore financial, technological and re...
Today’s enterprise is being driven by disruptive competitive and human capital requirements to provide enterprise application access through not only desktops, but also mobile devices. To retrofit existing programs across all these devices using traditional programming methods is very costly and time consuming – often prohibitively so. In his session at @ThingsExpo, Jesse Shiah, CEO, President, and Co-Founder of AgilePoint Inc., discussed how you can create applications that run on all mobile ...
The Internet of Things is not only adding billions of sensors and billions of terabytes to the Internet. It is also forcing a fundamental change in the way we envision Information Technology. For the first time, more data is being created by devices at the edge of the Internet rather than from centralized systems. What does this mean for today's IT professional? In this Power Panel at @ThingsExpo, moderated by Conference Chair Roger Strukhoff, panelists will addresses this very serious issue o...
Cloud computing started a technology revolution; now DevOps is driving that revolution forward. By enabling new approaches to service delivery, cloud and DevOps together are delivering even greater speed, agility, and efficiency. No wonder leading innovators are adopting DevOps and cloud together! In his session at DevOps Summit, Andi Mann, Vice President of Strategic Solutions at CA Technologies, explored the synergies in these two approaches, with practical tips, techniques, research data, wa...
paradigm shifts in networking, to cloud and licensure, and all the Internet of Things in between. In 2014 automation was the name of the game. In his session at DevOps Summit, Matthew Joyce, a Sales Engineer at Big Switch, will discuss why in 2015 it’s complexity reduction. Matthew Joyce, a sales engineer at Big Switch, is helping push networking into the 21st century. He is also a hacker at NYC Resistor. Previously he worked at NASA Ames Research Center with the Nebula Project (where OpenSta...
"People are a lot more knowledgeable about APIs now. There are two types of people who work with APIs - IT people who want to use APIs for something internal and the product managers who want to do something outside APIs for people to connect to them," explained Roberto Medrano, Executive Vice President at SOA Software, in this SYS-CON.tv interview at Cloud Expo, held Nov 4–6, 2014, at the Santa Clara Convention Center in Santa Clara, CA.
SYS-CON Events announced today that O'Reilly Media has been named “Media Sponsor” of 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. O'Reilly Media spreads the knowledge of innovators through its books, online services, magazines, and conferences. Since 1978, O'Reilly Media has been a chronicler and catalyst of cutting-edge development, homing in on the technology trends that really matter and spurring their adoption...
There will be 150 billion connected devices by 2020. New digital businesses have already disrupted value chains across every industry. APIs are at the center of the digital business. You need to understand what assets you have that can be exposed digitally, what their digital value chain is, and how to create an effective business model around that value chain to compete in this economy. No enterprise can be complacent and not engage in the digital economy. Learn how to be the disruptor and not ...
2015 predictions circa 1970: houses anticipate our needs and adapt, city infrastructure is citizen and situation aware, office buildings identify and preprocess you. Today smart buildings have no such collective conscience, no shared set of fundamental services to identify, predict and synchronize around us. LiveSpace and M2Mi are changing that. LiveSpace Smart Environment devices deliver over the M2Mi IoT Platform real time presence, awareness and intent analytics as a service to local connecte...
The 5th International DevOps Summit, co-located with 17th International Cloud Expo – being held November 3-5, 2015, at the Santa Clara Convention Center in Santa Clara, CA – announces that its Call for Papers is open. Born out of proven success in agile development, cloud computing, and process automation, DevOps is a macro trend you cannot afford to miss. From showcase success stories from early adopters and web-scale businesses, DevOps is expanding to organizations of all sizes, including the...
Thanks to widespread Internet adoption and more than 10 billion connected devices around the world, companies became more excited than ever about the Internet of Things in 2014. Add in the hype around Google Glass and the Nest Thermostat, and nearly every business, including those from traditionally low-tech industries, wanted in. But despite the buzz, some very real business questions emerged – mainly, not if a device can be connected, or even when, but why? Why does connecting to the cloud cre...
The web app is Agile. The REST API is Agile. The testing and planning are Agile. But alas, Data infrastructures certainly are not. Once an application matures, changing the shape or indexing scheme of data often forces at best a top down planning exercise and at worst includes schema changes which force downtime. The time has come for a new approach that fundamentally advances the agility of distributed data infrastructures. Come learn about a new solution to the problems faced by software orga...