In many ways, Swing is an easier to use alternative to AWT. We're going to build GUIs using Swing classes
rather than AWT classes because Swing is easier. Caveat! I have found that JButton
doesn't work the way I expect. For this reason, I use java.awt.Button
rather than javax.swing.JButton
.
We've already been importing the package javax.swing.*
so
that we could use JApplet
as a base class for our applets.
We could have been using Applet
as our base class (only would need java.awt.*),
but JApplet
simplifies the use of containers for GUIs.
start(), stop(), isRunning(), setDelay()
.
actionPerformed()
, which is the code that is executed when a timer "goes off."
java.util.Timer
.
We don't want to use that one. We want to use javax.swing.Timer
.
Timer(int delay, ActionListener listener)
delay
milliseconds.
The newly created Timer
object has one ActionListener
associated with it (listener).
RectRand.java
draws a black rectangle at a random location. Every time you run the applet,
the rectangle will appear at a different location.
I copy RecRand's paint()
here:
public void paint(Graphics g) { x = gen.nextInt(screenWidth - xsize); y = gen.nextInt(screenHeight - ysize); g.fillRect(x, y, xsize, ysize); }
Timer1.java
,
I add a timer that fires every 1000 milliseconds.
When the timer fires, the actionPerformed
code executes.
The actionPerformed
code
arranges for paint()
to be executed in the (near) future:
clearing the previous rectangle, then calculating new x,y position and drawing the rectangle.
paint()
is ok for a singler Timerpaint()
seems reasonable -
it's exactly the same as it was in RectRand
,
however, CAVEAT actually it's peculiar and only works
because there's only one timer. With one timer, it is still reasonable to
override paint()
by using it to directly draw on the relevant Component
whenever the state of the applet changes.
However, if you have different objects moving independently, and you want the
graphics image to display that, you'll need to use repaint()
as shown in a later example.
public void paint(Graphics g) // for RectRand.java { g.clearRect(x, y, xsize, ysize); x = gen.nextInt(screenWidth - xsize); y = gen.nextInt(screenHeight - ysize); g.fillRect(x, y, xsize, ysize); }The timer listener arranges for the drawing of a new rectangle whenever the timer fires:
class TimerListener implements ActionListener { public void actionPerformed(ActionEvent e) { repaint(); // arranges for paint() } }
paint()
is automatically made ready to run whenever needed.
If the applet needs to paint()
itself, then your code will
call repaint()
.
In this second example of using the Swing Timer,
Timer2.java
,
I have two different rectangles that are moving at different intervals. The first
timer (timer1
) moves (randomly) the first rectangle (b1) every 1 second.
The second timer (timer2) moves the second rectangle, b2, every 0.5 second.
You'll notice that paint()
only draws b1 and b2. paint()
is invoked by the TimerListeners whenever their relative timers go off.
The timers, as stated in the previous paragraph, update the position of the
relative box and calls repaint()
(forcing the paint()
method to redraw the current position of b1 and b2.
ButtonDemo.java
is an easy one that
controls a text string drawn on the canvas.
Here is the relevant code:
public class ButtonDemo extends Applet implements ActionListener { String msg = ""; Button yes, no, maybe; public void init() { yes = new Button("YES"); no = new Button("NO"); maybe = new Button("MAYBE"); add(yes); add(no); add(maybe); yes.addActionListener(this); no.addActionListener(this); maybe.addActionListener(this); } public void actionPerformed (ActionEvent e) { String str = e.getActionCommand(); if (str.equals("YES")) msg = "You pressed YES"; else if (str.equals("NO")) msg = "You pressed NO"; else if (str.equals("MAYBE")) msg = "You pressed maybe"; else msg = "UH OH!!!"; repaint(); }
Button (java.awt.Button)
rather than
JButton (javax.swing.JButton)
.
Since I'm not using any Swing component the class ButtonDemo extends Applet
(not Japplet
).
ButtonDemo implements ActionListener
,
rather than defining a new class that implements ActionListener.
ButtonDemo implements ActionListener
, ButtonDemo
must implement actionPerformed()
. Each button is linked to
its actionPerformed
through a statement like, e.g.,
yes.addActionListener(this)
.
actionPerformed
must distinguish between different events (there are three different events).
It does this through the getActionCommand()
method.
start()
and stop()
method.
In Timer1a.java
, I've added a start button and a stop button.
The start button with turn on Timer timer with timer.start()
.
The stop button will turn off timer with timer.stop()
.
Each button will have an ActionListener
that listens for the button press.
More generally, you can use the <applet> tag in an HTML page:
<applet code="Circles1.class" width="350" height="350">
Java applet that draws circles.
</applet>
For an example html document see Circles1.html, and view the
source.