XML Layout Parser

Yep… in the process of writing the XML layout parser and thus far it is going well, however, I could use a bit of help.

First, let me show what the layout XML file would consist of and then I’ll plow through some of the basics of the parser. After that, I’ll ask the questions I need assistance with.

XML Layout sample:
[java]
<root>
<screen>
<component type=“Window” id=“someFancyWindowID” position=“5%,5%” dimensions=“90%,90%”>
<method name=“setWindowTitle” param0=“This is a test” />
<component type=“Button” id=“aButtonID” position=“50,50” dimensions=“15%,8%” >
<method name=“setText” param0=“Click Me!” />
</component>
<component type=“Button” id=“aButtonID2” position=“50,100” dimensions=“100,25” >
<<method name=“setText” param0=“Click Him!” />
</component>
</component>
</screen>
</root>
[/java]

There will be a bit more involved, but let me explain what I have thus far.

Naming convention will mirror the classes and class methods to make full use of reflection for building components.
The component tag:
type = the type of control (or class name of control)
The rest of the attributes are the parameters from the common constructor, all being optional aside from position.
Attribute list is: uid, position, dimensions, resizeBorders, defaultImg

Within each component tag are a list of method tags for setting parameters past construction.

The method tag will use the following format:

name="actualMethodName"
and then a series of param0-param#ofParams

Once again, using reflection to build the invoke call.

Posting this and moving on with what I have (I don't want to have to f around with the < > crap again.

Thus far, the parser is rather small, but there are a few areas that I am struggling with how to generisize, for instance at some point I have to cast the Element. My thoughts were an Array of classes that I can instanceof against and pass the class through so I don’t have to branch.

recursive building of nested components is all squared away (aside from the point above.
methods, params and invoke are all squared away.
I have a game plan for defining effects via layout tags.

I really just need options for the above stated problem.

I guess I should also mention. The final parser will more than likely build AbstractAppStates instead of blindly dumping components into the screen. The app states will be accessible for you to load, unload as needed… allowing for multiple screens at the same time.

Oh crap…

I also have a rather large request of those in the know!

I would like to determine a way of allowing methods to be defined in the XML doc. even if it is as simple as a method name and parameters. Again reflection can be used to invoke the passthrough method allowing for ACTUAL DATA TYPES… who woulda thunk it. So, my question is, what are some methods of accomplishing this? What would you suggest looking into? etc…

Final mentions, for those interested in using Layouts…

  • These layout will not interrupt your workflow in the slightest.
  • If it can be done in the library through Java, you’ll be able to mimic it in XML
  • The naming convention is standardized between using Java or XML, so, if you know one, you know both.
  • There are no random tag names, attribute names or attribute values. 5 attributes from the constructor that have actual names and method calls always use name="" and param#=""
  • There are a few additional benefits to XML layouts… you can use % for both position and dimensions (for one)

Curious, have you heard of Java Beans and all of the built in JDK stuff for dealing with them? The whole (method name=”setText” param0=”Click Me!”) thing kind of made me ask.

@pspeed said: Curious, have you heard of Java Beans and all of the built in JDK stuff for dealing with them? The whole (method name=”setText” param0=”Click Me!”) thing kind of made me ask.

I looked into multiple possibilities for handling this and all of them seemed rather bloated for my purposes. Actually, beyond bloated… I would have ended up writing far more code utilizing any of the ObjectFactory type stuff than writing a parser specific to the library. I’m really close to a completed parser at the moment… with a total of an hours worth of work. The only thing left now is event handling… or at least some form of method pass-through.

Now, if I have overlooked something specific… pleeeeease mention the specific =) It’s hard to guess where you are potentially going with your question and if you think I missed the boat… the point at the boat :wink:

Ok… I have the event handling in place now as well.

Here is how it works…

You create an AbstractAppState and call screen.parseLayout(“someXMLDoc.xml”, this);

in the app state you define methods to call via XML:

[java]
public void button1LeftMouseUp(Integer x, Float y, String text) { // or whatever params you want
// Do things
}
[/java]

under the component tag for any given control you now add eventMoethod tags… they appear as follows:
[java]
<component type=“Button” id=“aButtonID2” position=“50,100” dimensions=“100,25” >
<method name=“setText” param0=“Click Him!” />
<eventMethod name=“onButtonMouseLeftUp” stateMethodName=“button1LeftMouseUp” param0=“5” param1=“0.753f” param2=“This is a test from Button 1” />
</component>
[java]

[/java]

Still need to add effect definitions… and yeah… this isn’t perfect… but there is no learning involved really… if you know how to invoke one control, you know how to invoke them all. Most importantly, it works for everything, so I shouldn’t have to modify the parser when new controls are added.

Another day or two and this should be complete.

@t0neg0d said: I looked into multiple possibilities for handling this and all of them seemed rather bloated for my purposes. Actually, beyond bloated... I would have ended up writing far more code utilizing any of the ObjectFactory type stuff than writing a parser specific to the library. I'm really close to a completed parser at the moment... with a total of an hours worth of work. The only thing left now is event handling... or at least some form of method pass-through.

Now, if I have overlooked something specific… pleeeeease mention the specific =) It’s hard to guess where you are potentially going with your question and if you think I missed the boat… the point at the boat :wink:

It’s the calling property methods manually part that I thought was strange… since setters can be used as bean properties. Then instead of (method name=“setText”…) you just have text=“Click Him!” and set the “text” property (using standard bean reflection) on the object.

Creating a well-defined schema or DTD is harder (requires you to write a utility) but frankly as it stands all of the important bits are in strings in your version so a DTD does little to help a user. If you want to help them with that problem then the complexity is the same.

This particular wheel is reinvented often (by myself included *) so you are among good company.

For bean setting/getting, you can crib from:
http://meta-jb.svn.sourceforge.net/viewvc/meta-jb/trunk/dev/src/main/java/org/progeeks/util/beans/BeanInspector.java?revision=3570&view=markup

…or if you prefer a more lax set of conventions and easier use:
http://meta-jb.svn.sourceforge.net/viewvc/meta-jb/trunk/dev/src/main/java/org/progeeks/util/Inspector.java?revision=4336&view=markup
…though it has some dependencies on a couple other classes. It tries to be much smarter than BeanInspector which strictly uses the Java Beans API from the JDK.

@pspeed said: It's the calling property methods manually part that I thought was strange... since setters can be used as bean properties. Then instead of (method name="setText"....) you just have text="Click Him!" and set the "text" property (using standard bean reflection) on the object.

I had a very specific reason for doing it this way.

text=“Click me!”
and button.setText(“Click me!”);

Are two different things I have to remember.

As apposed to:

method name=“setText” param0=“Click me!”
and button.setText(“Click me!”);

I only have to remember one thing now.

In this simple example it may not make that much of a difference… but what about when calling an object method that has multiple params?

now I have to remember a list of closely named tag attributes:

text=“Hey!” texture=“images/thisIsGettingHarderToRemember.png” useIcon=“I’m almost lost now” iconSize=“I give up”

or

method name=“setTexture” param0=“Hey!” param1=“images/someImage.png” param2=“true” param3=“50,50”

Where the original methos is:

steve.setTexture(“Hey!”, “images/someImage.png”, true, new Vector2f(50,50));

The longer you component list gets, the more methods you have to keep track of. The last thing in the world I want to insist people do is remember 70,000 arbitrary attribute names.

Speaking of simplifying things… eventMethod now just requires the event method name and the name of the forwarding method in the app state.

They will simply pass through whatever the abstract method receives. So…

[java]
public void myButtonLeftUp(MouseButtonEvent evt, boolean isToggled) {
// Do stuff
}
[/java]

nothing new to remember. You have access to all components via getElementById… and can 1 for 1 the event methods if you need to use them.

Not saying that you should get rid of the ability to call methods directly. Just saying that it’s weird not to use bean properties when nearly every other Java thing on earth does. The bean stuff has been in since JDK 1.1 and it’s the whole reason we all adopt the convention of setFoo/getFoo in the first place. :slight_smile:

@t0neg0d said: In this simple example it may not make that much of a difference... but what about when calling an object method that has multiple params?

now I have to remember a list of closely named tag attributes:

text=“Hey!” texture=“images/thisIsGettingHarderToRemember.png” useIcon=“I’m almost lost now” iconSize=“I give up”

or

method name=“setTexture” param0=“Hey!” param1=“images/someImage.png” param2=“true” param3=“50,50”

Where the original methos is:

Either way is the same, really. You are still referring to something in a totally separate file that cannot be easily checked except at runtime. One way is less verbose and extremely common. Common enough that we all say “setters and getters” now.

@pspeed said: Either way is the same, really. You are still referring to something in a totally separate file that cannot be easily checked except at runtime. One way is less verbose and _extremely common_. Common enough that we all say "setters and getters" now.

I’m definately not arguing that point. It would make MY life WAY easier. But, in the end… my life isn’t the one I’m trying to make easier… it’s anyone using the library.

So, in this case, I chose a little more typing for not having to reference the documentation a million times to pass through one event method. As long as you know the data types of the method and the name, your all good. Other wise, you would hae to know the method name, the data types and randomly selected attribute names.

EDIT: param0, etc is ugly… no doubt about it. Hopefully my take on not having to learn anything new will make up for that =)

@t0neg0d said: I'm definately not arguing that point. It would make MY life WAY easier. But, in the end... my life isn't the one I'm trying to make easier.... it's anyone using the library.

So, in this case, I chose a little more typing for not having to reference the documentation a million times to pass through one event method. As long as you know the data types of the method and the name, your all good. Other wise, you would hae to know the method name, the data types and randomly selected attribute names.

But who is this XML for? You still have to reference the docs or the code but now you also have to be a programmer. And if you are a programmer then why not just write the code.

Maybe I’m having trouble understanding how a user would magically remember that the method name is setText but not remember that there is an attribute “text”. Either way they have to check the docs… and in the second case they have to do the simple bean property name transformation that we all already know how to do.

Either way if you were to try to give this to a UI designer you will have to provide them with some custom docs. In one approach you give them a list of attributes and possible values and it looks very similar to HTML, etc. (in fact more can be done in that direction even). In the other case they have to remember some magic methodName incantations and constantly translate what they want to do “I just want to set text” into whatever long line does that. They probably end up with lots of sticky notes on the edge of their monitor with things like: text = method name=“setText” parm0=“the text”

XML that directly exposes code in a totally unabstracted way generally ends up being of use to no one. A .java file is easier to write and you get compile errors.

It is kind of fun to watch people repeat the same mistakes over and over again, though. But they are your mistakes to make.

@pspeed said: But who is this XML for? You still have to reference the docs or the code but now you also have to be a programmer. And if you are a programmer then why not just write the code.

Maybe I’m having trouble understanding how a user would magically remember that the method name is setText but not remember that there is an attribute “text”. Either way they have to check the docs… and in the second case they have to do the simple bean property name transformation that we all already know how to do.

Either way if you were to try to give this to a UI designer you will have to provide them with some custom docs. In one approach you give them a list of attributes and possible values and it looks very similar to HTML, etc. (in fact more can be done in that direction even). In the other case they have to remember some magic methodName incantations and constantly translate what they want to do “I just want to set text” into whatever long line does that. They probably end up with lots of sticky notes on the edge of their monitor with things like: text = method name=“setText” parm0=“the text”

XML that directly exposes code in a totally unabstracted way generally ends up being of use to no one. A .java file is easier to write and you get compile errors.

It is kind of fun to watch people repeat the same mistakes over and over again, though. But they are your mistakes to make.

I think Nifty did a fairly good job of showing how terrible this approach can end up.

Example:

imagemode=“resize:1,15,1,1,1,15,1,15,1,15,1,1” /boggle

a method call could potentially have more than one parameter and the friendly attribute names become unfriendly really quick like. Unless you try and mash them all together like in the approach above.

Like I said, the approach isn’t perfect by any stretch, however… in the long run it accomplishes two things:

A WHOLE lot less to remember and a WHOLE lot less to remember.

Plus, if this REEEEEAAAALLLY becomes an issue, updating the parser won’t take much effort. If worse comes to worst, it wouldn’t take more than a couple hours to completely rewrite the parser. And I’ll have enough feedback after the first day or so to start my groveling before you realize I started :wink:

Oh… in preparation for the groveling… how would you suggest naming attributes… the major issue I have with text="" and then some other param is… text="" is a method call. The next may not be. How do you distinguish methods and params?

@t0neg0d said: A WHOLE lot less to remember and a WHOLE lot less to remember.

Now we are talking in circles again. It’s your framework to do as you like. I fail to see how remembering “setText” is any different than remembering “text”.

Nifty’s approach was confusing because it wasn’t always clear where to look for the mappings, method or not.

@t0neg0d said: Plus, if this REEEEEAAAALLLY becomes an issue, updating the parser won't take much effort. If worse comes to worst, it wouldn't take more than a couple hours to completely rewrite the parser. And I'll have enough feedback after the first day or so to start my groveling before you realize I started ;)

Oh… in preparation for the groveling… how would you suggest naming attributes… the major issue I have with text="" and then some other param is… text="" is a method call. The next may not be. How do you distinguish methods and params?

You already have a special element for method calls. Why would you change that? Or if I misunderstood, why would the component element have a text attribute that wasn’t related to the text property on the component? Now that would be confusing.

Every point you make for why one way is confusing cuts the other way, too. Just because you are familiar with your way does not make it intuitive. People will have to be checking the javadocs anyway. Now that will also have to cut-paste method call blocks over and over just to setup their components.

The imagemode parameter is a good example of how not to do it, can’t argue with that.

But thats because for clarity it shouldn’t be imageMode=blah at all, it should be:
imageMode=“resize”
topMargin=1
bottomMargin=1
etc.

@zarch said: The imagemode parameter is a good example of how not to do it, can't argue with that.

But thats because for clarity it shouldn’t be imageMode=blah at all, it should be:
imageMode=“resize”
topMargin=1
bottomMargin=1
etc.

For proper fluency, one might actually expect: (using parens instead of less then/greater than)
(imageMode type=“resize” topMargin=“1” bottomMargin=“1”… etc./)

But you know, Spring’s XML support already has all of this wired up automatically. Pretty much 0 work to be done, I think.

1 Like
@pspeed said: For proper fluency, one might actually expect: (using parens instead of less then/greater than) (imageMode type="resize" topMargin="1" bottomMargin="1"... etc./)

But you know, Spring’s XML support already has all of this wired up automatically. Pretty much 0 work to be done, I think.

How do you manage the mapping though? In the DTD? And how large does this file become (i.e. how hard is it to maintain as your attribute list grows)?

EDIT: It’s a lot easier to take a look at changing this now that it is completely working. Before… the thought was kinda scary, because I wasn’t completely sure how to accomplish half of it.

EDIT @: I say completely working. I’ve tested all components and a large number of methods. Though, I’m fairly sure I haven’t accounted for some parameter data types. I also have an issue with getting audio nodes to fire off properly via the effect definitions