Dynamic Context Menus & Plugins

Well, this is certainly a tech blog. I kinda want to keep this brief, but I want to outline how plugins change the way you program GUI’s.

The old way of having a dynamic context menu (i.e. a popup menu that changes its items based on what thing you click on) is roughly:

You somewhere have a popupmenu (JPopupMenu in Java terms). You populate the popupmenu with the full list of possible menu items. You have a show() method that gets called, which is passed the thing you click on. Using this argument, it is possible to create a series of if … else … statements to decide what items to show, and what to hide. The menu can then be shown. If an item on the menu is clicked, it is necessary for this popup class to handle farming out the ActionEvent that is created to the relevant class.

This results in a popup menu class somewhere that is horribly designed – it has dependencies to basically everywhere else in the system. I always hated writing this kind of code. I really hope there are better ways to doing this that I don’t know of….

Plugins make this far better. I define an extension point that any plugin can add themselves to called ‘ContextMenuItem’ or similiar. Any plugin is able to add into this. When a context menu is shown for the first time, it goes out and says ‘get me all plugins wanting to extend this point’. It builds up a list of all such plugins. Whenever the context menu is shown, it then simply iterates through each plugin, passing it the JPopupMenu onto which it may insert its menu items, and of course the thing that was clicked on. It can then be up to the plugin to actualy decide what menu items to add based on the thing clicked on. Once all plugins have added what they want to add for this particular item, the menu can be shown.

That is pretty cool, cos the dependency hell from above is removed entirely, as all method calls are simply calling an interface, instead of directly to the plugin classes. Note also that ActionEvents can actually be handled internally within the plugin, reducing the size of the popup management class incredibly (it effectively just calls the plugins and handles showing the popup only).

Ok, that’s enough. Sorry if you don’t care, but I do get emails and MSN messages from people asking about this, and I’m personally very interested, so meh…:P

oh, btw, I’m down one ‘exam’ (it was only 1.5 hours), and have to wait until next Saturday (the 24th) until my next one – hence more work on plugin functionality.

Cheers,
Jonathan

Plugin software development

It’s been a while since I geeked out, so I thought I best do another round, if merely for the purposes of keeping those interested in my adventures into the land of the software plugin updated. The short summary is:

Progress is good, plugins are a great way to develop software, and I am still very much liking this new development mentality.

To expand on that last point: programming is no longer a matter of trying to design everything at once – you can simply say “I’ll make an extension point here, and later on decide on how the stuff happens on the other side of this point”. This is great for my programming style, where I tend to get a basic version written up, and then I can go back and go “hey, why not rip this part out into it’s own plugin?”. Doing this is easy, and allows for easy reconfiguration.

For example, I could have a static logging class that outputs to the console, or to file, email, etc – but how do I configure it on a per-customer basis? Configuration files? Sure, but I believe my solution is even better: drop the plugins you want into the plugins folder, and they’ll just work. This is very true – my build script compiles all files in a plugin into a single file, so each plugin truly is one file – making per-customer configuration simply a matter of reading the file names of the plugins.

So how does this work? I define a logging interface, and a logging extension point. Any plugin that wants to be a logger says it wants to be an extension to the logging extension point, and then simply implements the logging interface. Logging will then work regardless of the number of plugins I have that extend the logging extension point.

Clearly there may be instances where I only want one plugin to extend a certain extension point, such as only allowing one extension to the GUI extension point. This is also easily handled – simply state that the extension point multiplicity for this particular plugin is ‘one’. Easy :).

Ah well, That’ll do for now,
Exams soon, so good luck to everyone for that,
Cheers,
Jonathan Giles.

Arm Operation

Well, barring any mail arriving from the Upper Hutt hospital regarding giving me a public funded operation, I am now lined up for surgery privately on June 29th.

On a related note, I am now accepting donations to the “fund Jo’s arm operation fund”. The operation is costing $6000, but thankfully health insurance reduces that to only $2000, so that’s better.

So, here’s hoping that this surgery can begin my path to recovery (after the last one was a bit of a false start).

Cheers,
Jonathan.

Wedding Update 3

Here’s the cars we will be using. Unfortunately they aren’t too well photographed here (this one was parked tightly in someones garage). Julia and I will have three of them for the day.

Cheers,
Jonathan