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.

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

Use JavaFX to Add Google Maps to your NetBeans RCP Application

By utilizing the GMapsFX library which provides a JavaFX API for Google Maps, it is relatively straightforward to add a map component to a desktop application built on the NetBeans Rich Client Platform (RCP).

Assume we would like to add a map to a new TopComponent in the Editor mode in the frame, or for those who are not as familiar with NetBeans jargon, we would like to add a Map to a new tab within the main portion of the application frame.

First create a new NetBeans Module project which will utilize the GMapsFX component.

enter image description here

Enter project details
enter image description here

Use RELEASE80 of the NetBeans Platform. Please also note that the application will require Java 8 in order to run.
enter image description here

Once the project has been created, add the GMapsFX library as a dependency to the project.
The binaries are available on Maven Central and the source is available at GitHub: https://github.com/rterp/GMapsFX
enter image description here

Once the dependency has been added, right click on the project in NetBeans and select “New” -> “Other”. Select the “Module Development” category and then select “Window” file type. This will create a new TopComponent class which will be used to host the map component.

 

enter image description here

Enter a prefix for the new TopComponent class.
enter image description here

Once this is finished a new GMapTopCompoent class will be created. The GoogleMapView component can then be added to this class in order to display the map.

Below is the code for the entire TopCompoment class including code in which I added the map component as well as a couple of map markers and an info window, all without having to interact with the underlying Google Maps JavaScript API.

package com.lynden.gmapsfx.module;

import com.lynden.gmapsfx.GoogleMapView;
import com.lynden.gmapsfx.MapComponentInitializedListener;
import com.lynden.gmapsfx.javascript.object.Animation;
import com.lynden.gmapsfx.javascript.object.GoogleMap;
import com.lynden.gmapsfx.javascript.object.InfoWindow;
import com.lynden.gmapsfx.javascript.object.InfoWindowOptions;
import com.lynden.gmapsfx.javascript.object.LatLong;
import com.lynden.gmapsfx.javascript.object.MapOptions;
import com.lynden.gmapsfx.javascript.object.MapTypeIdEnum;
import com.lynden.gmapsfx.javascript.object.Marker;
import com.lynden.gmapsfx.javascript.object.MarkerOptions;
import java.awt.BorderLayout;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.windows.TopComponent;
import org.openide.util.NbBundle.Messages;

/**
 * Top component which displays something.
 */
@ConvertAsProperties(
        dtd = "-//com.lynden.gmapsfx.module//GMap//EN",
        autostore = false
)
@TopComponent.Description(
        preferredID = "GMapTopComponent",
        //iconBase="SET/PATH/TO/ICON/HERE", 
        persistenceType = TopComponent.PERSISTENCE_ALWAYS
)
@TopComponent.Registration(mode = "editor", openAtStartup = true)
@ActionID(category = "Window", id = "com.lynden.gmapsfx.module.GMapTopComponent")
@ActionReference(path = "Menu/Window" /*, position = 333 */)
@TopComponent.OpenActionRegistration(
        displayName = "#CTL_GMapAction",
        preferredID = "GMapTopComponent"
)
@Messages({
    "CTL_GMapAction=GMap",
    "CTL_GMapTopComponent=GMap Window",
    "HINT_GMapTopComponent=This is a GMap window"
})


public final class GMapTopComponent extends TopComponent implements MapComponentInitializedListener {

    protected GoogleMapView mapComponent;
protected GoogleMap map;

public GMapTopComponent() {
    initComponents();
    setName(Bundle.CTL_GMapTopComponent());
    setToolTipText(Bundle.HINT_GMapTopComponent());
    setLayout(new BorderLayout());
    JFXPanel panel = new JFXPanel();
    Platform.setImplicitExit(false);

    Platform.runLater(() -> {
        mapComponent = new GoogleMapView();
        mapComponent.addMapInializedListener(this);
        BorderPane root = new BorderPane(mapComponent);
        Scene scene = new Scene(root);
        panel.setScene(scene);
    });

        add(panel, BorderLayout.CENTER);        

    }


  @Override
    public void mapInitialized() {
        //Once the map has been loaded by the Webview, initialize the map details.
        LatLong center = new LatLong(47.606189, -122.335842);



MapOptions options = new MapOptions();
        options.center(center)
                .mapMarker(true)
                .zoom(9)
                .overviewMapControl(false)
                .panControl(false)
                .rotateControl(false)
                .scaleControl(false)
                .streetViewControl(false)
                .zoomControl(false)
                .mapType(MapTypeIdEnum.ROADMAP);

        map = mapComponent.createMap(options);

        //Add a couple of markers to the map.
        MarkerOptions markerOptions = new MarkerOptions();
        LatLong markerLatLong = new LatLong(47.606189, -122.335842);
        markerOptions.position(markerLatLong)
                .title("My new Marker")
                .animation(Animation.DROP)
                .visible(true);

        Marker myMarker = new Marker(markerOptions);

        MarkerOptions markerOptions2 = new MarkerOptions();
        LatLong markerLatLong2 = new LatLong(47.906189, -122.335842);
        markerOptions2.position(markerLatLong2)
                .title("My new Marker")
                .visible(true);

        Marker myMarker2 = new Marker(markerOptions2);

        map.addMarker(myMarker);
        map.addMarker(myMarker2);

        //Add an info window to the Map.
        InfoWindowOptions infoOptions = new InfoWindowOptions();
        infoOptions.content("<h2>Center of the Universe</h2>")
                .position(center);

        InfoWindow window = new InfoWindow(infoOptions);
        window.open(map, myMarker);

    }    

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );
    }// </editor-fold>                        

    // Variables declaration - do not modify                     
    // End of variables declaration                   
    @Override
    public void componentOpened() {
        // TODO add custom code on component opening
    }

    @Override
    public void componentClosed() {
        // TODO add custom code on component closing
    }

    void writeProperties(java.util.Properties p) {
        // better to version settings since initial version as advocated at
        // http://wiki.apidesign.org/wiki/PropertyFiles
        p.setProperty("version", "1.0");
        // TODO store your settings
    }

    void readProperties(java.util.Properties p) {
        String version = p.getProperty("version");
        // TODO read your settings according to their version


       }
    }

What is important to note is that no map related classes can be instantiated until the GoogleMapView has been initialized. This is because the underlying JavaScript peer objects can’t be created until the JavaScript runtime has been initialized. The TopComponent is added as a MapComponentInitializedListener so that it can determine when it is safe to begin manipulating the map and its associated objects.

This module is now ready to be included as a dependency in a NetBeans application in development, or be added as a plug-in to an existing Netbeans RCP application at runtime, or even added to the IDE itself.

One word of caution: The underlying JavaFX WebView and Javascript runtime which the GoogleMapView component is making use of to render the map appears to be a memory hog. I have had to play with memory settings in order to avoid OutOfMemoryErrors, so something to keep in mind as you play with this.

Below is the final product of running the GMapsFX plug-in within a NetBeans RCP application.

enter image description here

The GMapsFX project is open source with the project home at GitHub as mentioned above and can be accessed at:
http://rterp.github.io/GMapsFX/

twitter: @RobTerp

My Interview with TechTarget.com on JavaFX, Swing, and the NetBeans Rich Client Platform

I sat down with Jan Stafford of Tech Target at JavaOne in September and discussed our experiences with beginning to migrate to JavaFX from Swing while continuing to use the NetBeans Rich Client Platform (RCP) as the foundation for our application.

I discuss some of the pros of using JavaFX and the NetBeans RCP, such as having the ability to develop very polished looking components using effects such as drop shadows, reflections, and gradients  which may have been do-able in Swing, but were extremely painful and time consuming.  These effects however are baked into the JavaFX framework.

The largest negative at this point has been the learning curve with getting up to speed on Cascading Style Sheets.  Since much of the look and feel of the UI can be applied via CSS, it took a bit of work to learn how to use the style sheets to properly style the UI components.  However, the benefit to using CSS is that the work can be given to a UX/UI developer rather than a Java developer, thus truly decoupling the UI development from the business logic development.

A link to the interview on Tech Target’s website is below.

Interview with Tech Target: JavaFX beats Swing: Changing RIA development platform

techTargetInterview

twitter: @RobTerp

2012 JavaOne Summary

It was quite a busy week last week at JavaOne in San Francisco, but it was one of the best JavaOnes I have attended to date despite the disappointing accommodations at the Powell Hotel (No A/C and bed bugs)  There were so many interesting sessions lined up that it was hard to choose which ones to attend.  I participated on a NetBeans discussion panel as part of NetBeans community day on Sunday before the conference started, and also in a similar panel discussion in a JavaOne general session on Thursday. Listed below are some of the highlights of the sessions that I attended.



JavaFX

If there was one thing that I learned from the sessions that I attended related to JavaFX, its that it will be the UI framework of choice moving forward for desktop and rich Internet applications.  Probably more than half the sessions I attended were related to JavaFX in one way or another.  Adding rich content to applications such as gradients, translucency, reflections, blurring, animated transitions, etc. that were possible, but very painful to do in Swing are baked into the JavaFX toolkit.

JavaFX UIs can be constructed using a WYSIWYG designer called Scene Builder which is available as a free download from Oracle’s website.  The tool supports drag and drop of the various JavaFX widgets onto a JavaFX scene.  Scene Builder then generates a .fxml file rather than a Java class, which I feel is the biggest downside to this tool.  The FXML can still be used within a Swing component however as I detailed in a previous post here.  NetBeans IDE can also be integrated with Scene Builder so that Scene Builder will launch when a .fxml file is clicked within the NetBeans IDE.  Below is a screenshot from Scene Builder.

image

Probably the most interesting session I attended last week was titled “Building JavaFX Interfaces for the Real World”.  The presenter (Simon Ritter) went through an example of developing a JavaFX application using the Microsoft Kinect and the OpenNI (Natural Interaction) library which is a Java API for communicating with the Kinect.  Ritter demoed a black jack card game written with JavaFX for which he used gestures to interact with the game.

Ritter also demoed an interface with NeuroSky, which is a USB EEG sensor for monitoring brain activity.  While it was interesting to see his brain activity plotted with JavaFX chart components and gauge components from Steel Series (located at the JFXtras website), he admitted there wasn’t much practical application for such an interface yet, although it highlighted where things are heading with the future of user interface design.

Here at Lynden we have begun work with designing a new user interface for our Freight Management System (FMS) application using JavaFX on the NetBeans Rich Client Platform, which will give us the best of both worlds.  JavaFX for a rich set of UI components, effects and animations and the NetBeans platform which will provide the underlying framework/plumbing for the application including windowing system, menu, tool bar, property sheets, etc.

Anyone interesting in kicking the tires of JavaFX can tryout the Ensemble application which highlights the various UI components, effects and transitions that are possible with JavaFX.  There are also open source JavaFX components that can be found at the JFXtras website located here, for which there is also a demo “Ensemble” application as well, highlighting the library’s components.


NetBeans Platform Logo

NetBeans Rich Client Platform (RCP)

The NetBeans RCP made a strong showing at this year’s JavaOne and is gaining momentum as a solid platform to design rich client applications on.  In fact, two Netbeans RCP applications won a Duke’s Choice Award this year.

The first application from NATO is called “MICE console” which stands for “MASE Integrated Console Environment” and is used to support the execution of air operations in a real-time environment.

The next application called “AgroSense” is an open-source platform for and by the agricultural sector.

Of particular interest this year was integrating JavaFX components within a Netbeans RCP application which I discussed during my demos for the panel discussions that I participated in.   I will be blogging about this further in the near future as we develop our FMS application at Lynden.  I’m also working on an automated trading application built on the NetBeans RCP as well, which I would like to incorporate JavaFX chart components as they seem to be far more polished than the current charts that are available through JFreeChart.


java neural network

Neuroph

java neural network

I also attended an interesting presentation by Zoran Sevarac regarding a neural network design tool that is written on the NetBeans RCP called Neuroph.  The application allows one to quickly design neural networks for such usages such as facial recognition, music classification, predicting poker hands, etc.  I will be researching this further to see if neural networks can be used to determine how to best handle the loading/unloading of trailers at our warehouses in order to optimize the time spent moving freight from the inbound trucks to the delivery trucks.  I would also like to investigate this in regards to trading stocks/futures/currencies, maybe not as a sole predictor of price movement, but used as aid in an existing trading strategy to help improve performance


Javeleon

Allan Gregersen presented on Javeleon which allows you to apply code changes in a running application immediately, without losing any of the application state. The result is that development time is cut down since the application doesn’t need to be shut down and restarted for every change that you would want to see.  We have been using Javeleon for a little over a year now in the development of our NetBeans RCP application and we are able to deploy individual modules to our app running on our development desktop without having to stop this application, thus greatly reducing the amount of time spent waiting to start up the application.

During the demo, Gregersen showed a numer of modifications to a space invaders application that were deployed while the application was running, and also while preserving the application state.

Javeleon supports Swing applications as well as NetBeans RCP applications and has announced support for Java applications servers such as Tomcat, Jetty, and JBoss as well.


Hazelcast

Distributed data made easy is what I walked away with from the Hazelcast presentation.  Hazelcast is a lightweight distributed Map (and more) that has a fairly small footprint, a single 1.7MB jar file with no dependencies.  There are also a number of other interesting distributed constructs in addition to maps such as, Queues, Sets, Lists, Locks, Semaphores, Topics, and Executor Services.  We will be investigating distributed caches at Lynden at some point for storing data for quick retrieval by our FMS client application.


Raspberry Pi Logo.svg

Raspberry Pi

Finally, I attended a very cool demo on the Raspberry Pi which is a small ARM Linux device designed for the teaching of basic computer science in schools.  The board is the size of a credit card and includes a 700MHz ARM processor and retails for $25.  There a number of articles on getting Java SE Embedded set up and running on the device, which can be found here.

RaspberryPi.jpg

twitter: @RobTerp
twitter: @LimitUpTrading