If you've ever had to build an application in JMP
that required visual elements, say, a Report window or a dialog box,
Application Builder is the tool that you want to use.
It will allow you to create that application
more quickly and more easily.
Additionally, it will let you create an application that's more compact,
that's easier to maintain, and more robust.
I'm going to assume that you're watching this
because you're interested in Application Builder,
but you also have a little bit of JSL background.
You may or may not have used Application Builder,
but you know a little bit about scripting in JMP.
Let's get started.
I've got two examples that I'd like to use to illustrate
some of the visual and programming characteristics
that might not be obvious or that might not be documented
for the Application Builder.
I am going to start with a very simple example
that I've actually attached to a menu here.
It's just a dialog box.
It's going to allow me
to navigate my directory structure either from a tree that I already have set
or I can pick a different directory.
Once I'm there,
I can look to see whether or not files of specific types are available,
select that file, and then open it up.
Now, one of the important aspects
of this particular example is that it doesn't involve a data table.
We're going to see in the second example how to deal with data tables,
when I want to incorporate data tables into my application.
It's a little bit trickier, so I'm saving that example for second.
Let me put this off to the side so we have something to reference.
Okay, so let's go ahead and get started with Application Builder.
Under Files, New, Application.
I will almost always start with this blank application.
Reason I do that is I can always get to any of those templates.
I could build any of those samples starting with this blank application.
Blank application is just going to give me
more flexibility in terms of where I want to go.
Now, if you're unfamiliar
with Application Builder, if you've never used it before,
the layout is relatively straightforward.
On the far left, we've got our source panel,
and in that source panel are all of the items that I'm going to use
to display information, to organize elements, and to do things,
things like buttons and checkboxes.
In the middle, I've got my palette where I actually build the visuals
of my application.
On the right, I have an Objects window that shows me
the tree structure of the item that I built.
I've got my Properties window
where I can select an item and change its properties.
That's one of the things that makes Application Builder faster to use,
is that I can go in there, I could select an item, select an object,
and change the properties interactively,
not having to worry about what the name of the message is
or writing up the code to make those changes.
Now, what I find is that I often use the same properties
when it comes to specific elements.
Things that typically have some sort of text element,
I like text of a certain size and a certain style.
Certain container boxes, I like to have borders around them.
Rather than drag and drop items into this palette and make changes,
what I often do is I will start with a template.
Here I've created a template that will allow me just to copy and paste
from the template into my palette.
For example, for my list box, I've changed the font on that list box,
changed the font size.
I'm just going to Control C to copy that.
I'm going to paste it into my new application.
The great thing about working from a template
is that it works for composite items as well.
In this case, I've got multiple items.
I have two button boxes that are stuck next to one another
using a horizontal list box, and then I've got a horizontal center box.
I can actually copy those,
Control C, copy those en masse, and paste those into my application.
Now, a couple of things about item selection.
If you work quite a bit with PowerPoint,
one of the things that you're going to find out
is that to select an item in Application Builder
is a little bit different.
Whereas in PowerPoint, you need to select the entire item,
with Application Builder, all you need to do is select part of that.
You'll notice that by selecting part of that horizontal center box,
the entire box is selected.
That makes items much easier to select
in the sense that all I need to do is grab part of the item
to select the entire item in entirety.
Now, I have a second option that's available to me as well.
That is, if I find an item hard to select,
I might have, let's say, a hierarchy of container boxes
and it's hard to get to the right box,
I might have tiny objects that are behind other objects
and it's just hard to grab onto.
I can always make my selection from my Objects panel as well.
Here, I'll select my Objects panel
and you'll notice that it selects the item in my palette.
The only drawback to this is that I can only select one item
from the Objects panel.
But again, it makes it very handy if that item is very hard to grab onto.
Let me move on to my next couple of items
I want to talk about.
To do that, what I'd like to do is move on to a partially built…
Here, I've partially built my application.
Here, I've got all the components.
I just need to group them.
That brings me to another piece of functionality
with an application builder that you might not be aware of.
Let's take these three items here.
What I want to do is I want to group them together horizontally.
You might think, "Well, to do that,
I'll take a horizontal list box, I will drop it into my pallette,
and then drop those items and position them in the palette."
When I am putting multiple items into a container,
I find it much easier to select those items,
right-click, and say Add Container.
By doing so,
I can apply the container to the items rather than the other way around.
One of the other advantages of having this functionality
is that if I were to, let's say…
While the container is still selected, right-click,
I can actually change the container.
Let's say, I don't want an H list box.
I want an outline box.
Maybe that H list box was better.
I can also change that container.
That works from the workspace,
and in addition, it works from the Objects panel.
You'll notice that if I right-click over the item in the Objects panel,
I can also change the container, I can add a container, and so on.
Now, in certain circumstances,
there is an additional piece of functionality,
and that is the ability to remove a container.
I can remove a container anytime it is not the lowest- level container.
For example, if I were to put this in another…
Let's add an outline box to that.
Now, what I can do…
Let me just move this so this is out of the way
of the other items.
Now that I've got that outline box
with a horizontal list box and then all my items,
I can't remove that horizontal list box because it's the lowest level,
but if I were to right-click on the Outline box, I can remove that.
Again, sometimes it's easier to just grab the items and apply the container box
to those items rather than dropping them into the container box.
Let me recap some of these tips that we talked about.
Again, I can organize that source panel items
by either grouping them or alphabetically.
I don't think I showed that,
but just let me point out that if you go onto the hotspot
of the Application B uilder, go to Source Panel.
If I were to change that group by column, they're in groups.
If I would prefer them alphabetically, I have that option available to me.
However you find it easier to recognize, to find those objects,
I can reorganize that source panel.
Work from a template to make things easier and faster,
not having to change properties for items that you always change.
Applying the container to the objects
rather than dropping the objects into the container is often much quicker.
The Object panel is there to do selection,
to add containers, remove containers, and so on.
Copy and paste works for a single item or for multiple items as well.
Okay.
Let me move into some of the scripting concepts.
To do that, I have my pre-built dialog box here.
I've got everything organized the way I want it to be organized.
I don't have any scripts associated with it.
Now there's a couple of things that I need to point out visually
that really are implemented
via the scripting, but they're important to know about.
Not every property from every item is available to change interactively.
For example, you'll notice that this list box,
I still have an item in it.
Well, what if I wanted to start that list box with absolutely no items?
As it turns out, interactively,
there's no way to get rid of that last item.
I've got to do that using a message.
Same thing goes for setting.
If I want to set this check box,
if I want to set the first selected item to be JMP files,
that has to be done through messaging.
That's not available interactively.
The place where I do that, I'm going to go to the scripting tab.
I've got namespaces.
I've got different options for application, my module.
We'll talk a little bit about the namespacing
in the next example.
But anytime I generate a module,
I'm going to have a different module container
for my script, and then I'm going to have one
for the overall application.
I'm going to go to the module,
and what I want to do is I want to set that list box to be empty
when it starts.
Let me go back and select that list box.
I see that the name that I'd given to that list box
is lbfiles.
I'm going to have to message that.
Now it's important to know
that when I message an object that is visible,
I can only do so after those objects are created.
That message has to appear after that line.
That is a line in which the visual items are instantiated.
After they're instantiated,
I'm going to say lbfiles, Set Items, and we're just going to leave it blank.
That's just basic JSL scripting
that you should know how to do or you should be familiar with.
Now, another important point is that, let's say at this point,
I want to test it to make sure that that is working properly.
When I run, when I debug a script,
I don't do it from my Edit menu, nor do I do it from my options
if I have a run or debug script available in my icons.
All the running and debugging has to happen from the hotspot.
I have two options here.
I've got the Run and Debug Application.
This is how applications are run and are debugged.
Great, I ran the application.
It looks like it's removed that initial item,
so things are good to go.
Now, let's talk about getting scripts
into things like button boxes or checkboxes.
What if I wanted to associate a script?
Let's start with this Cancel button.
One of the things that the Cancel button does
in the application is just dismisses the dialog box.
I've got two places where I can put that script.
I can put that script in the Scripts window
where we saw before where I had that initial setting of my list box.
Or, again, I'll select my Cancel button.
If I scroll into the properties down in the Properties panel,
I see this item.
I'm going to hover and you should see where it says Edit Script.
I've got this area where I can write my own script.
If I want a little bit larger area to work with,
like the Formula Editor,
I can click on this and I can write my script here.
I'm going to go ahead and do that.
We'll talk a little bit about the namespaces,
but what I need to know is that this is called thisM oduleI nstance,
and I have to use the message Get Box.
That'll return a link to the window that's created by the module,
and then Close Window.
That should work.
Whenever I use scripting in that fashion,
whenever I don't have a function name associated with a script,
if you go to the documentation,
it will be referred to as an anonymous script.
Again, if I want to, I might want to test that.
Let's go ahead and run the application.
I'll hit the Cancel button and that works.
That's one place I can put my script.
I had mentioned that I can also put the script in the Script tab.
Now, whether you put it in the Properties window or the Script tab
is really a personal preference.
I have a tendency to avoid the Properties window
simply because I forget that I put scripts in there
and I can't remember where a particular script is.
What I'm going to do now
is just Control C, I'm going to copy this item.
Let me just go ahead and clear this box out for now.
Anytime I want to create a script for any of the objects to do things,
quickest way for me to get that script into the Script tab
is to hover over it, right-click,
and you'll notice at the very bottom, there will be one or more selections.
Most of the objects within the Application B uilder
only do one thing: the Text Edit.
Number Edit Boxes do a couple of different things
and Mouse Box does a whole bunch of different stuff.
Here, I'll select the script I want,
and this is what happens when I press the button.
You'll notice that as soon as I do that, it's going to generate my function.
It's going to give me a little stub of a function.
It's going to give it a name
based on the variable name I gave the button,
and it's going to give me just a little fill-in for some code.
Here is where I would put the script that I showed you earlier.
Let me just paste that in there.
Okay.
Couple things to point out is that first,
the default argument of a link of a pointer to the object is supplied
when you generate a script this way.
You don't necessarily need it, but it's given to you by default.
Also, the default local is used,
which means that anything defined within the function
is local to that function.
If you want to change that, you need to get rid of the default local.
Again, let's go ahead and test this out.
That works as well.
Again, two options here in terms of where you can put that script.
You can either put the script in the Script window
or you can put the script in the Properties panel.
One final note about scripts in the Script tab
is that they don't have to appear after the objects are instantiated.
You can actually put them anywhere in the script.
You don't need to have the script available.
You don't need to have the objects available
before that function is created.
You can put that anywhere.
As a matter of fact, I often will separate all my functions.
I'll put those at the top of the script,
and then I'll put all my messages to objects
obviously below this object instance.
That's about all I wanted to cover with this particular example.
I want to move on to the second example.
In this example, I want to cover a couple of visual elements.
As I had mentioned, I want to talk to you about how you deal with data tables
when you have a table that you want to use.
I want to talk a little bit about tab boxes,
so when you have a tab display.
Some folks have a tendency of finding them a bit confusing.
So I want to talk about tab display.
Finally, I want to touch on two important scripting notes.
One is, how do I pass information from one module to another?
Often I will have one module,
like a dialog box that passes information to another dialog,
and another module, which is a Report window,
so I need to know how to do that.
I also need to know a little bit about the namespaces
that the Application B uilder generates.
Let me start with demonstrating what this example looks like.
In this example, you get a dialog box.
You'll notice that my Run button is grayed out
until I drop things into the list box on the right.
I'm going to go ahead and click Run.
Two JMP platforms are used.
The distribution platform is in the first tab
and the scatter plot matrix in the second tab.
Now, the beauty of the way this application was set up
is that it doesn't matter the data table that I use,
it doesn't matter the number of columns, which columns I pick, and so on.
If I were to rerun this,
different set of columns, different column names…
Let me just minimize that.
My computer is having
a little bit of problem redrawing the screen.
There we go.
It works.
It works regardless of the data table.
Let me go ahead and close that.
I am going to start with a fresh application
to illustrate some of the visual aspects.
I'm going to say New, A pplication.
Again, I'm going to start with a blank application.
What you'll see is that some of the items in that source panel are not available.
There are actually seven items
that are not available and only become available
when you open up a data table.
If I have an application that I'm generating,
and that application is going to be using a data table,
what I like to do is to start with something
from the sample data directory.
In this example, I mean, this is not from the sample data directory,
but what I would do if I were creating an application for general use
is that I would open something up from the sample data directory,
I would build my report,
and then I would use that as the basis for my application.
The reason I do that is that when I start dropping in
some of these items that require a data table—
in this case, I've got this column list box all—
you'll notice that it's going to add that data table to my application.
Now, with these types of applications,
I need something there, at least as a stand-in.
The advantage of having something from the sample data directory
is that it's unlikely to change names,
it's unlikely to change locations, and it's unlikely to be deleted.
It's a safe bet in terms of what data table to use.
You'll also notice that I can specify the path here.
I can give it a different label.
I don't have to start with the current data table,
but that is the default.
That's what I find that I use most often,
is I'm building an application that's for general use
that's going to be used on the current data table.
I'm going to go ahead and change.
I have a stock variable name that I use for that, so we'll change that.
That's the way I will typically start an application
that requires a data table.
Before I move into the scripting,
let me talk a little bit briefly about the tab boxes.
If we scroll up to the containers, we see we've got two different tab boxes.
We've got a tab box and a tab page box.
As it turns out, the only one I really need is the tab box.
If I were to drop that tab box in there,
and let me just to call out the tab box in my Objects panel,
and I were to drop any item in that tab box,
and let's just drop a border box in there,
you'll notice that it automatically generates
a tab page box.
I do not need to drop something in a tab page box
and then drop that tab page box into my tab box.
All I have to do is work with the tab box.
If I want to add tabs,
all I need to do is, again, select that tab box,
make sure I've got it selected here,
right-click, and I have the option to insert tabs
either before the currently selected tabs
or after the currently selected tab, or if I want to, I can also delete tabs.
Now, one of the questions I often hear as well.
I've got my tabs set up a certain way.
How do I move tabs from one space to another?
Currently, there's no interactive way to do it, unfortunately.
What you would have to do
is you would have to manually add a tab page
and move the contents of those tab pages around.
You might be tempted to save the script to a Script window
and change things that way,
but I often discourage folks from working with the saved script
or making alterations to the saved script just because there are a lot of elements
within that saved script that are not documented,
that are particular to the Application Builder.
I would stay away from making changes to that saved script.
Let's do this.
To talk about the scripting elements of my box,
I have pre-built an application.
Actually, before I move on, let me point out a couple of things
that occasionally will happen to folks
who wonder, "Well, why won't the display box work?"
One of the things, if you've had some experience with Application Builder,
one of the things you might have heard of is a parameterized application.
Let me go to pass number one.
I've got my dialog box built.
What I've done is I have opened up a Report window, a data table,
generated a couple of reports
and just dropped those reports into the blank area.
For example, what I did in this case was I had my cars data table opened up.
I had that distribution platform generated,
and all I did was drop that in and worked with the report.
Now, if I were to stop there and use that for my report,
what would happen…
Let me close out my items.
I've actually done that, and I've saved that here.
What would happen is that unless I use the data table I started with,
I will not get any results.
Here, I've got my air traffic.
I'm going to use that saved script.
Everything looks good so far.
I get nothing.
If I were to switch back to my cars
and try the same thing, and I'm going to grab different columns,
run, I get the same columns I started with.
The reason is, anytime I use a Report window,
if I want to change those columns that get used,
if I want to change the data table that gets used,
I have to use a parameterized version.
Let me go to the example of the parameterized version,
and I will point out the differences.
It's not that one.
My parameterized version is here.
Here's my parameterized version.
Dialog box looks the same.
My report looks slightly different
in the sense that if I were to select on the reports,
you'll notice in the very bottom,
I've got these roles, and these are filled out.
If I do the same thing with scatter plot,
select the report, my roles, that's filled out.
Now when I run the application, I can change the data table.
But in most circumstances,
I am fixed to the number of columns that I use when I built the application.
Let me show you an example of that.
Let me close this out.
Let's go with the air traffic data table.
Here's my second example, my parameterized example.
You'll notice that when I call up the dialog box,
I've got a space for the three columns that I initially used for distribution.
I've got a space for the columns I used for my scatter plot matrix,
but that's what I'm limited to.
As it turns out,
if I am dealing with platforms that come from the Multivariate menu,
then I can use a variable number of columns.
Anything else, I am fixed to the specific number of columns
that I used when I built the application.
Here's the workaround, here's the solution.
Let me do this.
I'm going to go back to my cars data table and open up my final example.
Again, dialog box looks the same.
Report does not have anything in it.
I just have placeholders to put my built application,
my built platforms.
Here's where the ideas of namespaces and passing variables
becomes very important.
When an application is created,
there are two different namespaces that you have to be aware of.
One is the thisA pplication namespace.
That is variables that get created that can be shared by any of the modules.
If we look in the Objects panel, I've got my applications here,
these three variable names, they are in the thisA pplication namespace.
Let me actually type that out.
The name of the variable is thisA pplication.
It's in that namespace.
The other namespace that I have to be aware of
occurs in each one of my modules.
Each one of my modules gets their own thisM odule Instance.
You've already seen this when we've instantiated objects
on the visual parts of the application.
I have got a thisA pplication and thisM oduleI nstance.
How do I pass data from one module to the other
to make sure things get done correctly?
Well, where we do it in this Application is in this spot right here.
Here I'm referencing that second module, that report module.
Let me also point out that I've got some options to change
whether or not it gets launched at start.
Obviously, I don't want this to be launched
until the user picks columns.
I've got my report module referenced.
I'm going to use Create Instance to create that Report window,
and I'm going to pass the items that were put in the list box this way.
Now on the report module side,
the business gets done in the OnM oduleL oad.
On OnM oduleL oad, everything defined within OnM odule
is local to the function.
What I need to do is I need to create a variable specific for the module
that's going to store that data that gets passed in.
I've done that right here.
A fter that, I'm just using somewhat standard JSL to be able
to generate my platforms using the platform calls.
Everything that you're seeing here, this is standard…
A bit on the complex side,
but standard JSL in order for me to do that.
One more thing I want to briefly explain
that you might have noticed that I know folks always ask about,
and that is if I go to, let's say, one of my modules,
there's a whole bunch of different module types
that I can pick from.
Dialog box is exactly what you'd think with no menu.
Dialog box with a menu is a window with a menu.
A modal dialog box is exactly that.
It's a modal dialog box.
A Report window.
The difference between a Report window and say, a dialog with a menu
is that you can save a report to a journal, a JRN file.
The other two items that are in there,
there is a Launcher item, which is internally different
than a dialog, but externally the same, more or less.
Then display box is used as a template to be embedded in other modules.
It does not generate its own window, but it's used to embed in other windows.
Probably a good place for me to stop.
Lots more to talk about.
As I mentioned, there'll be a PDF that you can download.
All of the examples that we saw, they'll be there.
There'll be some additional examples
and much more detail in terms of what I can explain.
Hopefully, you found this all helpful,
and hopefully, that'll motivate your want to use Application B uilder more often.
Thank you.