The original design patterns book was published in 1995 and there was a lot of excitement about it initially. Some of that excitement has died down, so it's not quite as important as it used to be. But this is still an important part of object-oriented programming that you should become familiar with. Employers still often ask about design patterns in interviews.
One of the most important things to remember about a design pattern is that it
creates a new vocabulary for programmers. You might find yourself telling a
fellow programmer that you're trying to figure out how to construct just one of
a particular object and to provide access to the object while also guaranteeing
that you don't end up with two of them. Your friend is likely to say, "the
singleton pattern!" because that particular design problem is known and has
been written about (it's one of the 23 patterns in the GOF book). Most of
these common patterns are included in wikipedia, so you can read about it by
looking up .
After talking about the general idea of patterns, Horstmann talks specifically
about what is known as the Model/View/Controller
design pattern or MVC. The MVC pattern was not included in the original
pattern book, although the observer pattern
is similar to part of the MVC pattern (the idea of separating the model from
the view).
You should get used to this terminology because it's used a lot:
In terms of the line mania programming assignment, I'm asking students to
separate the controller code from the model/view code. You are to have a panel
class that will keep track of the current state of the drawing and will do the
actual drawing. In other words, the panel has the model (the state) and the
view (the drawing). I've asked students to define all of the user interface
controls in a separate frame class (buttons, listeners, etc). So the frame is
the controller (the code that indicates how to interact with the user).
I spent the rest of the lecture talking about the idea of layout managers.
We'll see that in writing Swing programs, you end up with deeply nested
containers. The frame has something called the "content pane", which is a
JPanel that stores its components. We've already seen that in the Colors
program and the line mania assignment, we're putting two different things into
the frame's container: a JPanel with buttons and a JPanel used for drawing. A
typical Swing application tends to have many levels of containers (typically
JPanels inside of JPanels inside of JPanels).
Each Container has an object associated with it called a layout manager. The
layout manager decides the sizes and locations of the objects inside the
container. To explore this, I added two new buttons in the frame class for our
Colors example:
We then changed the layout manager for the JPanel of buttons to be a
BorderLayout:
So we changed this to put the buttons in different areas:
I then pointed out that the colored panel is not very tall. Remember that the
frame itself has a BorderLayout that is deciding how to lay out the two frame
components. So I asked people what this tells you about the colored JPanel.
The answer is that it's preferred height is rather small (10 pixels).
Horstmann discusses all of this in the context that Swing components are
implemented using MVC. So, for example, you can ask a JButton for its model.
I have never found it particularly helpful to know that Swing components are
implemented this way, although it could be important if I wanted to create my
own custom variations of the basic components.
private JPanel buttonPanel() {
JPanel result = new JPanel();
result.add(makeButton("Yellow", Color.YELLOW));
result.add(makeButton("Blue", Color.BLUE));
result.add(makeButton("Red", Color.RED));
result.add(makeButton("Magenta", Color.MAGENTA));
result.add(makeButton("Green", Color.GREEN));
return result;
}
At first we couldn't see the buttons at all. The frame wasn't wide enough. To
be able to see the buttons, I changed where the JPanel of buttons was added. I
reminded people that the frame uses a BorderLayout. We included these two
lines of code to indicate that the colored panel should go in the center region
and the panel of buttons should be added on top (to the north):
frame.add(panel, BorderLayout.CENTER);
frame.add(buttonPanel(), BorderLayout.NORTH);
So we switched them to say that the colored panel should go to the south with
the panel of buttons in the middle:
frame.add(panel, BorderLayout.SOUTH);
frame.add(buttonPanel(), BorderLayout.CENTER);
When we did this, we found that the colored panel was very thin and the panel
of buttons had a lot of space. By default, a JPanel like our button panel uses
what is known as a FlowLayout. We saw by resizing the window that in the
FlowLayout, Java tries to put as many components as it can horizontally and
centered. If it runs out of room, it puts the extra ones below.
private JPanel buttonPanel() {
JPanel result = new JPanel();
result.setLayout(new BorderLayout());
result.add(makeButton("Yellow", Color.YELLOW));
...
}
When we did this, we saw just one button. Remember that in a BorderLayout,
there are 5 areas where you can add something: north, south, east, west and
center. If you add 2 things to the same area, then the first one is not
visible because the second one is drawn on top of it. If you add something to
a BorderLayout without saying where to add it, it goes to the center by
default. So our new version is adding all five buttons to the center and only
the fifth button is visible in that case (a really big button because it was
drawn to fill the space).
private JPanel buttonPanel() {
JPanel result = new JPanel();
result.add(makeButton("Yellow", Color.YELLOW), BorderLayout.NORTH);
result.add(makeButton("Blue", Color.BLUE), BorderLayout.SOUTH);
result.add(makeButton("Red", Color.RED), BorderLayout.EAST);
result.add(makeButton("Magenta", Color.MAGENTA), BorderLayout.WEST);
result.add(makeButton("Green", Color.GREEN), BorderLayout.CENTER);
return result;
}
When we ran this version of the program, we could see exactly how the five
regions of a BorderLayout are set up. I said that the BorderLayout basically
does the following:
We also saw that the BorderLayout can make different choices each of north,
south, east, and west. In other words, it doesn't try to establish any
symmetry for east/west and north/south. For example, when we changed the
button to the west to have a long name ("Magenta that's wide"), we found that
it gave extra space to the west without giving extra space to the east.
Stuart Reges
Last modified: Fri Apr 13 11:39:46 PDT 2007