Each of these purposes are discussed in more detail in the next three sections. These sections describe certain aspects of the finished program. They are not instructions for doing the first step. The instructions for the first step are in later sections.
However, communication is handled differently in the two assignments. In the previous assignment, the controls sent information to the graphics display panel by invoking its setter methods, such as setLevels(). For this assignment, the controls just tell the graphics display panel to update itself by invoking an updateDrawing() method defined in the DrawPanel class. Then the graphics display panel asks the applet about anything that it needs to know in order to do its drawing. It does this by invoking getter methods, such as getX(), defined in the GraphicsApplet class.
To make this work, you must define an instance variable in each class that refers to an object from the other class. A GraphicsApplet object needs a DrawPanel instance variable so it can tell the draw panel to update itself. A DrawPanel object needs a GraphicsApplet instance variable so it can invoke its getter methods.
Typically, an applet constructs other components in its init() method. This makes it easy to get an instance variable in the GraphicsApplet class that refers to a DrawPanel object. But how does the DrawPanel object get a reference to the DrawPanel object? The simplest answer is to design the DrawPanel constructor with a GraphicsApplet parameter. When the GraphicsApplet constructs its DrawPanel, it passes itself as the value for the parameter. In the constructor, the parameter is assigned to an instance variable. Then both objects can send messages to each other.
There is an unfortunate side effect to this kind of communication: neither class can be compiled unless there is at least a preliminary definition for the other. When the compiler encounters a DrawPanel variable definition in the GraphicsApplet class, it checks for a definition of the DrawPanel class. If it doesn't find one then you get an error message. Conversely, When the compiler encounters a GraphicsApplet variable definition in the DrawPanel class, it checks for a definition of the GraphicsApplet class. Again, if it doesn't find one then you get an error message.
g.drawString("Hit return after changes.", 100, 100);In this assignment, the title is supposed to change when the user operates the controls. Thus borders are handled differently than in the previous assignment. A titled border is an instance of the TitledBorder class in the javax.swing.border package. This class has a setTitle() method for changing the title. You could not use this if the border were set up as in the previous assignment because there wouldn't be a variable that could serve as the receiver of a setTitle() message. Thus for this assignment, the graphics drawing panel has a TitledBorder instance variable.
The most natural thing to do is install the border onto the drawing panel. Unfortunately, borders are installed inside the component that they are installed on. This means that the points with x-coordinates or y-coordinates near 0 are inside the border. To prevent overlap between the drawing and the title, you need an outer panel around the drawing panel. The drawing panel is added into the outer panel. Fortunately, layout managers are aware of borders so they will place the drawing panel inside the border.
This does, however, create a problem for the GraphicsApplet class. It has a variable that refers to a DrawPanel. If it adds that variable directly to its content pane then the outer panel will not show up. To solve this problem, the DrawPanel class has a getOuterPanel() method that returns its outer panel. This method is invoked in the GraphicsApplet class and the return value is added to the content pane.
For this assignment, you will use four helper methods in the GraphicsApplet class.
The createSlider() helper has an additional advantage. You write code once for creating and configuring JSlider. Then you only need one additional line of code to create each of the eight JSlider controls.
Type | Name | Initialization |
---|---|---|
GraphicsApplet | applet | null |
TitledBorder | border | BorderFactory.createTitledBorder("TBA") |
JPanel | outerPanel | new JPanel() |
The constructor for the class should have a parameter of type GraphicsApplet. The first line of code in the constructor assigns this parameter to the applet variable. The preferred size should be set to 400 by 400. Then you set the background color to white, set the border of the outer panel with the border variable, set its layout manager with a BorderLayout, and add the draw panel to the center of the outer panel. The statement for the last part is
outerPanel.add(this, BorderLayout.CENTER);The Java keyword this refers to the object that you are writing code for, a DrawPanel instance in this case.
The last thing you need in the class is a method for getting the outer panel. The code for this is Its return type is JPanel and its name is getOuterPanel. It has no parameters. It contains a single statement that returns the outerPanel variable.
Before writing the init() method, you need a helper method for constructing and configuring the control panel. Begin with the following code.
JPanel createControlPanel() { JPanel controlPanel = new JPanel(); controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS)); return controlPanel; }This is similar to most method definitions that you have written except that the keyword public is missing at the beginning. Helper methods are intended for use only inside the class in which they are written. You only need the public keyword for methods that are used outside the class.
Now you will need to add two lines of code to set the minimum and preferred sizes of the control panel to 160 by 400. These should be added just before the return statement.
For now, you are done with this helper method. When controls are added in later steps, you will add a line of code for each control.
Finally, you need to write the applet init() method. You only need two lines of code in it that add a controlPanel (use createControlPanel()) and the outer panel of the draw panel (drawPanel.getOuterPanel()) to the left and center parts of the applet's content pane. Since the content pane has a BorderLayout by default, you will not need to set the layout manager.
After you have completed preliminary definitions of both classes then you should compile them to check for syntax errors.