Declarative UI with XML

It is definitely worth to release it. Can you give a guess when it will be available in the incubator?
Maybe a small documentation would be also very handy :smiley:

Uploaded the 0.1 version to
http://code.google.com/p/xmlui/
.

All comments and feedback is welcome.

This is a great direction, but I want to push you towards Yaml, not XML.

Why YAML:

 1. YAML is much more human readable/editable then XML.
 2. YAML out of the box is designed to be a format for saving/loading objects trees into memory. Because of that, it supports references to other objects in the same document, etc. 
 3. Already a pretty good java Yaml implementation that can load/dump JavaBeans. (snakeyaml in googlecode).
 4. No Schema, DTD, etc. for Yaml. 
 5. Yaml is a robust format, XML formats tend to be fragile. 
 6. Format will automatically track changes in Vaadin. 
 7. Format will automatically support 3rd party additions to Vaadin. 

Yaml came out of Ruby on Rails, but they just popularized it. It has very little to do with Rails. I’m already using YAML at my work for doing all our test cases and I’ve come to love it both as a way to provide bootstrap data and to dump object trees for debugging. It’s both simple, and it provides everything you need to dump a complete object tree from java, even if that object tree has numerous cross references.

I’m brand new to Vaadin, in fact, I’m currently evaluating widget toolkits, and right now, despite how impressed I am with Vaadin, its current “Declare everything in the java code” development process is a show stopper. I just tried the visual editor in Eclipse, and I have to say, it seems to me to be a technical dead-end as its currently implemented. I can’t see how the Vaadin guys can ever get it working. I already notice that it doesn’t support Tab Panels, etc.

But with less than a man-day of work, I think that it would be possible to have the visual editor load/save yaml files so that all the java code has to do is load a yaml file, which will then build the Component tree. That means that the visual editor can just read/write those files, it won’t have to muck around with the java.

With a bit more work, I think it would be possible to make the visual editor itself configurable via a yaml file in terms of what fields to show and so on, which means that it could be made to not only support ALL of the Vaadin components, but it could be easily extended to support custom components as well.

Look, I know all that is hard to believe, unless you’ve used YAML. So let me say this. It’s not freaking rocket science! Java has reflection, JavaBeans have getters and setters. YAML isn’t magic. It calls the constructors, it calls the setters, it remembers what its parsed when it needs a back pointer, and so on. Here’s the beginning startingPoint.xml as YAML:

&id001 !!com.vaadin.ui.VerticalLayout
  height: 100%
  width: 100%
  margin: true
  components: !!set
    ? !!com.vaadin.ui.TabSheet
        height: 100%
        components: !!set
            ? !!com.vaadin.ui.TextField
                caption: Name
                id: name
            ? !!com.vaadin.ui.DateField
                caption: Age
                id: age

How does all that work? Well, basically that translates into the following java code:

id001 = new com.vaadin.ui.VerticalLayout();
id001.setHeight(“100%”);
id001.setWidth("100%);
id001.setMargin(true);

ts= new com.vaadin.ui.TabSheet();
ts.setHeight("100%);

tf = new com.vaadin.ui.TextField();
tf.setCaption(“Name”);
tf.setId(“name”);

df = new com.vaadin.ui.DateField();
df.setCaption(“Age”);
df.setId(“age”);

ts.setComponents( { tf,df});

id001.setComponents( { ts} );

That is, the YAML parser churns along, pulls out the class names and calls the right constructor, pulls out the values, calls the setters. It’s simple, and it just freaking works!

Anyways, if you’re interested in taking this to the next level let me know, and I can help you integrate this stuff with SnakeYAML (It’s just a few lines, really and you could delete tons of stuff in XMLUI.java). Then perhaps we can put pressure on the UI editor guys so that the visual editor can be more real and robust, because it need merely read/write text files without worrying about the java code, because that always looks like.

mainLayout = YAMLLayout.loadFromFile(“foo.yaml”);

Converting a file to be used with the visual editor would also be easy, because you could do:

YAMLLayout.dumpToFile(mainLayout,“foo.yaml”);

Pierce

Let me say a few words about the WYSIWYG editor even though this thread is about an XML component that has nothing to do with the WYSIWYG editor. The current WYSIWYG editor is mostly a tech preview, keep that in mind. We hope to get it moving forward in this spring/summer.

As of now the WYSIWYG is only usable within Eclipse but there are very few (minor) dependencies to Eclipse which we will be working on removing. These dependencies are related to the code generation but actually the WYSIWYG editor is not directly based on the java code it generates in Eclipse. The editor is based on a model of the view being created. Using this model we currently generate java code (export) and we also have the functionality to parse java code and create a model (import). This means that when the WYSIWYG editor evolves we can support multiple formats like XML, YAML and more. Maybe you can even create your own import/export module for your-favorite-way-of-storing-layouts.

We also plan to include support for (of course) all Vaadin core components and custom components. I think the largest challenges here are not the model import/export features but making it visually work and making the user interface good.

It is quite clear that people have different preferences about how to create layouts. Some definitely want to use java only. Some people want to use XML/YAML/another markup. Some people want to use a WYSIYWG editor - some people hate all visual aids and want to write by hand (either code or markup). Thus I do not see that there is a “correct format” to use, rather we should make the WYSIWYG so that it can support multiple formats and you can use the one you feel comfortable with.

In the same way wouldn’t it be great if there was one addon for YAML and another for XML (xmlui)? I am sure some people prefer one format over another other here also for whatever reasons.

Integrating xmlui with WYSIWYG editor is technically trivial. The problem is that xmlui is not a part of Vaadin, but just a small hobby project of mine. Publishing it at such a prominent place (as the official eclipse plugin) would imply that core Vaadin development team would somehow support xmlui format in the future - which it will not.

Still I think that it might be a good idea to allow editing component declaration in some serialized form. One “solution”: How about adding “pluggable serializators” to WYSIWYG editor? This way anyone could write a serializator that converts from UI object tree to text and back to UI object tree, then just package that as a jar and configure the WYSIWYG editor to use that jar. Wysiwyg editor would then add a new tab for each serialization format (declared by adding a serialization plugin jar) and allow editing the UI in “any” format.

Implementing support for YAML this way would be trivial using xmlui as basis. One could even use XSLT like this:


# created by http://yaml.org/xml/xml2yaml.xsl
--- %YAML:1.0 !!VerticalLayout
height: '100%'
width: '100%'
margin: true
c: 
   - 
      expandRatio: '1.0'
      TabSheet: 
         height: '100%'
         c: 
            - 
               caption: 'Fields'
               VerticalLayout: 
                  spacing: true
                  margin: true
                  c: 
                     - 
                        TextField: 
                           caption: Name
                           id: name
                     - 
                        DateField: 
                           caption: Age
                           id: age
                     - 
                        alignment: c
                        InlineDateField: 
                           resolution: 4
            - 
               caption: 'Misc'
               VerticalLayout: 
                  margin: 'left top'
                  c: 
                     - 
                        Label: 
                           contentMode: 3
                           =: |
                              <div style="background-color:
                              							yellow;">Foo</div>
   - 
      alignment: r
      Button: 
         caption: Save
...

(Just transformed the example XML without knowing anything about YAML)

Another hobby project that could be packaged as pluggable serializator:
http://www.oxygenite.org/blog/?p=33
.

If we’re going to talk about WYSIWYG editors, I think we should first talk about working with artists, which I’ve done a lot of.

What artists really, really want is very similar to what programmers want:

edit text file → refresh → review → repeat

This is why I think a Declarative UI is important, because compiling sucks.

So if the UI could re-bootstrap itself after the resource declaring the UI structure changed, you would find very, very happy artists. The WYSIWYG editor would get them close, and then after that, they would want to be able to tweak the UI with live data.

So that implies not just a serialization method, but a way to reboot the component structure with the new information. That might be as simple as having a “Development mode” flag that added a button to the component structure to force a reload.

As for my preferring YAML over XML, that’s admittedly just a preference, because XML implies DTD, etc. But something like the way that DBUnit dumps XML would be ok.

Just had a meeting with our UI designer about using Vaadin, here’s what we decided.

He has two main work cycles:

In the first, he has to get buy in from people, without necessarily running the app. In fact, not running the app is preferred. He can do this in Photoshop or OmniGraffle if he has to, but people don’t really get it.

In the second, he has to then go off and implement the result, after getting buy-in. In this case, being able to edit almost any kind of text file for the UI declaration and hit “refresh” in the browser, and see the new result is a must.

So here’s our wish list for declarative UI:

  1. An application that can take a set of UI declaration files and run them like they’re an app. The idea being that the UI designer can mock up the application during the buy in phase, so every one can agree what the main tabs, menus, toolbar, forms, etc. should look like.

  2. A development mode such that you can click some control on each nested view to rebuild that view from the declaration file that built it. I would implement this just that if you’re in development mode, when loading a view from the declaration file, it just wraps the view with something that adds a frame and a refresh button. The other alternative would be that in development mode, it would just ping the server periodically to see if the declaration file has changed, and if it has, reload automatically.

Does that seem doable? I noticed in the JPAContainer demo that there’s java wiring up all the buttons in the middle of the component tree building. But I also notice that clicking refresh seems to reload the page in the right state, so maybe #2 is already done.

Would XMLUI with the
above mentioned editor
be sufficient?

Possible improvements:

  • Use YAML instead of XML
  • Make xmlui syntax even simpler
  • Use a real XML editor instead. This could have a benefit of code completion with assistance from a schema.
  • Add a CSS editor to the prototyping tool

With xmlui library this should be really easy to do. Just look this piece of code:
http://code.google.com/p/xmlui/source/browse/trunk/src/fi/jole/xmlui/editor/XMLUIEditorApplication.java
. Instead of reading the code from a textfield, one could as easily read it from file periodically. It might even be a good idea to add an undo button there.

Instead of refreshing the page, one should leave the refreshing control to the editor application. Maybe refresh automatically or click a “Text UI” button as in the
xmlui editor app
.

If you really prefer browser refresh, it is also possible to support by returning a new window instance from application.getWindow() each time and reading the the ui declaration from a file then.

Hi,

I guess that an XML for declaratively describing the UI for vaadin applications is a very good idea.

Things should go like this:

The visual editor directly manipulates the XML file. Working with XML is much more easier for a visual editor than parsing source code. Just take a look at the Swing designer in Netbeans. The visual editor only changes things it created itself. There is no risk that the editor manipulates the written business logic.

For each XML UI file that is written by the visual editor (not manually), there exists an additional Java file that keeps the business logic for the UI. This combination is also used in visual studio.

Developing UIs manually should not be the way to develop applications. A visual editor as it is developed for Vaadin is state of the art. But using XML for the backend that is saving the UI is a good choice.

Just think about this combination of XML and visual editor to devide UI and business logic.

Regards,

Mike

Thans for comments. The current implementation of WYSIWYG editor uses instantiated UI component tree as the model. With this it should be fairly easy to add XML as an alternative view to the edited layout. Unfortunately I have not had time to make any progress with the project lately - so it is still on a “concept prototype” level.

Is there a schema file to go along with the XML so that the Eclipse XML Editor can auto complete things?

It may also be good if event listeners can be defined in XML as well. I like the way ZK does the ZUL files with its good eclipse plugin support to edit the ZUL files.

I think that XML is fundamentally the wrong approach. I went and looked at what Joonas did, and it has a ways to go before its usable. Wiring up listeners is just one of the problems.

However, using the snakeyaml project, it should be possible to bootstrap building the basic structure of a Vaadin UI in under a day, because snakeyaml can already read/write arbitrary Java bean structures.

If some one is interested in trying this, I have some simple code for snakeyaml that avoids writing out default values of java beans (based on the null constructor) that I could hand off to you.

Why Yaml:

     Yaml has a concept of aliasing, so you can setup a value of a java bean as matching something you've already defined. So you can tell the child that its parent is well, the parent. :

component: &parent1 { — the alias for our component is “parent1”
title: “Title”
children: [
parent: *parent1 — setParent(parent1) is going to get called on the child.

In XML, you'll have to go back after the fact in order to wire "parent", and you'll have to do that for each class.You can save/restore arbitrary structures of java bean objects in Yaml, which you can't do in XML. YAML files, if you use the "prettyFlow" stream that's in SnakeYaml 1.7 are also more human readable then XML. 

     Second, snakeyaml allows you to inject your own object resolvers, so you can wire listener methods up inside the layout. When I looked into how people made Vaadin UIs, there are lots and lots of inner classes. Which work great, until you're trying to split up the code from the layout. Snakeyaml would let you set the listener method using some pre-defined constructor:

  !listenerMethod: saveClicked
  !listenerClass: SaveClickerClass

The first would tell the loader to call “saveClicked” on the loading class, the second would know to make a new instance of SaveClickerClass (presumably an inner class).

This would be much better then ZKs approach because the code would be the code, and the layout the layout. That’s one of the things that I think sucks about ZUL.

If you use the Yaml approach, I suspect that someone could have a working declarative UI loader based on Yaml in a week. If someone wants to tackle this, let me know, and I can pass you some code to make things easier.

Yes! Exactly what I’ve wanted for a while now. Working as a theme designer/developer together with UI programmers is sometimes such a pain, when you have to go through all the Java code just to try and add some margin or change some layout to another type.

What would suffice for me, is that the UI programmer would just use CustomLayouts for each and every screen they code, and just provide semantic “slot” names for all the components that they put inside the layout. I could then only edit the CustomLayouts, where I would be allowed to hack as much HTML as I dare, instantiate core layouts with a set of components/slots as parameters, add/remove style names for all contained components and specify their sizes.

I would not want to specify any listeners for the components inside the layout, that’s specifically the job for the UI programmer. The program logic should, in my opinion, stay in the Java code, where it’s easiest to maintain, refactor and keep clean. Layout code is the one that usually ends up messy, not the logic, hence I would very much like to separate the two, and I bet the regular UI programmers would like it as well. So wiring up listeners through templates is a bad idea IMO.

I realize this would require a bit more effort from the UI programmer in the start (creating HTML templates, naming all slots etc.), but the reward would be worth it.

And to not just ramble about my own ideas, I might actually respond to your ideas as well :slight_smile:

I took a very brief glance at the SnakeYAML documentation. Pretty hard for me to say, with such limited info, if it would be useful to use that kind of syntax. My first gut feeling didn’t like it too much, but maybe if I saw a better example I could be persuaded otherwise.

Yeah, I’ve been on the other side of that, being the programmer working with the designer. So I agree, code is code, layout is layout.

As for what Yaml looks like, you’re right, the examples are lame. So this is a complex example in “flow” style, with the “pretty flow” option I added to SnakeYaml. It’s the first half of a file, so there are terminators missing. This is from our actual code.

Yaml has two flavors:
Block: Kind of like Python, indentation/whitespace is important to indicate nesting
Flow: whitespace is irrelvant, instead surround lists and { } surround name-value pairs, and there’s commas to terminate things.

For Pretty Flow, I take the indentation from Block and add {} and . But the indentation doesn’t matter, its just there to make it more readable. You have to make sure that your
and {} match, and you need commas here and there.

Note that # marks comments.

First the code:



# a series of steps
[

  { # begin step
    title : "Step 1 of 1",
    shortHelp : "This is some short help text for step 1",
    popupHelp : "This is longer popup help text for step 1",

    # begin a series of panels
    panels : [
        {   # panel start
            title : "Panel 1",
            shortHelp : "Short help text for panel 1 step 1",
            popupHelp : "Popup help text for panel 1 step 1",
            attributes : [
             {  # attribute start
                name : "emailAddress",
                label : "emailAddress",
              type : "String",      # This is just for reference, we pull this from the model each time
#              class : "BASIC", # This is just for reference, we pull this from the model each time
                    shortHelp: "",
                    popupHelp: "",
              }, #end of an attribute
             {  # attribute start
                name : "uuid",
                label : "uuid",
              type : "String",      # This is just for reference, we pull this from the model each time
#              class : "BASIC", # This is just for reference, we pull this from the model each time
                    shortHelp: "",
                    popupHelp: "",
                     disabled: true,
              }, #end of an attribute
             {  # attribute start
                name : "party?.name",
                label : "Party",
              type : "Party",      # This is just for reference, we pull this from the model each time
#              class : "MANY_TO_ONE", # This is just for reference, we pull this from the model each time
                    shortHelp: "",
                    popupHelp: "",
              }, #end of an attribute
             ], #end of all attributes for panel
            }, # end of a panel

There’s one thing that’s missing from this example, because this example doesn’t need it, and that is specifying any data types. The reason my above sample doesn’t have it is because SnakeYaml can determine from the context that a List has to be filled with objects of type “Foo”, and if you have an object “Bar” that has a parameter “color” of type “Color”, that it needs to build a “Color” object. Simple types like String, Integer, date can be inferred from the format of the data.

That is, if the type of an object can be determined from the context, either from the specification on the collection class or via the type of the object property, it’s not necessary to specify the type.

In the above, When I parse the file, I tell Yaml its parsing a List. Step.panels is set to be a List, and Panel has Panel.attributes = Map<String,Object>. Those are just the regular declarations for my objects, I didn’t add anything to be able to read/write the yaml!

If specifying the type is necessary, it looks like this:



!!com.example.ProductType {
    guid: 3520D0F5-C2F1-49AB-8F43-F5C808F59D1F,
    name: Demo Auth 9
  },

That excerpt above is from a List, so Yaml knows that they’re all SuperType objects, but it doesn’t know which kind, so it has to specify the type.

Do you think you could work with that?

May be use something more “standard”, like
mozilla rhino
?
JavaFx for poor men :wink:

~~concept:

importPackage(com.vaadin.ui);

JavaAdapter(Packages.com.vaadin.Application, {
title: “My Page 1”,//see? very easy and declarative
foo: 999999,
label1 = Label(“Blabla!”),

/** Init is invoked on application load (when a user accesses the application for the first time). */
init: function () {
with (this) {
// Main window is the primary browser window
main = Window(“Hello window”);
mainWindow = main;

// "Hello world" text is added to window as a Label component
main.addComponent(Label("Hello World!"));
main.addComponent(label1);
		
button = Button("Push me");
main.addComponent(button);
    button.addListener({buttonClick: function (event) {
       label1.value = "Button "+button+", this="+this+", event="+event;
       //but this is still programming language, not xml/yaml
       for (i=0; i<10; i++) { label1.value += i; }
     }});
}//with

}//init
});

There has been a lots of interest in this add-on, but unfortunately I have not had time to complete it.

IMO, there are two “blockers” before this could be considered stable for use:[list]

[]
Reviewing XML structure and deciding upon the final structure.
[
]
Adding support for all attributes of all layouts in the Vaadin Framework core package.

[/list]

Any opinions on the first one? My gut feeling is that the current XML structure is adequate, but it would be better if the structure would be flattened by moving layout attributes from c-nodes to child nodes. Maybe some prefixing should be considered to avoid naming conflicts.

So instead of writing:

<?xml version="1.0" ?>

<VerticalLayout height="100%" width="100%" margin="true">
	<c expandRatio="1.0">
		<TabSheet height="100%">
			<c caption="Fields">
				<VerticalLayout spacing="true" margin="true">
					<c>
						<TextField caption="Name" id="name"></TextField>
					</c>
					<c>
						<DateField caption="Age" id="age"></DateField>
					</c>
					<c alignment="c">
						<InlineDateField resolution="4"></InlineDateField>
					</c>
				</VerticalLayout>
			</c>
			<c caption="Misc">
				<VerticalLayout margin="left top">
					<c>
						<Label contentMode="3">&lt;div style="background-color:
							yellow;"&gt;Foo&lt;/div&gt;</Label>
					</c>
				</VerticalLayout>
			</c>
		</TabSheet>
	</c>
	<c alignment="r">
		<Button caption="Save"></Button>
	</c>
</VerticalLayout>

We could write

<?xml version="1.0" ?>

<VerticalLayout height="100%" width="100%" margin="true">
		<TabSheet height="100%" lo-expandRatio="1.0">
				<VerticalLayout spacing="true" margin="true" lo-caption="Fields">
						<TextField caption="Name" id="name"/>
						<DateField caption="Age" id="age"/>
						<InlineDateField resolution="4" lo-alignment="c"/>
				</VerticalLayout>
				<VerticalLayout margin="left top" lo-caption="Misc">
						<Label contentMode="3">&lt;div style="background-color:
							yellow;"&gt;Foo&lt;/div&gt;</Label>
				</VerticalLayout>
		</TabSheet>
		<Button caption="Save" lo-alignment="r"/>
</VerticalLayout>

(see for a live version at XMLUI Editor - just press “Test XML”)

Hello,

XML is fine to describe the GUI of Vaadin; I don’t see issues in use XML to describe the components. So, I believe that the second mode is more readable to users. What about listeners? Can we add a listener in one button, for example?

Rodrigo

How we should do that? If we would write java in XML attributes we would have to introduce some way of getting references and doing imports. Maybe we could add some references by default, like this:

<Button onClick="app.getMainWindow().showNotification(\"foo\");" caption="foo"/>

I am afraid that this would introduce a large set of complex problems: [list]

[]
how to do autocomplete and code validation?
[
]
how to do imports?
[]
how to pass references?
[
]
should we use BeanShell to execute the code?
[*]
…

[/list]
Any ideas on how to resolve these?

If not, I am in favor of the current “add ids to xml, add listeners in java” approach: Button myButton = (Button) ui.getById("myButton"); myButton.addListener(...)

Actually, for the most common listeners, this could even be reduced to:

ui.addListener("myButton", new Button.ClickListener() {...})