Rapid Business Modeling with a 
Java Graphical User Interface

Exploiting the Super Widget Package

David Bailey
http://www.dbaileyconsultancy.co.uk
and
Hans-Gerlach Woudboer, Rapid Business Modeling http://www.rapidbusinessmodeling.com/

Abstract

The  Rapid Business Modeling suite can create business models and perform customer profitability analysis and optimisation. This process uses the existing Business Modeling package together with a Java Graphical User Interface based on the Super Widget Package (SWP) to provide its interactive interface. Customer profitability analysis enables a company to gain an understanding of the drivers of individual customer profit, and to take practical and focused steps to improve overall performance. The underlying Business Modeling approach uses the concept of Activity Based Costing in a multi dimensional way.

This talk will give a brief outline of the concept of the Rapid Business Modeling suite and demonstrate how the SWP GUI interface unleashes the full potential of the Business Modeling suite for non-Mathematica users. The application runs in kernel-only mode (KOM) and therefore requires no notebook as a frontend. It has the expected look and feel of  a state of the art high performance management tool. 

However this is just one example of what is possible by bridging between the Mathematica world – mostly used in academia and research – and the business world. As a side features we demonstrate how easily it is to rapidly deploy new tailor made software applications for any kind of business.

The second half of the talk will focus on the GUI interface itself. Prior to version 6.0, the only way to create a GUI application using Mathematica was to use Java – directly or indirectly. Although version 6.0 contains many GUI elements, we demonstrate that a Java GUI  presents a much more industry-standard "look and feel" for applications, such as the Rapid Business Modeling suite.

The SWP itself has been enhanced in a variety of ways to provide the functionality for this application. It now uses J/Link rather than the GUIKit to provide the link to Java, for performance and stability.

The talk will emphasise those GUI features that are available via the SWP, but which are not part of the 6.0 frontend (or are not as well developed), such as the fast flexible Java tables, the multiple document interface (MDI), and multi-level menus that can be selectively enabled/disabled. 

Although end users of the Rapid Business Modeling suite  will, of course, require Mathematica on their machines, they will typically start the application like any other – by clicking on a Rapid Business Modeling suite icon. The talk will describe a variety of subtle issues related to this use of Mathematica in kernel only mode.

Rapid Business Modeling Outline

Business Models

Value Proposition

Labeled Arrays

Java Tables

Stand-alone Java Application

Super Widget Outline

Business Models

Value Proposition

Build a comprehensive business model for your company,

Analyze your business performance from a range of perspectives,

Build detailed performance profiles for each customer or product,

Segment your customers by profitability, cost-to-serve, or cluster analysis,

Improve your overall customer profitability by running a potentializer,

Improve your bottom line by 3-6 Million per 100 Million revenue.

Labeled Arrays

LabeledArray is a new expression in Mathematica that preserves the integrity of data values and their syntax given by descriptive index labels. LabeledArray facilitates the handling of large and possible inconsistent data sets of arbitrary rank.

Load Add-On

Needs["BusinessModeling`"]

Import Data

Import a simple 1-dimensional cost vector.

expenses=ImportLabeledArray["Expenses.csv"]

expenses=ImportLabeledArray["Expenses.xls"]

Built Driver: Expenses to Activities

Build a driver that projects the expenses onto the activities. To conserve the overall expenses, the driver has to be normalized.

expenses2activities = Normalize[({{, "Activities", "Production", "Sales", "Shipping", "Support"}, {"Expenses", ⬚, , , , }, {"Facilites", , 60, 20, 0, 10}, {"Human Resource", , 20, 60, 100, 0}, {"Raw Materials", , 5, 10, 0, 80}, {"Services", , 15, 10, 0, 10}}),"Activities"]

Multiplying the driver on the cost vector.

expenses2activities expenses

Sum over all Expenses to obtain the total costs for each activity.

Contract[expenses2activities expenses, "Expenses"]//N//AccountingForm

Built Driver:  Activities to Products

Build the driver to map activites onto products.

activities2products=Normalize[({{, "Activities", "Production", "Sales", "Shipping", "Support"}, {"Products", ⬚, , , , }, {"Laptop", , 30, 5, 2, 10}, {"Desktop", , 40, 5, 1, 10}, {"Keyboard", , 15, 2, 1, 5}, {"Mouse", , 15, 2, 1, 6}}),"Products"]

Generate Model

Generate a business model by applying both drivers on the cost vector.

(model =N[ activities2products expenses2activities expenses])//AccountingForm

The following costs occur for each product.

Contract[model, {"Expenses","Activities"}]//AccountingForm

Java Tables

JavaTables is a Java - based function that helps to scroll through large data sets with ease.

Needs["SuperWidgetPackage`"]

Needs["BusinessModeling`GadgetsAndAliases`"]

Needs["BusinessModeling`GUISupport`"]

JavaTable[model]

Whale Curve

WhaleCurve is one of the analyzing functions in the BusinessModeling add - on. It generate a cume of the profit and displays it
as a so-called whale curve. In the following case the curve helps to identify the customers that contribute a lot and a little to the profit, and
those to inflict a loss.

profit=({{"Customer", ⬚, }, {"c1", , 20}, {"c2", , 10}, {"c3", , 60}, {"c4", , -30}, {"c5", , -10}, {"c6", , 0}, {"c7", , 25}, {"c8", , 5}}); volume = ({{"Customer", ⬚, }, {"c1", , 100}, {"c2", , 120}, {"c3", , 60}, {"c4", , 40}, {"c5", , 90}, {"c6", , 200}, {"c7", , 10}, {"c8", , 20}});

WhaleCurve[profit,volume]

The Super Widget Concept (1)

•  The super widgets are very similar in concept to the new control objects (InputField, Slider, etc.) that were introduced at 6.0 – but they are used to create a Java GUI, not tied to the notebook frontend. For example:

SuperWidgetButton[bb,"OK",1]

SuperWidgetIntegerBox[xx]

SuperWidgetRealBox[xx]

SuperWidgetTree[tr]

•  All super widgets have the HoldFirst attribute, and transfer data to and from their first argument automatically (without the use of Dynamic).

•  There are plenty of options to control the super widgets, but often the defaults are adequate.

•  Notice that many super widgets offer facilities that exceed those available using Mathematica 6 in notebook form – they can tap directly into the richness of Java!

A window will contain several super widgets, grouped together with layout information in a structure which is somewhat analogous to a Graphics object – i.e. it does not evaluate directly. It is interpreted by the SuperGUIRunModal and SuperGUIRun functions:

{(Subscript[¶, 10]),
{(Subscript[¶, 0]),"Hello World from",(Subscript[¶, 0])},
(Subscript[¶, 10]),
{(Subscript[¶, 0]),"The SWP!",(Subscript[¶, 0])},
(Subscript[¶, 10]),
{(Subscript[¶, 0]),SuperWidgetButton[Null,"OK",1],(Subscript[¶, 0])},
(Subscript[¶, 10])}//SuperGUIRunModal

The Super Widget Concept (2)

There are super widgets availalable for almost all aspects of GUIs, including:

•  Input of integers, reals (including support for exponents), and strings.

•  Input of real numbers as decimals (e.g. for currency).

•  Labels of various kinds – text, images, and even animated images.

•  Text or image buttons with special simple syntax for buttons that close a window and return a result.

•  Radio buttons and checkboxes

•  Horizontal and vertical sliders with zooming capability.

•  Extensive graphics support.

•  Scrollable trees and tables.

•  Full support for menus, with mnemonics, keyboard accelerators, and images.

•  The multiple document interface

•  Modal and modeless windows. Modal windows can spawn additional modal windows as deeply as required.

Java tables

•  Java tables are particularly powerful because they can handle large quantities of data. As an example, here is a display of some IsotopeData:

ll=IsotopeData[];
info=Map[{#,IsotopeData[#,"AtomicNumber"],IsotopeData[#,"AtomicMass"],IsotopeData[#,"HalfLife"]}&,ll]/.{Missing[_]->"–",∞->"∞"};

Short[info]

ll//Length

SuperGUIRunModal[SuperWidgetTable[info,Pixel˘Width->600,Table˘Headings->{"Name","Atomic number","Atomic mass","Half life (secs)"}]]

•  Much larger data sets can be displayed (and also edited!) – something which does not seem practical to achieve with notebooks.

•  Multiple items can be selected from tables, and used to drive arbitrary processes – exploited in the Rapid Business Modeling application.

•  Each cell (not just each column) can contain a different data type – Integer, Real, String, boolean, or image, and the colour of the cell can be adjusted dynamically.

•  Real numbers can also be displayed with a fixed number of decimal places (right justified) – useful, for example, for currency.

Java multiple document interface (MDI)

Open Word for Windows or Paint Shop Pro, or any one of a variety of other applications, and you will be presented with a Multiple Document Interface (MDI). The idea is that you are presented with a back window – usually containing menus and tool bars – on which the user opens documents in other windows. Everything is contrained to lie within the back window, and if you minimise that window, everything else disapears too.

The space that is to be used to host child windows is defined by a SuperWidgetDesktop:

doc˘no=0;
New˘Document[]:=Module[{fr,str},
doc˘no++;
str=FromCharacterCode[Table[Random[Integer,{65,90}],{10}]];
SuperWidgetFrame[fr,{
SuperWidgetTextEditor[str]
},Desktop->ddd,Title->"Example "<>ToString[doc˘no]]//SuperGUIRun
];


SuperGUIRunModal[SuperWidgetFrame[Null,{
SuperWidgetDesktop[ddd,{
Image˘File[SuperWidgetPackagePath[]<>"\\ExampleFiles\\Consultancy.gif"]
},Background->RGBColor[1.0,1.0,0.7],Pixel˘Width->300,Pixel˘Height->200]
},Menu->{{"File",{{"New",New˘Document}}}}]]

Although in this example windows are opened with random text, in a real application they might contain a Java table, or the contents of a file. Notice that the underlying application must be able to deal with a varying number of open windows. Note that in this example, the control variables, fr and str, associated with the child windows are local to the module – because all active control variables must be unique.

GUI with a memory

Almost all GUI applications (including the Mathematica frontend itself) have a memory. In other words, they retain information such as where you last went to fetch a data file, or what size you like your window to be. Although it would be possible to program this functionality into a GUI from scratch, the SWP makes this much easier. First, before you do much else, you tell the SWP the name of the file that will provide the memory:

Set˘Application˘Dump˘File["myApplication"]

This file will be located in $UserBaseDirectory (unless a complete path is used), and if it exists, it will be read to provide initial data (from the last time the program was run).

The Open˘File˘Dialog and Save˘File˘Dialog SWP routines always use this mechanism to store the directory that the user last used to open files. On a well-used PC with a large directory structure, this can be save a lot of time. Future versions of the SWP may store additional variables in this file, but the user also has the option to store arbitrary variables in the same way:

Add˘Application˘Variable[someVariable]

The first time this function is called, it sets up the information to store the variable. The value of the variable is then carried from one run  of the application to the next.

It is good to ensure that the latest information is stored prior to shutting down the GUI (however, certain other events also cause the data to be written back to the file):

Save˘Application˘Dump˘File[]

A common problem is that it is possible to close an application in such a state that it will not re-open cleanly – which can be very troublesome. For this reason, it is best to validate all user variables  after calling Set˘Application˘Dump˘File. For example, if you store window dimensions, and restore the window to the same dimensions on the next run, it makes sense to check first that these have reasonable values.

Java look and feel

The Java GUI system adopts the style of the platform on which it sits. This means that, unlike a Mathematica notebook, all the controls will look appropriate for, for example, Windows, if on a Windows platform. They will also have standard keyboard/mouse functionality. This is perhaps best seen by looking at a window with menus:

txt="The quick brown fox";
f˘new[]:=Print["New"];
f˘open[]:=Print["Open"];
f˘exit[]:=Print["Exit"];
f˘lev2[]:=Print["Level 2"];
SuperWidgetFrame[fr,{
SuperWidgetTextEditor[txt,Pixel˘Width->500,Pixel˘Height->350]},
Menu->{{"&File",{{"&New",f˘new},{"&Open",f˘open},{"E&xit",f˘exit,"Ctrl-Q"}}},
{"Test",{{"Level 1",{{"Level 2",f˘lev2}}}}}}]//SuperGUIRunModal

This example illustrates several things:

•  The menu can be operated with the mouse, or via keyboard mnemonics (identified with the '&' character), or with accelerator keys.

•  The menus can be multi-level. Remember that a serious application may well have as many menu items as Mathematica itself, and these absolutely must be nested to be useful.

•  Because the GUI is not displayed within the notebook, there are no glitches associated with the use of Print commands.

Working in Kernel only mode(1)

•  The notebook frontend is very friendly to most of us. However, it is specialised towards the needs of mathematicians and serious maths users – as even its name betrays – and for applications that are designed for a different audience, it can seem very unfriendly. Once the decision has been made to use a Java GUI, it is probably best to hide the notebook frontend completely – at least from the final product.

•  Executing the kernel directly can be done with one of the following commands (with changes to the path as required).

"C:\Program Files\Wolfram Research\Mathematica\6.0\Math"

or

"C:\Program Files\Wolfram Research\Mathematica\6.0\MathKernel"

The first command will start a console-based Mathematica session (which will bring back memories for long term Mathematica developers), while the second will produce a window-based session, but with essentially the same interface.

At this point nothing has been gained – we have simply swapped the notebook interface for a much more primitive one! To be useful, it is necessary to suppress the visible interaction altogether and execute a program that first becomes visible when it displays its Java GUI.

•  Both the above commands display subtle complications – at least under Windows. Perhaps the most obvious initial approach is to use MathKernel thus:

"C:\Program Files\Wolfram Research\Mathematica\6.0\MathKernel" -mathlink  -initfile program.m

This uses the given program file as 'initialisation', and it seemed reasonable to assume that the entire program could be executed in this way. The '-mathlink' option suppresses the window so that the first visible effect of this command is to display a Java GUI. At first, this command seems to work well – indeed, I displayed a SWP-based GUI in this way at last year's conference! However, it turns out that Mathematica exhibits some curious bugs when started in this way which plague both SWP and GUIKit code. (There is also a '-run' option to this command, but this generated the same problems. Curiously, starting the program from the interactive window does work, but is obviously impossibly clumsy.

The Math command (as opposed to MathKernel) has its own problem. Under Windows, since it is a command-mode application, it opens a new console if it is started from a GUI context – e.g. by using a shortcut on the desktop.

•  While the exact circumstances that provoke these problems are obscure, I eventually developed a satisfactory solution using the Math command. I created a small C program that used the WIN32 API to start Math.EXE with the desired program as an input pipe, and an option to make the newly created console invisible. As a bonus, this command can have its own desktop icon – in this case relating to the Rapid Business Modeling application. I have called this C program MathLauncher. Although MathLauncher is written specifically for Windows, it would be very easy to create equivalent code for Linux, and presumably for other platforms.

This gives us an application that looks and feels exactly like any other application, with no extraneous Mathematica menu, and no empty notebook on startup.

Working in Kernel only mode(2)

•  This leaves one other logistical problem – it would seem we have hard coded the Mathematica path into the MathLauncher program! In fact, under Windows, this is not necessary because this information is available in a registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MathematicaNB\shell\open\command

The Windows version of the MathLauncher program accesses this variable

•  A normal free-standing GUI also has a memory.

•  Typically, when a SWP program completes Math.EXE will try to read the next command from the input file. Unfortunately, when it reaches the end of the file, it does not terminate because it 'thinks' that it is reading from a terminal and that more input will be typed. Kernels stalled in this way quickly use up the usual allocation of just two active kernels at any one time. For this reason, it is advisable to end the .m file with Quit[], and also include this command in any code which terminates the Java GUI. The SWP provides a useful alternative to Quit – ExitGUIProgram[]. This will close all open GUI windows and perform a Quit[] if in KOM. Thus by using this function, you do not lose the kernel while testing your code with a FrontEnd attached.

•  The MathLauncher command can also take two options for debugging purposes. The '/verbose' option will cause the program to print out the command that it is about to use to launch Mathematica. The '/visible' option makes the associated console window visible rather than hidden. This can be very useful for reading diagnostic messages etc.

•  Developing in KOM does have drawbacks, however. It is often best to develop code from within a notebook (or opening a .m file as if it were a notebook) and test in KOM mode from time to time.

Conclusion

Using the Super Widget Package, it is possible to create an industrial strength GUI by accessing Java. The concepts behind the SWP are not too dissimilar to the GUI concepts of Mathematica 6 – making it very easy to use. Although the SWP does not access all Java GUI features, it can be extended much more rapidly than Mathematica – essentially as required by particular users.