Version 1.1.2 of JavaFxPropertyHelper NetBeans Plugin Released

This a minor release of the JavaFxPropertyHelper NetBeans plugin, and will now follow JavaFX best practices by marking any get/set methods as final.

 

This plugin would create the following methods:

public final String getName() {
    return name.get();
}

public final void setName( String value ) {
    name.set(value);
}

public final StringProperty nameProperty() {
    return name;
}

 

The latest release version can either be download from github:
Or the NetBeans plug-in portal page.
Advertisements

New NetBeans Plugin to Generate Getter & Setter Methods for JavaFX Properties

JavaFxPropertyHelper NetBeans Plugin Released

 

This NetBeans plugin will help to generate get/set methods for JavaFx properties that are contained within a POJO.

The standard get/set code generator creates the following get/set methods for a JavaFx property which is not ideal:

private StringProperty name;

public StringProperty getName() { 
    return name;
}
public void setName( StringProperty name ) {
    this.name = name;
}

This plugin would create the following methods:

public String getName() {
    return name.get();
}

public void setName( String value ) {
    name.set(value);
}

public StringProperty nameProperty() {
    return name;
}

It’s also possible to use variables with the suffix Property in their names which will create the following methods:

private StringProperty nameProperty;
public String getName() {
    return nameProperty.get();
}

public void setName( String value ) {
    nameProperty.set(value);
}

public StringProperty nameProperty() {
    return nameProperty;
}

Usage

Press Alt-Insert to get the “Generate” popup menu, and select “Java FX Getter and Setter…” alt tag

Methods for supported property types will automatically be generated. alt tag

Supported Property Types

  • StringProperty
  • BooleanProperty
  • DoubleProperty
  • FloatProperty
  • IntegerProperty
  • LongProperty

Unsupported Property Types

  • ListProperty
  • MapProperty
  • ObjectProperty
  • SetProperty

The plugin is current available on GitHub at:

https://github.com/rterp/JavaFxPropertyHelperNBPlugin/releases/tag/1.1.1

and will hopefully be available via the general NetBeans Plugin portal by next week.

 

Freight Tracking with JavaFX and the NetBeans Rich Client Platform

iconI am super proud of my team who this week, rolled out Version 2.0 of Lynden Navigator to more than 1,000 desktops company-wide.   Navigator allows our freight terminal managers to optimize resource planning by giving them complete visibility to freight that is scheduled to arrive and depart to/from their facility.  In addition, customer service personnel have access to a new Shipment Tracing plugin included in this version which can be used to quickly access current information about customer freight and freight history.

The initial version of the application was built on the NetBeans Rich Client Platform (RCP), utilizing Swing UI components, but version 2.0 includes new functionality implemented with JavaFX.  A screenshot of the new version of Navigator appears below.  The top portion of the application is original portion that is utilizing Swing, and specifically components developed by JideSoft.   The lower portion of the screen is new functionality that has been built utilizing JavaFX.

FMS

Enter a caption

MVC tutorial with the NetBeans Rich Client Platform (RCP) and JavaFX

This tutorial illustrates the creation of a small application based on the NetBeans Rich Client Platform (RCP), and JavaFx, which will monitor the prices of a few stocks and update the UI in real time as prices are updated.  The application will make use of SceneBuilder to create an main UI, and JavaFX property bindings in order to keep the UI up to date as the prices are updated.


The Model

First, lets start with the model, a Stock class which will simply consist of a ticker symbol and a name.

public class Stock {
    
    protected String symbol;
    protected String name;

    public Stock(String symbol, String name) {
        this.symbol = symbol;
        this.name = name;
    }

    public String getSymbol() {
        return symbol;
    }

    public String getName() {
        return name;
    }    
}

Next, the listener interface that we will need to implement in order to get updates on the prices.  The priceUpdated() method will be invoked whenever a new price arrives for a stock.


public interface StockPriceUpdatedListener {

    public void priceUpdated( Stock stock, double price );
    
}

The model will consist of a collection of stocks, each of which will be mapped to a StringProperty.  When a new stock is added to the model, a new StringProperty will be created and mapped to the specified stock.  The model implements the StockPriceUpdatedListener interface.  When a new price is received, the StringProperty for that Stock will be looked up and updated.

Note that in the model below that you need to be on the main JavaFx thread when you update a property!  For the purposes of this application the stock prices are arriving from a non-ui thread, so updating the property needs to be wrapped in a Platform.runLater() call which will put the update on to the ui-thread.


import com.mvc.stock.price.Stock;
import com.mvc.stock.price.StockPriceUpdatedListener;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class StockModel implements StockPriceUpdatedListener {
    
    protected Map<Stock, StringProperty> stocks = new HashMap<>();
    DecimalFormat df = new DecimalFormat("$##0.00");
    
    public StringProperty addStock( Stock stock ) {
        StringProperty property = stocks.get(stock);
        if( property == null ) {
            property = new SimpleStringProperty("");
            stocks.put(stock, property);
        }
        
        return property;
    }
    
    @Override
    public void priceUpdated(Stock stock, double price) {
        //Don't update the properties from a non-JavaFx-UI thread!
        Platform.runLater( () -> stocks.get(stock).setValue(df.format(price)));
    }    
}


The View

Next, the view for this application was designed with SceneBuilder.  The layout consists of a GridPane containing information about a few stocks, as well as a subscribe button which will trigger the monitoring of price information.

Screen Shot 2015-06-12 at 1.06.11 PM

SceneBuilder generated the following FXML code below, with the UI controller set to:

com.mvc.stock.ui.StockPriceController

Also note that the button has its onAction event defined to call the subscribeButtonClicked() method which will need to be implemented in the StockPriceController class.


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

<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>


<AnchorPane id="AnchorPane" prefHeight="197.0" prefWidth="233.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="com.mvc.stock.ui.StockPricePanelController">
    <children>
        <GridPane alignment="CENTER" gridLinesVisible="true" layoutX="14.0" layoutY="14.0">
            <columnConstraints>
                <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
            </columnConstraints>
            <rowConstraints>
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            </rowConstraints>
            <children>
                <Label text="MSFT" GridPane.halignment="RIGHT" GridPane.rowIndex="1">
                    <padding>
                        <Insets right="10.0" />
                    </padding>
                </Label>
                <Label alignment="CENTER" text="Stock" textAlignment="CENTER" GridPane.halignment="CENTER">
                    <padding>
                        <Insets right="10.0" />
                    </padding>
                    <font>
                        <Font name="System Bold" size="13.0" />
                    </font>
                </Label>
                <Label text="Last Price" GridPane.columnIndex="1" GridPane.halignment="CENTER">
                    <font>
                        <Font name="System Bold" size="13.0" />
                    </font>
                </Label>
                <Label text="EBAY" GridPane.halignment="RIGHT" GridPane.rowIndex="3">
                    <padding>
                        <Insets right="10.0" />
                    </padding>
                </Label>
                <Label text="AMZN" GridPane.halignment="RIGHT" GridPane.rowIndex="2">
                    <padding>
                        <Insets right="10.0" />
                    </padding>
                </Label>
                <Label fx:id="msftPriceLabel" GridPane.columnIndex="1" GridPane.rowIndex="1">
                    <padding>
                        <Insets left="10.0" />
                    </padding>
                </Label>
                <Label fx:id="amznPriceLabel" GridPane.columnIndex="1" GridPane.rowIndex="2">
                    <padding>
                        <Insets left="10.0" />
                    </padding>
                </Label>
                <Label fx:id="ebayPriceLabel" GridPane.columnIndex="1" GridPane.rowIndex="3">
                    <padding>
                        <Insets left="10.0" />
                    </padding>
                </Label>
            </children>
        </GridPane>
        <Button fx:id="subscribeButton" layoutX="136.0" layoutY="153.0" mnemonicParsing="false" onAction="#subscribeButtonClicked" text="Subscribe" />
    </children>
</AnchorPane>



The Controller

As mentioned above, the FXML file references StockPricePanelController as the UI’s controller.  The controller has 3 labels and a button defined which will be injected into the controller by annotating those fields with the @FXML annotation.  When the controller is first initialized it creates a new stock object for each stock and then binds the StringProperty of the StockModel to the StringProperty of its corresponding label.

Also, as previously stated, the controller will need to implement a method called subscribeButtonClicked() which was defined in the FXML above.  This method needs to be annotated with the @FXML annotation in order to be invoked when the subscribeButton is clicked.  When this action is invoked, the controller will subscribe to price data for the specified stocks.


import com.mvc.stock.price.Stock;
import com.mvc.stock.price.provider.IStockPriceProvider;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;

/**
 * FXML Controller class
 *
 */
public class StockPricePanelController implements Initializable {

    
    @FXML
    protected Label msftPriceLabel;
    
    @FXML
    protected Label amznPriceLabel;
    
    @FXML
    protected Label ebayPriceLabel;
    
    @FXML
    protected Button subscribeButton;
    
    protected StockModel stockModel;
    
    protected IStockPriceProvider provider;
    protected Stock msft = new Stock("MSFT", "Microsoft");
    protected Stock amzn = new Stock("AMZN", "Amazon");
    protected Stock ebay = new Stock("EBAY", "eBay");
    
    
    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        stockModel = new StockModel();
        //bind the string property from the model to the labels.
        msftPriceLabel.textProperty().bindBidirectional( stockModel.addStock(msft) );
        amznPriceLabel.textProperty().bindBidirectional( stockModel.addStock(amzn) );
        ebayPriceLabel.textProperty().bindBidirectional( stockModel.addStock(ebay) );
    }    

    public IStockPriceProvider getProvider() {
        return provider;
    }

    public void setProvider(IStockPriceProvider provider) {
        this.provider = provider;
    }

    @FXML
    public void subscribeButtonClicked( ActionEvent event ) {
        if( provider != null ) {
            provider.subscribeToPriceData(msft, stockModel);
            provider.subscribeToPriceData(amzn, stockModel);
            provider.subscribeToPriceData(ebay, stockModel);
        }
    }
    
}

The final piece is to tie JavaFX UI into the NetBeans module which this component is a part of.  In order to do this you will need to have a TopComponent defined for your module like in the example below.  Basically a TopComponent is a top level panel that is usually within a TabbedPane in the main UI.  The TopComponent class below uses the Lookup API to find an implementation of an IStockPriceProvider interface.  Next a JFXPanel is created, which is a Swing JPanel that can hold a JavaFX Scene.

Within the Platform.runLater() method, a new FXMLLoader is created which points to the location of the FXML file from above.  Once the loader has loaded the file, we can obtain a reference to the StockPricePanelController, and pass in the instance of the stockPriceProvider that was previously just looked up.

Finally, a new Scene is created,  added to the JFXPanel, and the JFXPanel is added to the Center position of the TopComponent.


public final class StockPriceTopComponent extends TopComponent {

    public StockPriceTopComponent() {
        initComponents();
        setName(Bundle.CTL_StockPriceTopComponent());
        setToolTipText(Bundle.HINT_StockPriceTopComponent());
        putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE);
        putClientProperty(TopComponent.PROP_DRAGGING_DISABLED, Boolean.TRUE);
        putClientProperty(TopComponent.PROP_UNDOCKING_DISABLED, Boolean.TRUE);
        
        
        IStockPriceProvider stockPriceProvider = Lookup.getDefault().lookup(IStockPriceProvider.class);
        if( stockPriceProvider == null ) {
            throw new IllegalStateException( "Provider is null");
        }        
        
        JFXPanel jfxPanel = new JFXPanel();

        //This needs to be set to make sure the JavaFx thread doesn't exit if the tab is closed.
        Platform.setImplicitExit(false);
        
        // create JavaFX scene
        Platform.runLater(() -> {
            Parent root;
            try {
                FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/mvc/stock/ui/StockPricePanel.fxml"));
                root = loader.load();
                StockPricePanelController controller = loader.getController();
                controller.setProvider(stockPriceProvider);
                
                Scene scene = new Scene(root);
                
                jfxPanel.setScene(scene);
            } catch (IOException ex) {
                Exceptions.printStackTrace(ex);
            }
        });
        add( jfxPanel, BorderLayout.CENTER );
    }

The resulting NetBeans application is shown below.

Screen Shot 2015-06-12 at 1.43.45 PM

twitter: @RobTerpilowski
t
witter: @LimitUpTrading

JavaFX Application Thread Mysteriously Disappearing in Netbeans RCP / JavaFX App

I have a fair amount of pluggable infrastructure in place with the NetBeans platform for trading related applications. My latest application, “Atlas Trader” is being used to route our commodity trades through Quantitative Brokers. I want to take advantage of JavaFX for this project as it provides a cleaner MVC separation than Swing does, and also provides a lot of eye candy out of the box, such as animated transitions, translucency, etc.). I have been having strange issues however when attempting to incorporate this as a module to my NetBeans platform application.

I started out with a stripped down version of the platform, since I don’t need any of the Swing components and all the UI components with be within an JavaFX Scene, so have only included the following RCP modules:

  • org-netbeans-api-annotations-common
  • org-openide-modules
  • org-openide-util
  • org-openide-util-lookup

In my module’s “Installer” class, the restored() method kicks off the JavaFX app with the following calls:

Application.launch(MainApp.class);
Platform.setImplicitExit(false);

Screen Shot 2015-04-10 at 11.07.51 AM

All seems to be ok at this point. The app launches and displays the UI correctly. I can log in and get to the main screen of the application.

Below is the main screen in the application. The issues arrises when one of the commodity labels at the top of the screen is clicked. The expected behaviour is to display a new JavaFX componenet allowing the user to enter an order.

Screen Shot 2015-04-10 at 11.13.21 AM

The “CommodityHeaderLabels” at the top of the UI have the following action method defined.

@FXML
public void fireCommodityClicked() {

When one of these headers are clicked, an exception is immediately thrown, complaining that:

Caused by: javafx.fxml.LoadException: 

/Users/RobTerpilowski/ZoiCapital/JavaSource/QTrader/ZQTrader-Plugin/target/classes/com/zoicapital/qtrader/plugin/TradePanel.fxml:15

at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2605)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2583)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2445)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2413)
at com.zoicapital.qtrader.plugin.TradePanel.init(TradePanel.java:198)
... 10 more

Caused by: java.lang.NullPointerException
at javafx.fxml.FXMLLoader.loadTypeForPackage(FXMLLoader.java:2920)

After drilling into the FXMLLoader class to find out what was going on, it appears that the “fireCommodityClick()” method is not being called from the JavaFX Event thread, and so it isn’t able to load the FXML file for the component that it needs to create when the item is clicked.

In fact, when running through the debugger, the JavaFX Thread is running prior to the component being clicked, but disappears when the component is clicked.

To make things even more difficult to understand, is that all the events leading up to this point are executed as expected in the RCP version of this application on the Java FX Application Thread. As I mentioned, I can log in to the application without any issues, and its not until one of these CommodityLabel components are clicked that the issue appears. Below is a screenshot of NB in the debugger with a breakpoint at the first line in the method that is called when the component is clicked. On the left side of the screen you can see the stack trace and that the current thread is the “AppKit Thread”, with the Java FX Application thread no longer present.

NB Screenshot

I set up a test project to run this application as a stand-alone outside of the NetBeans RCP, and things work as expected. The event method is called on the JavaFX Application Thread, and the resulting component is created and displayed as expected.

I can only think that there is an exception being swallowed somewhere, and that there may possibly be another NetBeans Platform module that is required in addition to the 4 modules that I mentioned at the beginning of this post.

I realize this post is a little short on the amount of code, but I’m looking for any other ideas on areas I could look at to further debug this issue.

twitter: @RobTerpilowski

Make Money Online Automatically. Trading Commodities with JavaFX and the NetBeans Rich Client Platform

Ok, so maybe it isn’t quite as easy as it sounds, but we were able to leverage an automated trading application we had previously written and the modularity of the NetBeans Rich Client Platform to create a commodity trading application that will interface with, and allow us to place trades with a new commodity broker.

Even though the original application was for the purposes of automated trading, we were able to use many of the same NetBeans plugins we had developed in order to create the new application, as well as utilize JavaFX to put a nice polished UI on the app.

The login screen is below. The commodity images on the right side of the screen scroll down the UI and represent each commodity market that we trade.
enter image description here

After logging in to the application, those same commodities are in a dock at the top of the window. The images have an animated effect that will fade-in a green background when the mouse moves over the component. The first table in the UI shows orders that have been sent to the broker, but have not been fully executed, and the lower table displays commodity orders that have been completely executed.

enter image description here

After clicking on a commodity component at the top of the screen, the user is presented with a dialog to enter details about the order which will be placed. In the case of the screenshot below, an order is being entered to purchase 50 contracts of gold.

enter image description here

The last screenshot displays the state of the two main tables after orders to trade gold and natural gas have been fully executed, and while an order to purchase 50 Canadian Dollar futures contracts is still in process.

enter image description here

And finally, the 2 minute demo below highlights the application’s functionality as well as shows off the animated transitions and other eye candy that is possible using JavaFX. I will be speaking at JavaOne at a session entitled Flexibility Breeds Complexity: Living in a Modular World [CON6767], where I will discuss this and other JavaFX applications built on the NetBeans Rich Client Platform.

twitter: @RobTerpilowski

Written with StackEdit.

Monitoring Real-Time Commodity Prices using JavaFX, NetBeans RCP, and Camel

Zoi Capital is a commodity investment firm which trades in the commodity futures markets on behalf of clients, with offices in New York and Seattle. We needed an application which could display the commodities we were currently holding as well as show any open profit/loss of our trades in real-time. In addition, we wanted to display the current performance of our trading strategy (named Telio) along with a comparison of the current performance of the S&P 500 stock index as well as the Dow Jones UBS commodity index.

Trades are placed from the Seattle office, but are monitored throughout the day from the New York office, so the application (which would be running in New York) needed a way to stay up to date with the current trades. The application also needed to be aesthetically pleasing as it was planned to put it on a large 50 inch LCD in the reception area of our New York office, where both staff and visitors could view the current trades and statistics in real time.

I had previously written an automated trading application on the NetBeans Rich Client Platform (RCP), where I had created a number of plug-ins, including a plug-in to connect to Interactive Brokers to retrieve real-time market data. Since I already had the plug-ins available in order to connect to a real-time data feed, it seemed a natural choice to also build the Quote Monitor application on the NetBeans RCP as well. Instead of using the existing Swing components however, I opted for JavaFX in order to give the application a polished look.

In order to get the trade information from the Seattle office to the Commodity Monitor application in the New York office, we made use of Camel to facilitate the communication between the 2 offices. The great thing about Camel is that it provides an abstraction layer for the actual communication mechanism between applications. Since the offices are not networked together we made use of the Camel email component in order to transfer the data from the Seattle office to the Commodity Monitor application. In the future we could move the communication mechanism to web services or JMS simply by changing a property file, with no code changes required as camel takes care of everything else under the hood.


System Architecture

enter image description here

Trades are placed in the Seattle office, and then emailed to a designated email box which the Commodity Monitor watches (via Camel). Trade information is then imported into the application, at which point it requests real-time quote information of the commodities from Interactive Brokers via their Java API. At this point the application can then update the profit/loss statistics in real-time.


Application Screen Shot

enter image description here

The grid in the top left portion of the screen displays the performance for our Telio trading strategy for today, for the month of August, and then the year-to-date return of the strategy. The table also shows the same statistics for the S&P 500 stock index and Dow Jones/UBS commodity index for comparison purposes.

Below the table is a candlestick chart displaying the performance of the S&P 500 Index futures for the current day. The chart made use of the charting API in JavaFX as well as CSS. The chart is updated in real-time throughout the day.

Finally, on the right half of the screen is a panel which displays the commodities that we are currently holding with current profit/loss on the trade. For example, we have a current profit of +0.18% since we bought natural gas.

To add additional eye candy to the application, I created a scrolling background with a slightly blurred Zoi Capital logo. The animation was extremely easy to set up in JavaFX, and I’ll post a short how-to blog on animations in the not-too-distant future.


Demo Video

Below is a 3 minute video demo showing the Commodity Monitor application with the animated scrolling background. About 40 seconds into the video an email is sent to the Camel email box, at which point the Commodity Monitor picks up the email and displays the commodities that were sent, and their corresponding profit/loss in real time. Another email is sent at the 2:10 mark that clears most of the commodities from the application.

 

twitter: @RobTerpilowski