Space

- GUI Redesign -



PURPOSE:

The purpose of this portion of the Journal is to show how I redesigned the GUI component of my program to make it nicer and more user-friendly.

ANALYSIS OF ORIGINAL GUI DESIGN:

My original GUI design is really a misnomer in that there was no design that went in to it. I just created all of my graphical objects in a top-level row. While this works just fine, it isn't necessarily great GUI design. As I mentioned before there is lots of space that is wasted that could be put to better use.

Another thing I would like to do is display the name of the ships which are available to select as well as their external appearances. Besides that I would just like to have a better looking program.

Before I started to redesign my GUI I started up xpaint, a graphical editor, to draw what I wanted to GUI to look like. Having a picture of what I wanted my program to look like would give me a concrete artifact to check my design against.

Now that I had a picture to look at it was time to identify the geometry management I would have to do in order to get my program to look like this. Again I turned to xpaint and drew purple borders to account for the geometry management I needed to do. What I decided from this picture was that I would use GP.Containers.Frames for the ShipButtons and labels, a GP.Containers.RadioRow for the Mouse buttons (as I already was), a GP.Containers.Column for the Starfield and Mouse button row, another GP.Containers.Column for the GP.Components.ColorChooser and InputChooser. All of this would be wrapped up in a GP.Containers.Row that was already the Simulation.

The first thing I decided to tackle was the ShipChooser code. I went in trying to add my frames but found that this would be impossible. Why? Because in order for toggle buttons to work properly their container needs to be of type GP.Containers.RadioRow or GP.Containers.RadioColumn. If this is not the case they will not function properly. So instead of embedding them in their own frame with labels I opted to just create instances of GP.Graphics.Text with the name of each ship. I did this in the ShipChooser class.

Next I decided to put the MouseController below the Starfield. This proved to be even easier. One thing that is nice about having a large graphic library to use, like GP, is that you do not always have to subclass and extend classes. You can just use them. So to place my Starfield and MouseController classes into a column all I did was to create an instance of GP.Containers.Column and passed it into their constructors as their container. Simple, quick and easy.

To get the ShipChooser in front of the Starfield I did the same thing. I just made a new instance of a GP.Containers.Column and passed it in to the ShipChooser as its constructor. But it was a little bit more complex. Normally, since the Simulation class is a GP.Containers.Row you would have just created the ShipChooser class before you created the Starfield and its column. However the ShipChooser needs a reference to the Starfield so we cannot possibly instantiate it first. So what I did to solve this was exactly what I said. Create the column first so that it occupies the first slot in the row and then use it as the container later when we create the ShipChooser.

While playing around with my newly reorganized GUI I found out that there was a bug in my code! If I was the Explorer and had activated my Light and then decided to switch to the Attacker the ship and light would still remain on the screen! After a few minutes of looking at my code I realized what the problem was: Eventhough I was telling GP to graphically Hide() the ship, and I was getting rid of the reference to the old ship the Light and LightBehavior still had references to them.

To fix this I created a java.util.Vector in my Explorer class and stored every instance of a Light that I made. Whenever this class was finalize()d it would tell all of the Lights to do likewise and to lose their references to the ship. The Light also removed its behavior which helped too.

After fixing this bug I decided that I wanted graphics for my input chooser. After surfing the web for less than two minutes I found some suitable graphics, blew them up and added them to my KeySelect and MouseSelect classes.

I then decided to put some more labels on things so the users would know clearly what everything on the screen was. Since the color chooser came prelabelled I followed suit and labelled by input chooser and ship chooser. I labelled these by creating instances of GP.Graphics.Text in the Simulation class.

While I am on this subject let me make a slight diversion into design again. While it is nice to reuse GUI components at what level is using them rather than subclassing off of them and making free form GUI components going too far? Well with object-oriented design we like to think of things as being reusable. That is, if I designed a similar system I would like to be able to take out an object of one system and transplant it in the new system with relative ease. If I am organizing my GUI components in a non-structured manner, as I am here, will this be possible?

Not really. I will have to remove certain parts and add others to my new system. Considering this aspect it might be wise to actually subclass and create stand alone GUI components. Here is my modified GUI code before I modularized it:

Modified GUI code (unmodular):

And after I redid it, along with a screen shot of my GUI:

Modified GUI code (modular):

My GUI design was just about complete. What I'd really like is to have graphical buttons for the MouseController but I am no artist. If I can find some on the web I will add them in the same manner as I added graphics to the InputChooser.


This page was last updated by Shoe on 03/04/98.
Comments or suggestions, should be sent to: ahs@cs.brown.edu
Space is copyright 1996-1998 by Andrew H. Schulak