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 useGP.Containers.Frames for theShipButtons and labels, aGP.Containers.RadioRowfor theMousebuttons (as I already was), aGP.Containers.Columnfor theStarfieldandMousebutton row, anotherGP.Containers.Columnfor theGP.Components.ColorChooserandInputChooser. All of this would be wrapped up in aGP.Containers.Rowthat was already theSimulation.The first thing I decided to tackle was the
ShipChoosercode. 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 typeGP.Containers.RadioRoworGP.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 ofGP.Graphics.Textwith the name of each ship. I did this in theShipChooserclass.Next I decided to put the
MouseControllerbelow theStarfield. 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 myStarfieldandMouseControllerclasses into a column all I did was to create an instance ofGP.Containers.Columnand passed it into their constructors as their container. Simple, quick and easy.To get the
ShipChooserin front of theStarfieldI did the same thing. I just made a new instance of aGP.Containers.Columnand passed it in to theShipChooseras its constructor. But it was a little bit more complex. Normally, since theSimulationclass is aGP.Containers.Rowyou would have just created theShipChooserclass before you created theStarfieldand its column. However theShipChooserneeds a reference to theStarfieldso 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 theShipChooser.While playing around with my newly reorganized GUI I found out that there was a bug in my code! If I was the
Explorerand had activated myLightand then decided to switch to theAttackerthe 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 graphicallyHide()the ship, and I was getting rid of the reference to the old ship theLightandLightBehaviorstill had references to them.To fix this I created a
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 myjava.util.Vectorin myExplorerclass and stored every instance of aLightthat I made. Whenever this class wasfinalize()d it would tell all of theLights to do likewise and to lose their references to the ship. TheLightalso removed its behavior which helped too.KeySelectandMouseSelectclasses.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.Textin theSimulationclass.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 theMouseControllerbut 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 theInputChooser.