Archive for the 'User Interface' Category


Designing a Smarter UI Action Framework 0

First of all let me apologize for the silence over Christmas(plus a bit) - a snowboarding accident, moving house, seeing family, its amazing how much time these things take!

In my previous post on designing a UI action framework we got started on a simple way to separate actions from the UI and put it all together. Brilliant, but you cant help but think we can make it better…

Lets say a user has a simple text editor, they may have kindly set up a save action that opens a file browser and puts the contents of the editor into a file, they may have a file menu with a save menu item and maybe a toolbar button that runs the same action, but what if the user hasn’t entered any text? You could disable the menu and toolbar button but that means our logic is getting mixed in with our interface, if you cant save then it makes sense that the save action cant be run not that the buttons are turned off.

So this is how we make our system smarter, now we will improve our tiny framework a bit so that actions can be turned on or off and the UI can reflect that. Please take care though, its easy to keep adding to a framework and end up with a huge load of classes that can do millions of things but make it very complicated, here were going for something small, compact and efficient.

First of all we need to modify our IAction class and its sub actions so they hold a state and also so we can manipulate that state to enable or disable them. Planning ahead we also then need to notify anything that’s interested about state changes, so we will provide a listener type system for this. Add these methods to your interface:

void setEnabled(boolean enabled);

void addActionStateListener(IActionStateListener listener);

Dont forget to knock up the interface for the listener too:

public interface IActionStateListener {
void stateChanged(String actionID, boolean enabled);
}

Not the most challenging code ever written but it does allow you to turn things on and off, and allows you to listen to that event (you can write methods to remove listeners etc easily)

Now that we can turn our actions on and off the next real task is to reflect this in the UI, there are 2 ways of doing this. First each UI component can be created, its action performed can call the action manager (as in the previous post on this topic) and it can also add and react to its listeners. Thats great if you building a tiny system, if your adding more than just a handful of buttons and menu items I would suggest you subclass that item and move this logic into that, making your UI code a lot neater and shirinking your codebase.

As the first option is easy i’m sure you can figure it out, so ill take the 2nd approach and subclass the UI objects just to demonstrate how this can be done, in this case ill hook up a menu item that can do all this reacting to the actions.

public class MyMenuItem extends JMenuItem {
    private static final long serialVersionUID = -2941768987720461279L;
private final String actionId;
    public MyMenuItem(final String label, final KeyStroke accelerator, final String actionId) {
super(label);
super.setAccelerator(accelerator);
this.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
ActionManager.getInstance().runAction(actionId);
}
});
        // save the action id for this button
this.actionId = actionId;
        // listen for action updates
hookActionListener(this);
}
    private void hookActionListener(MindMapMenuItem item) {
        ActionManager.getInstance().addActionStateListener(new IActionStateListener() {
public void stateChanged(String actionID, boolean enabled) {
// react to the changes if applicable
if (actionID.equals(MyMenuItem.this.actionId)) {
MyMenuItem.this.setEnabled(enabled);
}
            }
});
}
}

The final stage of this UI is to hook it all together, for this is just add a simple listener to my text area that forces me to check for data as the user types, I then go via the action manager to update the state of my action and watch the UI react to that change!

Ok now our UI is becoming smart, it reacts to the user and is really starting to look like a nice little application given the tiny amount of code we have written. It also scales up quite nicely for fairly meaningful peices of software.

In my final post ill show you how we can take this simple word editor and using some fantastic external libraries and coding tricks turn our smart UI into something smart AND beautiful.

I’ll also provide full source code so if your not able to follow this then you can just click run and see it in action.

Designing a UI Action Framework 3

There’s millions of UI frameworks out there, but the one thing I always find is that they fall into 2 categories, they either do too little so I spend my time writing extra bits and adapting things to fit into their system or they do wayyyy too much for what I need such as Eclipse RCP - its an amazing system that can really scale but often you spend so much time coding for it that your project is never going to arrive on time!

The third choice is to write your own. Often when it comes to programming people say that the best programmers cheat, they reuse code, call on libraries and do anything but write code. I completely agree, but in the real world you have the ever looming fact that you don’t have all the time to build and RCP type monolithic system and if your going to spend £5k on a library, then 100 hours adding to it could you have just done it in 100 hours? Ill leave that debate for another day, on with the framework!

The goal of this system is to provide a simple but powerful action framework the separates the action doing the work from the UI system calling this, in my next post ill show you how this type of orthogonal programming can give huge benefits.

What this 2 minute diagram is showing you is that the UI bits are wayyyy over on the left and the action bits are wayyy over on the right. Brilliant our actions have no idea about the UI, so we can swap them out, change them, TEST THEM and pretty much do what we like without even bothering the UI code.

This pretty much looks like this in code, first our UI components must invoke the action via the manager class (this is also a perfect time to get off the EDT).

JButton button = new JButton();
button.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e) {
            new Thread(new Runnable() {

public void run() {
ActionManager.getInstance().runAction(actionId);
}
}).start();
}}

What happens here is that it first gets the action event on the EDT, switches to a new thread and runs the action via the action manager.

The action manager class simply stores the actionID to action pairing in a hashmap for fast look up and as defined in the IAction class invokes the run method.

Finally an instance of IAction may have the following code snippet

public void run(){
//here i run the action
System.out.println("Action Has Been Run");

}

The final bit of the puzzle is how do you pass the id’s around and how does the action manager know about all the ID to action pairings. These solutions depend on the type of system you are building, if its a simple little application maybe its ok to define the ID’s in IAction so you end up with:

ActionManager.getInstance().runAction(IAction.SaveAction);

If this is the case the the constructor of ActionManager may look like this:

//create the hashmap
this.actionMap = new HashMap<String, IAction>();
//add all the local actions in
this.actionMap.put(IAction.SaveAction, new SaveAction());

Sometimes systems are more dynamic that this, you don’t know about all the actions until run-time, for instance when you have plug-ins to your application you need to give them the ability to register themselves to the action manager and to the GUI. Its easy with the action manager, just provide a method to add in an action, with your GUI I would suggest you define locations where these UI objects can be added but that is outside the scope of this post, maybe one for the future.

Now that you have a very simple action framework you can knock up some actions, hook them into the manager and call them from the GUI! Pretty cool for only a few classes, following this post ill explain how we can improve on this framework to provide on/off actions that reflect their state in the GUI, I will also post a demonstration of just how useful it is to separate your UI completely from your action layer in a post on truly native cross platform java apps.

Encrypting Files with an RFID Key 0

I have recently, just out of pure curiosity, picked up a Phidgets RFID Kit which consisits of an RFID scanner, a set of RFID tags (key chain, card, coins) and a disc with some software on it. After booting up their various sample code and seeing the thing in action (it works great by the way and has a nice java api) i couldn’t help but come up with a little project for myself (at the time i was watching spooks on tv and looking forward to the new James Bond film, so was thinking about cool spy gadgets). How great would it be if you could send someone a file that was encrypted, but they needed a physical key to open it?

What follows is my experince with the RFID kit and how I managed to get this up and running!

Overview

The basic idea of this system is that it will show a proof of concept of using RFID’s as a security key in encryption, as such ill just encrypt some text for now. What im aiming to achieve is that I can enter some text into a GUI, choose my encrypt or decrypt option, swipe my card and instantly see my data get encrypted!

To make life easier ill just use some standard DES encryption in java and a pretty simple GUI to tie it all together, obviously we can add some nice touches to the GUI to make it a little bit of a filthy rich client.

The Basics

Now what cool spy program would be complete without a cool spy GUI? Rather than spend all my time on the GUI, which was quite tempting I used a few tricks to speed things up. First I set the window to undecorated (for no real reason) then I used some overlayable components from the Jide Common Library to get a progress icon as things were encrypted and finally 2 radio buttons to choose encrypt or decrypt with only an exit button to press (that should confuse people trying to access your data!). The end result is this:

Encryption

For the encryption I plan to use some simple java cryptography using a DES Cypher and a key that is orignally hard coded, later on we will use the RFID chip as the key.

Generating the key is pretty easy, with a given string you need to get the bytes of the string (most encryption you will find works at a byte level), after that we need to create a key spec based on those bytes and finally get a secret key for our type of cypher with that key spec. It all sounds a bit complicated but in reality is 4 lines of code from string to SecretKey

String encryptionKey = "IAMTHEKEY";
 byte[] keyAsBytes = encryptionKey.getBytes("UTF-8");
 KeySpec keySpec = new DESKeySpec(keyAsBytes);
 SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(keySpec);

The second stage of encryption, once all the objects are set up, is just a case of converting the data you want to encrypt to bytes and encrypting it, in our example we also encode those bytes as a string so we can use them in the GUI. 3 lines of code later and you will have an encrpyted string.

byte[] bytes = str.getBytes("UTF8");
 byte[] encrypted = ecipher.doFinal(bytes);
 return new BASE64Encoder().encode(encrypted);

Im sure you can figure out how to do the reverse (or just grab the source from the bottom of the page).

RFID Addon

At this point we can encrpyt strings and decypt them, I have plugged all of that into my GUI and the final stage is just to react to RFID events from the phidgets device. At this point you could panic about having to do some low level IO coding, JNI or god knows what to get access to the RFID input, but thankfully Phidgets come with a nice java API.

To set up the reader all we need to do is the following, create an RFID reader and attach a listener for the RFID tag being placed onto the reader at that point we will call our internal encrpyt or decrypt methods based on the current radio button.

rfid = new RFIDPhidget();
rfid.addTagGainListener(new TagGainListener(){
void tagGained(TagGainEvent e){
//here we can start the encryption based on the tags ID
}
});


Summary

Ok before anyone starts having a go saying the RFID value isn’t a long enough key to use etc, this is just for fun!

What this does show is that seemingly complex functionality is very acessible these days. Ok RFID cards can be copied, but what if I also add a password to the system? What if I scan the area for bluetooth devices and check my phone is about?

Its a pretty fun little project and if I get some time ill hook into my laptops bluetooth to improve the key and maybe stop encrypting strings but actually encrypt files instead! Heres some pics of it running, and how it was all set up.

The laptop with the phidget installed and the software running

Heres the text again after decryption

Heres the encrypted text

Source Code for this project is here and released under my usual terms. Note you wil need to download Jide and get phidgets installed on your platform.

Next Page »