Interface BalsamiqImport
Mockup Importer
Balsamiq is a tool for rapidly & collaboratively creating mockups of user interfaces. Smart GWT Pro and better includes a tool called Mockup Importer that allows you take exported Balsamiq mockups (.bmml files) and instantly turn them into interactive Smart GWT applications backed by clean, clear code. This allows you to:- speed up development by reusing all the careful layout work you did in Balsamiq
- use Balsamiq as a development tool for Smart GWT, since you can re-import at any time or even continuously
- instantly create a fully interactive version of a Balsamiq mockup in any Smart GWT skin
- offer such functionality to your end users as a means of extending your application (requires Reify Embedded license)
Using the tool
There are two ways to use the Mockup Importer:
- as a standalone tool: go to <project base>/tools/bmmlImporter.jsp and an import dialog similar to Reify's File -> Import dialog will immediately appear. For example, if your bootstrap .html file is at /myProject/start.html, the importer should be at /myProject/tools/bmmlImporter.jsp (be sure your project imports the same tools module required to run Reify).
- in Reify: select the Screen menu option "Import from Balsamiq". You can provide the Balsamiq mockup file in various ways; providing a file will automatically load the screen created from the imported Balsamiq mockup into Reify for further editing.
Component XML
. In
Reify, you
can copy and paste the XML from the Screen menu option "Show code for screen";
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 Reify, use Screen->Save screen 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 the Mockup Importer 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.
Containers & Layout
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, the Mockup Importer uses heuristics to try to organize your components into layout managers and logical forms, as follows.
Containers
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 the Mockup Importer did the same thing, the resulting code wouldn't be very useful because the screen would become jumbled if anything was resized. Instead, the Mockup Importer 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. The Mockup Importer automatically recognizes such elements as contained anyway. If something is sticking very far out of its container and the Mockup Importer didn't realize it was meant to be contained, just fix the size in your mockup, and re-run import.
The Mockup Importer 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
Window.headerControls
being
created, similarly, placing controls in an Accordion's
section will lead to SectionHeader.controls
being created.
Stacks & Layouts
the Mockup Importer recognizes when you have stacked together several things of the same approximate size and assumes they go together. It's OK to be inexact - the Mockup Importer 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, the Mockup Importer will generally pick the option that results in the simplest overall layout.
Space Filling & Fluid Layout
By default, the Mockup Importer 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, the Mockup Importer defaults to ignoring any blank space that appears around the outside of the your mockup (ignoring markup elements - see below). Then, the Mockup Importer 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 - the Mockup Importer 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, the Mockup Importer 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.
Markup Elements
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 the Mockup Importer ignore selected components.
Linked Mockups
Balsamiq supports linking multiple mockups together to create basic interactivity for guided walkthroughs of multi-screen mockups. The Mockup Importer 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.
Links on Tabs
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. The Mockup Importer 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 the Mockup Importer 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.
Links on Accordions
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. The Mockup Importer 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.
Other links
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.
Symbols & Assets
Balsamiq has a concept of symbols, which are reusable elements that can be incorporated into multiple mockups. The Mockup Importer 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.
From imported mockup to application
Once you've imported your mockup, making it into a real application involves 3 things:
- loading the mockup into a larger application (or as the entire application)
- connecting to real DataSources
- adding event handlers and other programmatic logic
Loading the mockup as an application
To load your imported mockup into an application, see the "Loading screens stored in
Component XML" section of the Component XML
overview
.
Connecting to real DataSources
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:
- if you have already separately developed real DataSources: the simplest approach is to
load your DataSources normally, then just delete the <MockDataSource> definitions from
the XML source, and replace the
dataSource
attribute on the <ListGrid> or <TreeGrid> element with the ID of your real DataSource - if you want to start from the mockup DataSources: move the XML definition of the
MockDataSource into a new .ds.xml file, rename the outer tag to just <DataSource>,
add
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 theclientOnly="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:
- any series of adjacent form controls that have a roughly tabular layout will be created as a single DynamicForm
- all DynamicForm controls within one container will share a common
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.
Setting IDs & Custom Properties
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 as well as a 1
pixel black border.
Event Handlers & Scripting loaded components
See the section "Event Handlers & Scripting loaded components" in the
Component XML overview
.
Troubleshooting
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
.
Supported balsamiq component types
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.
- "com.balsamiq.mockups::Accordion":
SectionStack
- "com.balsamiq.mockups::BarChart":
FacetChart
- "com.balsamiq.mockups::BreadCrumbs":
HLayout
- "com.balsamiq.mockups::BrowserWindow":
VStack
- "com.balsamiq.mockups::Button":
ButtonItem
- "com.balsamiq.mockups::ButtonBar":
ToolStrip
- "com.balsamiq.mockups::Calendar":
DateChooser
- "com.balsamiq.mockups::Canvas":
VStack
- "com.balsamiq.mockups::CheckBox":
CheckboxItem
- "com.balsamiq.mockups::CheckBoxGroup":
DynamicForm
- "com.balsamiq.mockups::ColorPicker":
ColorItem
- "com.balsamiq.mockups::ColumnChart":
FacetChart
- "com.balsamiq.mockups::ComboBox":
SelectItem
- "com.balsamiq.mockups::DataGrid":
ListGrid
- "com.balsamiq.mockups::DateChooser":
DateItem
- "com.balsamiq.mockups::FieldSet":
Canvas
- "com.balsamiq.mockups::FormattingToolbar":
ToolStrip
- "com.balsamiq.mockups::HelpButton":
Label
- "com.balsamiq.mockups::HorizontalScrollBar":
Scrollbar
- "com.balsamiq.mockups::HSlider":
SliderItem
- "com.balsamiq.mockups::Icon":
Label
- "com.balsamiq.mockups::IconLabel":
Label
- "com.balsamiq.mockups::Image":
Img
- "com.balsamiq.mockups::Label":
Label
- "com.balsamiq.mockups::LineChart":
FacetChart
- "com.balsamiq.mockups::Link":
LinkItem
- "com.balsamiq.mockups::LinkBar":
HLayout
- "com.balsamiq.mockups::List":
SelectItem
- "com.balsamiq.mockups::Menu":
MenuButton
- "com.balsamiq.mockups::MenuBar":
MenuBar
- "com.balsamiq.mockups::MultilineButton":
Button
- "com.balsamiq.mockups::NumericStepper":
SpinnerItem
- "com.balsamiq.mockups::Paragraph":
Label
- "com.balsamiq.mockups::PieChart":
FacetChart
- "com.balsamiq.mockups::PointyButton":
Button
- "com.balsamiq.mockups::ProgressBar":
Progressbar
- "com.balsamiq.mockups::RadioButton": RadioItem
- "com.balsamiq.mockups::RadioButtonGroup":
DynamicForm
- "com.balsamiq.mockups::SearchBox":
TextItem
- "com.balsamiq.mockups::SubTitle":
Label
- "com.balsamiq.mockups::Switch":
CheckboxItem
- "com.balsamiq.mockups::TabBar":
TabSet
- "com.balsamiq.mockups::TagCloud":
Label
- "com.balsamiq.mockups::TextArea":
TextAreaItem
- "com.balsamiq.mockups::TextInput":
TextItem
- "com.balsamiq.mockups::Title":
Label
- "com.balsamiq.mockups::TitleWindow":
Window
- "com.balsamiq.mockups::Tree":
TreeGrid
- "com.balsamiq.mockups::VerticalScrollBar":
Scrollbar
- "com.balsamiq.mockups::VerticalTabBar":
TabSet
- "com.balsamiq.mockups::VSlider":
SliderItem