Frank,
Thanks or your input, this is really appreciated and I would wish we had
more contributions like this. Please send me your code and I will
integrate it in the next or a following releases.
I would like to keep the custom attribute tags (like class,
factorymethod, etc.) to an absolute minimum.
Maybe a single attribute name like "instance" would do. I.e.
<tagname=".." attr=".." instance="mypack.myclass"/>
and getInstance() is used if this this method exists otherwise the
default constructor is called.
Wolf
Frank Mei�ner wrote:
Hello Wolf,
I understand it the way you explained it.
A couple of month ago I worked on an application heavliy using Action
objects. Some actions did have their own status, e.g. linked with some
JTree or the like. First, we had a lot of attributes, some anonymous
inner classes, some external classes. Then we decided to create the
menu items, toolbar buttons and the like from a Collection holding
Action items. These actions could merely act on themself: they
registered on some event notifier (to get notified if the user clicks
on a table row, a tree item, ...). If the action was invoked, it was
able to handle all of the business logic on themself. These actions
where not lightweight, they did not only forward their wish to some
object which does the work. They kept the business logic for themself,
where it belonged.
E.g. the action PayBookings registered itself on a JTable containing a
list of bookigs. If the user selects at least one, the action enables
itself. If the user clicks on the button (menu item, ...) which is
associated with the action, it collects the selected bookings, wraps
them in some even object and fires the event. Done. No further action
was necessary. This approach enabled us to keep the business logic
very concentrated in the actions. These actions where reasonable
small, easy to understand and to maintain. If we had to keep all the
methods in some outer class (actually, this was our first approach),
this outer class would grow beyond maintainabilty. The outer class was
about 3500 lines of code when we switched to the action-approach --
and nobody liked to touch it :-(. Then it was about 500 lines of code
because we removed nearly all code to Action classes... Now it is easy
to remove or add new actions and to get rid of unused functions --
even without the help of some sophisticated IDE.
So, the nested class approach works good for some smaller designs. If
you want code isolation or have a lot of actions with sophisticated
busines logic (maybe likely to change), this may not work very well.
Swixml would enable the design to get completly rid of creating the
action objects on ourself. Of course, some thinking has to be done for
the init of the actions...
Let me show the code I wrote recently with the "unimproved" swixml:
public class SwixmlTest extends SwingEngine {
public test1Action = new Test1Action();
public test2Action = new Test2Action();
public test3Action = new Test3Action();
public test4Action = new Test4Action();
public test5Action = new Test5Action();
public test6Action = new Test6Action();
public test7Action = new Test7Action();
public test8Action = new Test8Action();
public test9Action = new Test9Action();
public test10Action = new Test10Action();
public test11Action = new Test11Action();
public test12Action = new Test12Action();
public test13Action = new Test13Action();
public test14Action = new Test14Action();
private SwixmlTest() {
try {
render(SwixmlTest.class.getResource(
"/xml/swixml-test.xml")).setVisible(true);
...
I do not know which actions are actually used in swixml-test.xml --
and I do not care. So, why should I create the variables and not let
swixml create exactly the actions I mention in the xml? You easily see
the code above is reduced to this:
private SwixmlTest() {
try {
render(SwixmlTest.class.getResource(
"/xml/swixml-test.xml")).setVisible(true);
...
I hope I shed some light on the topic. And I hope I showed I'm no
swing-newbie ;-)
Frank
Wolf Paulus wrote:
Frank,
While there is nothing wrong with your approach, there was a
particular reason why we did it differently.
I guess the missing documentation is to blame. However, let me try to
explain how we pictures the link between the GUI Widgets and the
actual evenbthandlers.
All the SwiXml Tags representing Swing objects that inherit from
Abstract Button (like JButton, JMenuItem, JCheckBox, etc.) accept the
ActionCommand and the Action attribute.
When the Action attribute is used, the following will happen with the
example for instance:
XML Code:
..
<button Text="Click" Action="Handle_Click"/>
<button id="btn2" Text="2nd Button"/>
..
Java Code:
..
public class HelloWorld extends WindowAdapter {
private SwingEngine swix = new SwingEngine( this ); // *1*
public JButton btn2; // *2*
public Action Handle_Click= new AbstractAction() {
public void actionPerformed(ActionEvent e) {
System.out.println( "Click was pressed" );
btn2.setEnable(false); //*3*
}
}
private HelloWorld() {
try {
swix.render( "xml/HelloWorld.xml" ).setVisible( true );
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new HelloWorld();
}
}
The button Tag triggers the instatiation of a JButton object. Then
after the parsing and instantiation work of the whole XML document is
done, EventHandlers, (in our case the _public_ Action Handle_Click is
linked with the Button.
The Button does not need an ID if you don't need to refer to it later.
The example has another button (//*2*) that we want to disable if
the 1st button was clicked. Therefore this button needs an ID.
If there is a _public_ Button in the class of the object that was
passed into the SwingEngine at construction time (//*1*) and the
button's name matches the tag's then this button gets initialized
automatically during parsing as well.
If you need to make your members private you will have to use the
SwingEngine's find method to init those yourself.
Now here comes the benefit of during it this way. Swing programmers
are used to use inner classes. The Action class used in this example
is an inner class, allowing easy access to the outer class members
and methods. See how easy it is to disable the 2nd button in the
event handler.
When you want to use the alternative (built in) way hook up your
event handlers, you need to use the ActionCommand attribute. This
requires a little more java code to write but in certain situations
this might be preferable over the Action attr. way.
Check the sample code at http://www.swixml.org/samples/index.html for
details.
Wolf
Frank Mei�ner wrote:
Hello again,
Ok, because I needed the features I mentioned, I added them for
myself. Now I'm able to write swigxml-code like this:
...
<menuitem id="mi_exit" InitClass="test.actions.ExitAction"
FactoryMethod="getInstance"/>
...
<button enabled="true" InitClass="test.actions.ExitAction"
FactoryMethod="getInstance"/>
...
All these objects use the same instance of ExitAction. If no
ExitAction is used at all, no object of this type is created (of
course...).
So, this code moves swigxml a bit more to the business-logic part of
the code. It allows you to switch some (maybe expensive) parts of
your gui on and of. Especially if the components do create without
further arguments you do not have to take care on them. Just
implement them, test if they work correctly and leave it to someone
else to decide if he/she wants to see them.
On the original swigxml you have to take care on the creation of the
actions for yourself. You have to (correct me if I'm wrong) assign
an id to every button or menu item in the xml. Then you have to
write code which iterates over all of the id's you defined. If one
is used (e.g. the component by getIdMap().get(id) returned a value
!= null), you have to create the appropriate Action and assign it to
the {button, menu item, ...}. Of course, one might use a clever
String for the id (like "1.test.actions.ExitAction<getInstance>")
but this is not as clever as to provide the factory method :)
Just tell me what you think of it...
Frank
_______________________________________________
Forum mailing list
[email protected]
http://mars.lunarpages.com/mailman/listinfo/forum_carlsbadcubes.com
_______________________________________________
Forum mailing list
[email protected]
http://mars.lunarpages.com/mailman/listinfo/forum_carlsbadcubes.com
_______________________________________________
Forum mailing list
[email protected]
http://mars.lunarpages.com/mailman/listinfo/forum_carlsbadcubes.com