Welcome!

Machine Learning Authors: Liz McMillan, Yeshim Deniz, Pat Romanski, Elizabeth White, Shelly Palmer

Related Topics: Agile Computing, Machine Learning

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 Kaazing Blog

Kaazing is helping define the future of the event-driven enterprise by accelerating the Web for the Internet of Things.

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 delaPlex will exhibit at SYS-CON's @ThingsExpo, which will take place on June 6-8, 2017, at the Javits Center in New York City, NY. delaPlex pioneered Software Development as a Service (SDaaS), which provides scalable resources to build, test, and deploy software. It’s a fast and more reliable way to develop a new product or expand your in-house team.
Regardless of what business you’re in, it’s increasingly a software-driven business. Consumers’ rising expectations for connected digital and physical experiences are driving what some are calling the "Customer Experience Challenge.” In his session at @DevOpsSummit at 20th Cloud Expo, Marco Morales, Director of Global Solutions at CollabNet, will discuss how organizations are increasingly adopting a discipline of Value Stream Mapping to ensure that the software they are producing is poised to o...
IBM helps FinTechs and financial services companies build and monetize cognitive-enabled financial services apps quickly and at scale. Hosted on IBM Bluemix, IBM’s platform builds in customer insights, regulatory compliance analytics and security to help reduce development time and testing. In his session at 20th Cloud Expo, Tom Eck, Industry Platforms CTO at IBM Cloud, will discuss how these tools simplify the time-consuming tasks of selection, mapping and data integration, allowing developers ...
SYS-CON Events announced today that Outscale, a global pure play Infrastructure as a Service provider and strategic partner of Dassault Systèmes, will exhibit at SYS-CON's 20th International Cloud Expo®, which will take place on June 6-8, 2017, at the Javits Center in New York City, NY. Founded in 2010, Outscale simplifies infrastructure complexities and boosts the business agility of its customers. Outscale delivers a secure, reliable and industrial strength solution for its customers, which in...
SYS-CON Events announced today that Outscale will exhibit at SYS-CON's 20th International Cloud Expo®, which will take place on June 6-8, 2017, at the Javits Center in New York City, NY. Outscale's technology makes an automated and adaptable Cloud available to businesses, supporting them in the most complex IT projects while controlling their operational aspects. You boost your IT infrastructure's reactivity, with request responses that only take a few seconds.
SYS-CON Events announced today that Systena America will exhibit at SYS-CON's 20th International Cloud Expo®, which will take place on June 6-8, 2017, at the Javits Center in New York City, NY. Systena Group has been in business for various software development and verification in Japan, US, ASEAN, and China by utilizing the knowledge we gained from all types of device development for various industries including smartphones (Android/iOS), wireless communication, security technology and IoT serv...
DevOps at Cloud Expo – being held October 31 - November 2, 2017, 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 world's largest enterprises – and delivering real r...
Cloud applications are seeing a deluge of requests to support the exploding advanced analytics market. “Open analytics” is the emerging strategy to deliver that data through an open data access layer, in the cloud, to be directly consumed by external analytics tools and popular programming languages. An increasing number of data engineers and data scientists use a variety of platforms and advanced analytics languages such as SAS, R, Python and Java, as well as frameworks such as Hadoop and Spark...
Cloud promises the agility required by today’s digital businesses. As organizations adopt cloud based infrastructures and services, their IT resources become increasingly dynamic and hybrid in nature. Managing these require modern IT operations and tools. In his session at 20th Cloud Expo, Raj Sundaram, Senior Principal Product Manager at CA Technologies, will discuss how to modernize your IT operations in order to proactively manage your hybrid cloud and IT environments. He will be sharing bes...
Interested in leveling up on your Cloud Foundry skills? Join IBM for Cloud Foundry Days on June 7 at Cloud Expo New York at the Javits Center in New York City. Cloud Foundry Days is a free half day educational conference and networking event. Come find out why Cloud Foundry is the industry's fastest-growing and most adopted cloud application platform.
Five years ago development was seen as a dead-end career, now it’s anything but – with an explosion in mobile and IoT initiatives increasing the demand for skilled engineers. But apart from having a ready supply of great coders, what constitutes true ‘DevOps Royalty’? It’ll be the ability to craft resilient architectures, supportability, security everywhere across the software lifecycle. In his keynote at @DevOpsSummit at 20th Cloud Expo, Jeffrey Scheaffer, GM and SVP, Continuous Delivery Busine...
In order to meet the rapidly changing demands of today’s customers, companies are continually forced to redefine their business strategies in order to meet these needs, stay relevant and continue to see profitable growth. IoT deployment and development is integral in this transformation, and today businesses are increasingly seeing the value of investing their resources into IoT deployments. These technologies are able increase ROI through projects such as connecting supply chains or enabling sm...
SYS-CON Events announced today that Twistlock, the leading provider of cloud container security solutions, will exhibit at SYS-CON's 20th International Cloud Expo®, which will take place on June 6-8, 2017, at the Javits Center in New York City, NY. Twistlock is the industry's first enterprise security suite for container security. Twistlock's technology addresses risks on the host and within the application of the container, enabling enterprises to consistently enforce security policies, monitor...
SYS-CON Events announced today that CollabNet, a global leader in enterprise software development, release automation and DevOps solutions, will be a Bronze Sponsor of SYS-CON's 20th International Cloud Expo®, taking place from June 6-8, 2017, at the Javits Center in New York City, NY. CollabNet offers a broad range of solutions with the mission of helping modern organizations deliver quality software at speed. The company’s latest innovation, the DevOps Lifecycle Manager (DLM), supports Value S...
SYS-CON Events announced today that Peak 10, Inc., a national IT infrastructure and cloud services provider, will exhibit at SYS-CON's 20th International Cloud Expo®, which will take place on June 6-8, 2017, at the Javits Center in New York City, NY. Peak 10 provides reliable, tailored data center and network services, cloud and managed services. Its solutions are designed to scale and adapt to customers’ changing business needs, enabling them to lower costs, improve performance and focus intern...
Everywhere we turn in our industry we can find strong opinions about the direction, type and nature of cloud’s impact on computing and business. Another word that is used in every context in our industry is “hybrid.” In his session at 20th Cloud Expo, Alvaro Gonzalez, Director of Technical, Partner and Field Marketing at Peak 10, will use a combination of a few conceptual props and some research recently commissioned by Peak 10 to offer a real-world consideration of how the various categories of...
A strange thing is happening along the way to the Internet of Things, namely far too many devices to work with and manage. It has become clear that we'll need much higher efficiency user experiences that can allow us to more easily and scalably work with the thousands of devices that will soon be in each of our lives. Enter the conversational interface revolution, combining bots we can literally talk with, gesture to, and even direct with our thoughts, with embedded artificial intelligence, whic...
SYS-CON Events announced today that Super Micro Computer, Inc., a global leader in compute, storage and networking technologies, will exhibit at SYS-CON's 20th International Cloud Expo®, which will take place on June 6-8, 2017, at the Javits Center in New York City, NY. Supermicro (NASDAQ: SMCI), the leading innovator in high-performance, high-efficiency server technology, is a premier provider of advanced server Building Block Solutions® for Data Center, Cloud Computing, Enterprise IT, Hadoop/...
DevOps is often described as a combination of technology and culture. Without both, DevOps isn't complete. However, applying the culture to outdated technology is a recipe for disaster; as response times grow and connections between teams are delayed by technology, the culture will die. A Nutanix Enterprise Cloud has many benefits that provide the needed base for a true DevOps paradigm. In his Day 3 Keynote at 20th Cloud Expo, Chris Brown, a Solutions Marketing Manager at Nutanix, will explore t...
This talk centers around how to automate best practices in a multi-/hybrid-cloud world based on our work with customers like GE, Discovery Communications and Fannie Mae. Today’s enterprises are reaping the benefits of cloud computing, but also discovering many risks and challenges. In the age of DevOps and the decentralization of IT, it’s easy to over-provision resources, forget that instances are running, or unintentionally expose vulnerabilities.