Let's say you are given the following task
Develop a Java Applet that brings up an empty window. Allow the user to change the background color of the window by using a Menu.
If the user chooses Menu -> Color -> Blue,
* Change the background to HTML color "071aaa".
* Print the String "Blue" in the Java Console
If the user chooses Menu -> Color -> Red,
* Change the background to HTML color "ff1a00".
* Print the String "Red" in the Java Console
OK. Sounds pretty easy. Lets make our Frame class.
The first thing I want to do is define constants for those Colors. A few years ago, I was only really familiar with the java.awt.Color constructor that took three integer values: one each for red, green and blue. If I was given an HTML color to display, like our blue "071aaa" I would have had to translate that HTML hex string to the three integers. I would have used Photoshop or a color web site like this. Recently I learned how to directly pass the hex value to the Color constructor that takes in a single integer value. All you have to do is pass in an integer in hex format like this
private static final Color BLUE_COLOR = new Color (0x071aaa);
That's much easier than translating to RGB. The reason I use a static Color constant is so that we don't go reconstructing a new Color object every time the menu item is selected. I've seen a lot of code out there where the programmer calls "new Color(r,g,b)" every time they need that Color. That's a lot of excess object construction.
The ShortcutFrame code:
public class ShortcutFrame extends Frame
{
private static final Color RED_COLOR = new Color (0xff1a00);
private static final Color BLUE_COLOR = new Color (0x071aaa);
MenuItem miBlue;
MenuItem miRed;
public ShortcutFrame(Applet parentApplet)
{
MenuBar menuBar = new MenuBar();
Menu colorMenu = new Menu("Color");
miBlue = new MenuItem("Blue");
miBlue.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
performCommandBlue();
};
});
colorMenu.add(miBlue);
miRed = new MenuItem("Red");
miRed.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
performCommandRed();
};
});
colorMenu.add(miRed);
menuBar.add((colorMenu));
setMenuBar(menuBar);
}
private void performCommandRed()
{
setBackground (RED_COLOR);
log ("Red");
}
private void performCommandBlue()
{
setBackground (BLUE_COLOR);
log ("Blue");
}
public void log (String output)
{
System.out.println (output);
}
}
A few notes here.
- I'm using "anonymous inner classes" to perform the action listening for the menus. A lot of programmers will use the old paradigm of having one global listener for all of their buttons and menu items. This makes for one pretty ugly actionPerformed() method with a whole bunch of if / elses. The inner-classes allow one listener per UI element, no more if / else trees. These anonymous classes will show up as ShortcutFrame$1.class and ShortcutFrame$2.class at compile time.
- Within the anonymous listener classes, I'm not performing the actual menu commands, I'm simply dispatching a method call which does the actual work, i.e. performCommandBlue. This makes the anonymous listener classes a lot cleaner, and also allows these commands to be called by keyboard shortcuts!
- I'm not calling System.out.println directly in my performCommand methods. Instead, I'm calling a log method which does the printing. This way later on, when I want to redirect the output somewhere else, I only have one place to change this. Also if I want to turn off printing, I only have one line to comment out. An even better implementation would be to use the java.util.logging.Logger class. But that's for another blog entry.
In my next entry, we'll look at how to add configurable keyboard to our application.
-Alex
Recent Comments