CSE190L Notes for Wednesday, 4/11/07

I said that we were going to start moving into chapter 9 material. Horstmann begins the chapter with some interesting material on design patterns. Design patterns have become very popular in the OOP community ever since the publication of a book called Design Patterns: Elements of Reusable Object-Oriented Software by four authors who are collectively known as the Gang of Four or GOF. The book is sometimes referred to as the "GOF book."

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:

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.

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:

        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.

We then changed the layout manager for the JPanel of buttons to be a BorderLayout:

        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).

So we changed this to put the buttons in different areas:

        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.

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).


Stuart Reges
Last modified: Fri Apr 13 11:39:46 PDT 2007