JMP has a friendly point-and-click interface, and the scripting language in JMP, JSL, can be used to create some of your own. I did a lot of display box manipulation when building my JMP add-in, the JMP to R Custom Add-In Builder. Using display box commands to create a custom user interface (UI) can be challenging for new JMP scripters, so I put together a series of examples that have the main components of a JMP interface you might want to create.
In addition to the case study here, you might find the JMP display box documentation on common display box organization and an advanced example (search “Advanced Example”) with interactive display elements helpful, as well as the resources I detail in another blog post, Display Box Construction 101.
The two main types of organizations for UI display boxes are V List Box() and H List Box(). V List Box will glue components together vertically, while H List Box will glue components together horizontally. You can nest V and H List Boxes to create the exact organization of elements that you need. For example, if you wanted to create this simple window:
Example 1: A simple UI
You will need to use both V and H List Boxes to hold the components you use (Check Box, Panel Box, Radio Box). Use a V List Box, as your components are all ordered vertically, to create the overall display.
Then, within the vertically aligned items, use H List Boxes to hold the items that need to be organized horizontally — for example, the A, B, and C Check Boxes. Repeat this with all of your components, including the Panel Box that holds Radio Boxes within it.
The script for this example is below:
New Window("Letters",
V List Box(Align(center),
H List Box(
Spacer Box(Size(10, 15)),
Text Box("Select all of the letters your heart desires."),
Spacer Box(Size(10, 10))
),
Spacer Box(Size(20, 10)),
H List Box(
Check Box("A"),
Check Box("B"),
Check Box("C")
),
Spacer Box(Size(20, 10)),
Panel Box("Select some more...",
Radio Box({"D", "E", "F", "G", "H"})
),
Spacer Box(Size(20, 10)),
H List Box(Align(center),
Check Box("I"),
Check Box("J"),
Check Box("K")
),
Spacer Box(Size(10, 10))
);
);
But what if you want more? The same goes if you want to create a more intricate combination of nested vertical and horizontal displays, as in this UI:
Example 2: Even more nested V and H List Boxes
The corresponding JSL for this UI is:
New Window("Letters 2.0",
V List Box(Align(center),
H List Box(
Spacer Box(Size(10, 15)),
Text Box("Select all of the letters your heart desires."),
Spacer Box(Size(10, 10))
),
Spacer Box(Size(20, 10)),
H List Box(
Check Box("A"),
Spacer Box(Size(10, 10)),
Check Box("B"),
Spacer Box(Size(10, 10)),
Check Box("C")
),
Spacer Box(Size(20, 10)),
H List Box(
Spacer Box(Size(20, 10)),
Panel Box("Select some more...",
Radio Box({"D", "E", "F", "G", "H"})
),
Panel Box("And another...",
Radio Box({"I", "J", "K", "L", "M"})
),
Spacer Box(Size(10, 10)),
V List Box(
Spacer Box(Size(10, 1)),
Text Box("What are your favorite letters?"),
Spacer Box(Size(10, 10)),
Text Edit Box("add your own"),
Spacer Box(Size(10, 10)),
Text Edit Box("add your own"),
Spacer Box(Size(10, 10)),
Text Edit Box("add your own"),
),
Spacer Box(Size(20, 10)),
),
Spacer Box(Size(20, 20)),
H List Box(
Spacer Box(Size(10, 15)),
Text Box("Which of these SAS Cary buildings is your favorite?"),
Spacer Box(Size(10, 10))
),
Spacer Box(Size(20, 10)),
H List Box(Align(center),
Check Box("S"),
Spacer Box(Size(10, 10)),
Check Box("T"),
Spacer Box(Size(10, 10)),
Check Box("U")
),
Spacer Box(Size(10, 10))
);
);
Notice how, for visual appeal, I add Spacer Boxes around the edges of display boxes to pad them.
But what about data tables, column selects, and column lists, you ask? You may want to create a useful column selection dialog with some other elements, like Check Boxes, thrown in:
Example 3: Using Col List Boxes
The principle behind this display is the same. Continue using V and H List Boxes to contain your items.
The new type of component seen here is the Col List Box, which contains the names of all the columns of a given data table if you set the first parameter of the Col List Box to All, as in the code below for the first Col List Box, which is housed in the first Panel Box: colListData=ColListBox(All,nLines(min(nc,10))).
To group the buttons and column selection boxes together, use a Line Up Box to align all the elements in two columns.
//the data table you want to operate on
dt = Open( "$SAMPLE_DATA/Birth Death.JMP", invisible(1) );
//number of columns in the data table
nc = ncol(dt);
//list of methods that will be used for the dropdown menu for "Method"
methodList = {"Average","Centroid","Ward","Single","Complete"};
clusterDlg = New Window("Column Selector",/*uncomment if you want a modal window: <<Modal*/,
BorderBox(left(3),top(2),
VListBox(
TextBox("This UI likes columns more than letters."),
HListBox(
VListBox(
PanelBox("Select Columns",
colListData=ColListBox(All,nLines(min(nc,10)))
),
Check Box("Interpolate Missing Values")
),
PanelBox("Cast Selected Columns into Roles",
LineupBox(NCol(2),Spacing(3),
ButtonBox("Y, Columns", colListY<<Append(colListData<<GetSelected)),
colListY = ColListBox(nLines(5),"numeric"),
ButtonBox("Ordering", colListO<<Append(colListData<<GetSelected)),
colListO = ColListBox(nLines(1),"numeric"),
ButtonBox("Label", colListL<<Append(colListData<<GetSelected)),
colListL = ColListBox(nLines(1)),
ButtonBox("By", colListB<<Append(colListData<<GetSelected)),
colListB = ColListBox(nLines(1))
)
)
)
)
)
);
As a recap thus far, I’ve listed some common components you’ll find yourself needing and their corresponding properties. The comprehensive list of element types and their properties is here.
b = Button Box("text", <script>);
numbox = Number Edit Box(initialValue, <width>));
cb = Check Box ({“item 1”, “item 2”, ...}, <script>);
clb = Col List Box (<Data Table (<name>), <All>, <width(n)>,
<maxSelected(n)>, <nlines(n)>, <script>, <MaxItems(n)),<MinItems(n)>, <character | numeric>, <onChange(expression)>);
comboBox = Combo Box({“item 1”, “item 2”, ...}, <script>); //this is a dropdown menu
h = H List Box(<displaybox args>);
lb = Line Up Box (NCol(nc), <Spacing(pixels)>, displaybox args);
pb = Panel Box (“title”, <displaybox args>);
rb = Radio Box({“item 1”, “item 2”, ...}, <script>);
t = Text Box(“text”);
teb = Text Edit Box (“text”, Hint(“text”));
v = V List Box(<displaybox args>);
Now, we are ready to build a more complex UI.
The script below, which I have annotated (adapted from the example here), creates the following JMP UI and functional program for the Clustering function.
Note that the previous UI examples were not executable, as we were just learning how to build the interfaces. You may have also noticed that the second argument in the Button Box() function was not used. Here, when you click the “OK” button, a script executes. The particular script implemented here is the code for the JMP Clustering function. See the example code to see the function’s script.
Example 4: The Clustering function
//the data table you want to operate on
dt = Open( "$SAMPLE_DATA/Birth Death.JMP", invisible(1) );
//number of columns in the data table
nc = ncol(dt);
//the width of the column list box in pixels
lbWidth = 108;
//list of methods that will be used for the dropdown menu for "Method"
methodList = {"Average","Centroid","Ward","Single","Complete"};
//what happens upon clicking "Recall" or "Help" buttons
notImplemented = expr(New Window("Feature Not Implemented Yet!",<<Modal, ButtonBox("OK")));
//opens new window called "Clustering" that houses all the function display boxes
clusterDlg = New Window("Clustering",/*uncomment if you want a modal window: <<Modal*/,
BorderBox(left(3),top(2),
//V List Boxes organize elements vertically, from top to bottom
VListBox(
TextBox("Finding points that are close, have similar values"),
//H List Boxes organize elements horizontally, from left to right
HListBox(
VListBox(
//Column Selection Box
PanelBox("Select Columns",
colListData=ColListBox(All,width(lbWidth),nLines(min(nc,10)))),
//Options Box
PanelBox("Options",VListBox(
//Dropdown with two choices and defaulted to first choice
comboObj=comboBox({"Hierarchical","K-Means"},<<Set(1)),
//Radio Box with five choices and defaulted to third choice
PanelBox("Method",
methodObj=RadioBox(methodList,<<Set(3))
),
//Check Box defaulted to checked state
checkObj=check box({"Standardize Data"},<<Set(1,1))
)
)
),
//Column Select Boxes Y, Ordering, Label, and By and respective action buttons
PanelBox("Cast Selected Columns into Roles",
LineupBox(NCol(2),Spacing(3),
//Y, Columns Button and Column List Box with 5 lines, type numeric
ButtonBox("Y, Columns", colListY<<Append(colListData<<GetSelected)),
colListY = ColListBox(width(lbWidth),nLines(5),"numeric"),
//Ordering Button and Column List Box with 1 line, type numeric
ButtonBox("Ordering", colListO<<Append(colListData<<GetSelected)),
colListO = ColListBox(width(lbWidth),nLines(1),"numeric"),
ButtonBox("Label", colListL<<Append(colListData<<GetSelected)),
colListL = ColListBox(width(lbWidth),nLines(1)),
ButtonBox("By", colListB<<Append(colListData<<GetSelected)),
colListB = ColListBox(width(lbWidth),nLines(1))
)
),
//Actions menu
PanelBox("Action",
LineupBox(NCol(1),
//OK Button
ButtonBox("OK",
//script that executes upon clicking "OK"
if ((comboObj<<Get)==1,
HierarchicalCluster(
Y(Eval(colListY<<GetItems)),
Order(Eval(colListO<<GetItems)),
Label(Eval(colListL<<GetItems)),
By(Eval(colListB<<GetItems)),
Method(methodList[methodObj<<Get]),
Standardize(checkObj<<get(1))
),
KMeansCluster(
Y(colListY<<GetItems)
)
);
clusterDlg<<CloseWindow
),
//Cancel Button
ButtonBox("Cancel", clusterDlg<<CloseWindow),
TextBox(" "),
//Remove Button
ButtonBox("Remove",
colListY<<RemoveSelected;
colListO<<RemoveSelected;
colListL<<RemoveSelected;
colListB<<RemoveSelected;
),
//Recall and Help not implemented here, buttons are shown in UI
ButtonBox("Recall",notImplemented),
ButtonBox("Help",notImplemented))
)
)
)
)
);
I hope this tutorial will be useful for JMP users who have wanted to build their UIs to execute scripts, but didn't know where to start. Have you built your own UI in JMP? I’d love to hear your thoughts in the comments.