A Simple Paint Applet
The applet's real estate is the area within the border
Source
ASimplePaintApplet.java:
import java.applet.*;
import java.awt.*;
public class ASimplePaintApplet extends Applet {
public void init() {
Scrollbar lengthAdjuster = new Scrollbar(Scrollbar.HORIZONTAL, 30, 0, 0, 100);
TextField lengthDisplay = new TextField(3);
lengthDisplay.setEditable(false);
TextField thicknessDisplay = new TextField(3);
thicknessDisplay.setEditable(false);
Button thicker = new Button("Thicker");
Button thinner = new Button("Thinner");
Button lucky = new Button("Feeling Lucky?");
PaintCanvas paintCanvas = new PaintCanvas(lengthAdjuster, thicker, thinner, lucky,
lengthDisplay, thicknessDisplay);
setLayout(new BorderLayout());
add(paintCanvas, BorderLayout.CENTER);
Panel buttonPanel = new Panel();
buttonPanel.setLayout(new GridLayout(0, 1));
buttonPanel.add(thinner);
buttonPanel.add(thicknessDisplay);
buttonPanel.add(thicker);
buttonPanel.add(lucky);
add(buttonPanel, BorderLayout.EAST);
Panel scrollPanel = new Panel();
scrollPanel.add(lengthAdjuster);
scrollPanel.add(lengthDisplay);
add(scrollPanel, BorderLayout.SOUTH);
}
}
PaintCanvas.java:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
class PaintCanvas extends Canvas implements ActionListener, AdjustmentListener {
PaintCanvas(Scrollbar lengthAdjuster, Button thicker, Button thinner, Button lucky,
TextField lengthDisplay, TextField thicknessDisplay) {
this.lengthAdjuster = lengthAdjuster;
this.thicker = thicker;
this.thinner = thinner;
this.lucky = lucky;
this.lengthDisplay = lengthDisplay;
this.thicknessDisplay = thicknessDisplay;
lengthAdjuster.addAdjustmentListener(this);
thicker.addActionListener(this);
thinner.addActionListener(this);
lucky.addActionListener(this);
setSize(200, 200);
centerX = getWidth() / 2;
centerY = getHeight() / 2;
length = lengthAdjuster.getValue();
lengthDisplay.setText(length+"");
thicknessDisplay.setText(thickness+"");
setBackground(new Color(15, 150, 200));
}
private void makeThicker() {
thickness += 1;
thicknessDisplay.setText(thickness+"");
repaint();
}
private void makeThinner() {
thickness -= 1;
thicknessDisplay.setText(thickness+"");
repaint();
}
private void makeRandomThickness() {
Random random = new Random();
thickness = random.nextInt(20)+1;
thicknessDisplay.setText(thickness+"");
repaint();
}
public void paint(Graphics g) {
for (int i = 0; i < thickness; i++) // Draw 'thickness' number of adjacent lines
g.drawLine(centerX-(length/2), centerY+i, centerX+(length/2), centerY+i);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == thicker)
makeThicker();
else if (e.getSource() == thinner)
makeThinner();
else
makeRandomThickness();
}
public void adjustmentValueChanged(AdjustmentEvent e) {
length = lengthAdjuster.getValue(); // Only one scrollbar, no need for getSource() invocation
lengthDisplay.setText(length+"");
repaint();
}
Scrollbar
lengthAdjuster;
TextField
lengthDisplay,
thicknessDisplay;
int
centerX,
centerY,
length,
thickness = 1;
Button
thicker,
thinner,
lucky;
}
Description and Objective
A simple, minmally-featured, paint applet.The applet allows the user to control the length and thickness
of a displayed line.
- Illustrates how to combine the various interface elements covered in the previous applets.
- Illustrates the use of multiple panels for increased layout control
Notes
This Applet's Behavior
Overview / Basic Structure
- Since we don't want our interface components (buttons, scollbars, etc) to interfere
with our graphics, we will introduce a Canvas subclass, PaintCanvas, for our drawing.
- As before:
- The Applet subclass, ASimplePaintApplet, will be responsible for
- creating the interface elements
- performing the layout (using Panel and Layout objects)
- PaintCanvas will be responsible for
- listening and reacting to the components (event handling methods)
- maintaing its display (paint method)
The Applet Subclass, ASimplePaintApplet
- The various interface elements are first created (in the init method):
- A scroll bar to control the length of the displayed line
- Note the scrollbar's initial value
- A trio of buttons to control the line's thickness
- The 'Feeling Lucky?" button generates a random value for the line thickness
- Text boxes to display the current values line length and thickness
- These are set to non-editable since we intend for them to be read-only
- The canvas upon which the line is displayed
- When creating the PaintCanvas, the various interface elements are passed
to its constructor.
- The elements are then laid out using Panels and various layouts
- A BorderLayout is used for the applet's top-level
- The canvas is placed in the center
- The buttons and their text display go on the right (EAST)
- The scrollbar and its display go on the bottom (SOUTH)
- A Panel using a GridLayout is created for the buttons and their associated text field
- This provides a 2-dimensional grid upon to which the elements
can be added.
- There are several useful constructors
- The one used here uses the convention that a value of 0 for either
the rows or cols parameter allows a variable number of elements to
be added to either the row or column respectively
- This applet specified 0 rows and 1 col which means that there will
be one column with as many rows as we add to the panel.
- A Panel is created for the scrollbar and its associated text field
- FlowLayout, the default layout for Panel is used (i.e., no explicit overriding
layout is specified)
The Canvas subclass, PaintCanvas
- Once the elements have been created and laid out, PaintCanvas does most of the work
- Overview of PaintCanvas' behavior
- Manipulating the scrollbar causes the line to get longer and shorter
- The paint method draws a line whose length corresponds to the value of the length instance
variable
- There is no thickness parameter when drawing a line, therefore to get a thicker line,
the canvas draws several lines, one right immediately beneath the other
- The number of lines drawn corresponds to the thickness instance variable
- When an adjustment event occurs, the value of the scrollbar is retrieved and
stored into the length instance variable
- Whenever a value that affects the display is modified, repaint is invoked to
cause the display to be refreshed.
- The constructor
- The parameters corresponding to the interface components are saved in instance variables
- The canvas registers itself as a listener for the various events
- action for the buttons
- adjustment for the scrollbar
- The canvas specifies it size
- The location of the center of the line is set to the center of the canvas
- The instance variable for the length is initialized from whatever the initial value of the scrollbar
is set to (in ASimplePaintApplet)
- The content of the text fields are set to their respective value
- A background color is specified for the canvas
- The paint method
- The canvas draws as many lines as are specified by the thickness instance variable
- Using y+i causes the y value to be increased by 1 each time through the loop
- This causes each succesive line to be drawn directly beneath the previous
- Each line (horizontally) centers around the centerX instance variable
- The actionPerformed method (button event handler)
- getSource is used to determine which button generated the event
- Although the modification of the thickness variable is simple enough (simple
increment or decrement tha variable), and could be done in place in actionPerformed,
the canvas illustrates the common technique of introducing methods to handle
the effect of each component (in this case the methods makeThicker, makeThinner,
and makeRandomThickness to handle the effect of the event generated by the thicker,
thinner, and 'feeling lucky?' buttons)
- The adjustmentValueChanged method (scrollbar event handler)
- In contrast to the actionPerformed methid, this event handler performs the event-handling
logic in place (i.e., in the method itself)
- The (adjusted) value of the scrollbar is retrieved and used to update the length instance variable
as well as the value in the associated text field
- repaint is invoked to refresh the display
- The new length should be used to redraw the line
- The makeThicker/makeThinner methods
- These methods
- increment/decrement the thickness variable
- update the associated text field
- invoke repaint for a refresh
- The makeRandomThickness method
- A Random object is created and an invocation of the nextInt
method is used to generate a random value for the thickness variable
- An arbitrary limit of 20 is specified as the parameter to nextInt
to keep the thickness of the line within reason
- The text field is updated, and again, repaint is invoked for a refresh
Things to Do
Playing with the Applet
Combine the following modifications into a single applet:
- Use panels to make the buttons look presentable
- Add logic to prevent the thickness from going below 0, getting too large, or both
- Use a scrollbar (instead of buttons) to control the thickness
- Add interface elements (buttons are probably the easiest) to
- move the line
- allow the user to select a different shape (instead of a line)