public interface BalsamiqImport
There are two ways to use Reify:
Component XML
. In
Visual Builder, you
can copy and paste the XML from the "Code" tab; with the standalone tool you can press the
"Show Source" button and copy and paste from there.
When using the standalone tool and running the server on your own machine, when you use the "Select file.." option to import a mockup from a file on disk, this tool will periodically re-import the mockup, so you can work in Balsamiq and the browser will periodically refresh, showing the Smart GWT version updated to reflect your latest changes.
Both tools can also save to a file under webroot. In Visual Builder, use File->Save As. In the standalone tool, use the "Output File" text field in the initial dialog. This is most useful if you are using an "exploded" deployment . If you are using the Eclipse IDE with the built-in Jetty server, saving under webroot may not be useful since it means saving to a generated "deployment directory", not your Eclipse project. In this case copy and paste is the best way to grab the generated source code.
For both tools, you can add the URL parameter "mockup" to cause your mockup to be immediately imported as the tool starts up:
tools/bmmlImporter.jsp?mockup=myMockup.bmmlThis makes your imported mockup into something you can bookmark.
For the standalone tool, you can also add the URL parameter "outputFile" to specify where the generated XML source should be saved. This makes the entire import & save process bookmarkable, but again is most valuable in an "exploded" deployment.
The next sections explain how Reify works, and how to tweak your Balsamiq mockup to produce the best results, then the section "From imported mockup to application" explains how to turn your generated Smart GWT code into a working application.
Most Balsamiq mockup elements have a direct Smart GWT equivalent - what Balsamiq calls a "Tabs Bar" is translated to a Smart GWT TabSet component, a Balsamiq "Accordion" is translated to a Smart GWT SectionStack, and so on. However, rather than only translate elements 1-to-1, Reify uses heuristics to try to organize your components into layout managers and logical forms, as follows.
Balsamiq mockups have no true notion of containers - to put something "in" a container in Balsamiq, you just make sure it visually appears inside of the container - you never assign it as a child of the container. If Reify did the same thing, the resulting code wouldn't be very useful because the screen would become jumbled if anything was resized. Instead, Reify detects that you have placed something inside the visual area of a container and automatically creates a true container relationship in Smart GWT. A grid inside of a Window really will be inside that Window in Smart GWT, and will move with the window if it is dragged.
It's also OK to be inexact. If you look at a typical Balsamiq mockup, if an element doesn't have a visible right/bottom border its very common that its logical extents go outside of it's container. Reify automatically recognizes such elements as contained anyway. If something is sticking very far out of its container and Reify didn't realize it was meant to be contained, just fix the size in your mockup, and re-run import.
Reify will also recognize extra controls in the header area of a container. For
example, just placing buttons or icons in a Window's header area will lead to
headerControls
being created,
similarly, placing controls in an Accordion's
section will lead to controls
being created.
Reify recognizes when you have stacked together several things of the same approximate size and assumes they go together. It's OK to be inexact - Reify will ignore small differences in size and alignment and still realize that several items are meant to end up in a Layout. If there are two or more possibilities for how elements can be arranged into Layouts, Reify will generally pick the option that results in the simplest overall layout.
By default, Reify assumes your mockup isn't really meant to be fixed size - whatever container it's placed into, whether that's the whole browser or something smaller, your design is actually intended to fill it.
To achieve this, Reify defaults to ignoring any blank space that appears around the outside of the your mockup (ignoring markup elements - see below). Then, Reify tries to find a way to allow your design to "flex" by finding elements that can use more space: grids, text areas, accordions, etc. These elements are given flexible size and layout settings are applied to all of their parents such that resizing the mockup as a whole will give available space to the components that can use it.
To get the best results from this system, pay close attention to whether or not you are filling containers - Reify will only assume that a given component would like more space if it is already taking up as much space as possible in the mockup. For example, if you have a grid as the sole member of a tab, but the grid only fills half the tab, Reify will assume the grid should be fixed size rather than fill the tab.
If you really want the entire mockup to be exactly the sizes you specified, this fluid layout behavior is one of the things you can turn off right in the import dialog: uncheck "Fill Space" if the design should not be made into a fluid layout, and uncheck "Trim Space" if you meant the empty space around the mockup to be taken literally.
Elements such as Sticky Notes are considered "markup" and are dropped by default since it's assumed you don't want them now that you are moving on to creating your real application. You can retain them if you'd like by unchecking "Drop Markup" in the importer dialog.
Also, if you right-click on a component in Balsamiq (or option-click on MacOS), the menu item "Treat as Markup" allows you to convert a normal component into markup, which gives you a way to have Reify ignore selected components.
Balsamiq supports linking multiple mockups together to create basic interactivity for guided walkthroughs of multi-screen mockups. Reify understands that certain types of Balsamiq links and can create a combined appliction from several linked mockups, with the interactivity you would expect.
However, linking only works when mockups are loaded via the "Select file.." option and exist on disk at correct relative paths (the same relative locations where Balsamiq stores them); linking cannot be used with mockups that are uploaded using the web interface.
A common idiom used in Balsamiq to create the illusion of functioning tabs is to create a link on a tab that points to another mockup which is exactly the same except for the selected tab and contents of the tab pane. Reify will recognize this idiom and take the contents of the selected tab from the linked mockup and place it in the same-named tab from the primary mockup. As intended, the contents will be initially hidden since the tab will not be initially selected, and will be revealed when an end user clicks on the tab. All other content from the linked mockup is ignored.
Unlike other aspects of Reify that compensate for small differences, here it is required that the two mockups be exactly the same except for the selected tab and tab contents. The only elements that can differ are "markup" elements such as Sticky Notes.
Similar to the idiom for multiple tabs, links on Accordion components are sometimes used to point to mockups that are identical except for the expanded Accordion section. Reify will recognize this idiom in the same way as for tabs, and create a SectionStack where the contents of the visible Accordion section from the linked mockup appear in an initially collapsed section in the imported application.
A link on an element such as a button that leads to a second mockup will, by default, cause both the primary and linked mockup to be imported with all of their components, and an event handler will be generated on the button that simply hides all the components of the primary mockup and shows all the components of the linked mockup.
If this is not correct (perhaps the linked mockup is really intended to be the same screen, with various changes caused by the button), simply remove the link before importing. You can then add event handling logic to implement the intended effect of the button. You can also separately import the linked mockup and load it as an additional screen - see the follow sections on going from imported mockup to full applications.
Balsamiq has a concept of symbols, which are reusable elements that can be incorporated into multiple mockups. Reify supports symbols, however, like linked mockups, symbols are only supported when the mockup file and symbol file are both present on disk and do not need to be uploaded. The symbols file should be in the same location relative to the mockup as Balsamiq expects it - assets/symbols.bmml by default.
Once you've imported your mockup, making it into a real application involves 3 things:
To load your imported mockup into an application, see the "Loading screens stored in
Component XML" section of the Component XML
overview
.
First, be sure you have read the QuickStart Guide chapters on Data Binding and the Server Framework so that you are familiar with DataSources, .ds.xml files and how DataSources are loaded into your application. Then, consider the different data-aware widgets in the application created from your mockup:
Grids and Trees
Sample data provided for grids and trees in the mockup is converted to a special kind of
DataSource called a MockDataSource
, which is essentially a
clientOnly DataSource
. There are two
ways to replace these with
real DataSources that save to a persistent store:
dataSource
attribute on the <ListGrid> or
<TreeGrid> element with the ID of your real DataSource
clientOnly="true"
and remove the <mockData> element. Load the
DataSource
normally and the application imported from the mockup will continue to function just as it has.
You can now add settings to the new .ds.xml file to set up persistence (see QuickStart
Guide) - remove the clientOnly="true"
setting and <cacheData> element
whenever you want to switch over to real persistence.
Forms & ValuesManagers
As far as form controls (anything used to enter data), the basic rules are:
ValuesManager
Bear in mind when adding DataSources: the FormItems within each DynamicForm will only be connected to the DataSource field if they have the same name attribute. You'll notice the FormItems are given automatically generated names based on the label for the field in the mockup, for example, a title of "First Name" yields a field name of "First_Name". You may need to edit these in order to match the names of your DataSource fields.
If you right-click on a component in Balsamiq (or option-click on MacOS), a menu item
"Custom Properties" allows you to set a "Custom control ID" and provide "Custom control
data". The "Custom control ID" will become component.ID
for the
Smart GWT component generated from the Balsamiq component.
You can use "Custom control data" to provide additional properties for the generated component, as a semicolon-separated set of properties and values. For example this setting:
showFilterEditor:true; border:"1px solid black".. applied to a Balsamiq "Data Grid" would enable
showFilterEditor
on the
generated ListGrid.
See the section "Event Handlers & Scripting loaded components" in the
Component XML overview
.
If you manage to get the importer to crash or do something clearly incorrect, we want to know about it. Take the BMML file(s) that failed and post them to the forums along with the exact version of your product (lower-left-hand corner of the Developer Console). If you can isolate the exact portion of the mockup that causes the problem and save that as a separate file, that's very helpful in terms of fixing the problem as soon as possible.
In terms of getting past the problem while you wait for a fix, the easiest thing is to just
remove the offending portion of the mockup. You can then create that portion with normal
coding techniques or with ComponentXML
.
Almost all balsamiq components have obvious analogs in smartclient, so during translation they converted in according classes. Here is the list of balsamiq components and smartclient classes which used for convertation. All balsamiq types that are not in this list converted to MockupElement which shows an image of balsamiq component (if there is an image in smartclient library for the component) and component title as a Label.
SectionStack
FacetChart
HLayout
VStack
ButtonItem
MenuBar
DateChooser
VStack
CheckboxItem
DynamicForm
ColorItem
FacetChart
SelectItem
ListGrid
DateItem
Canvas
ToolStrip
Label
Scrollbar
SliderItem
Label
Label
Img
Label
FacetChart
LinkItem
HLayout
SelectItem
MenuButton
MenuBar
Button
SpinnerItem
Label
FacetChart
Button
Progressbar
DynamicForm
TextItem
Label
CheckboxItem
TabSet
Label
TextAreaItem
TextItem
Label
Window
TreeGrid
Scrollbar
TabSet
SliderItem