Está en la página 1de 77

Session 3 - Exception-Handling

Java Programming
1
1
TCS Confidential
Applets and Event
Handling
Java Programming
Session 3 - Exception-Handling
Java Programming
2
2
TCS Confidential
Applets
Applet Basics
The Applet Architecture
Applet Initialization & Termination
Applet Restrictions
Writing a Simple Applet
Visualizing How an Applet Works
Session 3 - Exception-Handling
Java Programming
3
3
TCS Confidential
Applets
Simple Applet Display Methods
Overriding update()
Requesting Repainting - Threads
in Applets
Using the Status Window
The HTML APPLET Tag
Passing Parameters to Applets
Session 3 - Exception-Handling
Java Programming
4
4
TCS Confidential
Applet Basics
Applet
Applets are small application that
are accessed on an internet
server, Transported over the
Internet, Automatically installed
and run as part of an web
document.
Session 3 - Exception-Handling
Java Programming
5
5
TCS Confidential
Applet Basics
Component
Container
Panel
Applet
All applets
Session 3 - Exception-Handling
Java Programming
6
6
TCS Confidential
Applet Basics
Run Examples
From appletviewer
From Browser
Session 3 - Exception-Handling
Java Programming
7
7
TCS Confidential
Applet Basics
Provide support for
Applet execution (start and stop)
Load and display images
load and play audio clips.
Applets must import java.applet.*
and java.awt.*
Execution by Web browser or an
applet viewer provided by JDK
Session 3 - Exception-Handling
Java Programming
8
8
TCS Confidential
The Applet Architecture
AWT
Methods
SOP O/P
Only Few All main()
init() main() Begin with
Applet Normal
Class
Execution of
Session 3 - Exception-Handling
Java Programming
9
9
TCS Confidential
The Applet Architecture ...
This is a crucial point.
An applet should not maintain
control for an extended period.
An Additional thread must be started
for repetitive task.
Session 3 - Exception-Handling
Java Programming
10
10
TCS Confidential
The Applet Architecture ...
Second
The user initiates interaction with
an applet not the other way
round.
These interactions are sent to the
applet as events to which the
applet must respond.
Session 3 - Exception-Handling
Java Programming
11
11
TCS Confidential
The Applet Architecture ...
Control applets execution by
overriding set of methods.
init
start
stop
destroy
Session 3 - Exception-Handling
Java Programming
12
12
TCS Confidential
Applet Initialization and
Termination
Begins order
init()
start()
paint()
Termination order
stop()
destroy()
Session 3 - Exception-Handling
Java Programming
13
13
TCS Confidential
Applet Initialization and
Termination
init():
First method
Variables initialization
Called only once
Session 3 - Exception-Handling
Java Programming
14
14
TCS Confidential
Applet Initialization and
Termination
start():
It is called after init();
Called to restart an applet
User comes back to a web page
Session 3 - Exception-Handling
Java Programming
15
15
TCS Confidential
paint():
It is called each time
Restoring the applet window
Window overwritten
When applet begins execution;
paint() has one parameter of type
Graphics.
Applet Initialization and
Termination
Session 3 - Exception-Handling
Java Programming
16
16
TCS Confidential
Applet Initialization and
Termination
stop():
When a web browser leaves the
HTML document containing the
applet and goes to another page
destroy():
When the environment
determines that your applet needs
to be removed completely from
memory.
Session 3 - Exception-Handling
Java Programming
17
17
TCS Confidential
Applet Restrictions
Which are not enforced at compile
time.
Result in run-time exception.
Session 3 - Exception-Handling
Java Programming
18
18
TCS Confidential
Applet Restrictions
Applets may not
Read, write or delete files
Create or list directories
Check for the existence of a
file/properties
Session 3 - Exception-Handling
Java Programming
19
19
TCS Confidential
Applet Restrictions ...
Applets may not invoke a local
program
Create a network connection
Applets can read the file system
on the server it has been
downloaded from.
Session 3 - Exception-Handling
Java Programming
20
20
TCS Confidential
Applet Restrictions ...
These restrictions can be
overwhelming.
Be lifted for applets from a trusted
source.
Signing of an applet
Information is encoded that proves
that the applet can be trusted.
Session 3 - Exception-Handling
Java Programming
21
21
TCS Confidential
Demo of SampleApplet.java
// Writing a Simple Applet
public class SampleApplet extends Applet {
String msg;
// Initial settings.
public void init() {msg = "In init() -- ";
setBackground(Color.cyan);
setForeground(Color.red);
}
public void start(){msg += "In start() -- "; }
public void stop() {msg = ""; }
// Display msg
public void paint(Graphics g) {
msg += "In paint().";
g.drawString(msg, 50, 150); }
}
Session 3 - Exception-Handling
Java Programming
22
22
TCS Confidential
Compiling/Running an Applet
The applet subclass must be
declared as public, because it will
be accessed by code that is outside
the program.
Compile the program in the same
way used for other Java programs:
javac SampleApplet.java
There are three ways to run the
applet.
Session 3 - Exception-Handling
Java Programming
23
23
TCS Confidential
Compiling/Running an Applet
1.Executing within a Java-
compatible Web browser:
Create file apv.html
<applet code = SampleApplet
width = 200 height = 80> </applet>
Session 3 - Exception-Handling
Java Programming
24
24
TCS Confidential
Compiling/Running an Applet ...
2.Above html file can also be
executed from command line as
follows at the DOS prompt:
D:\suryoday> appletviewer
apv.html
Session 3 - Exception-Handling
Java Programming
25
25
TCS Confidential
Compiling/Running an Applet ...
3. Include the contents of the html file
at the head (after includes) of your
Java source code file.
D:\suryoday> appletviewer
MovingBanner.java
Applet Viewer: SampleApplet.class
In init() -- In start() -- In paint()
Applet
Applet started.
Session 3 - Exception-Handling
Java Programming
26
26
TCS Confidential
Visualizing How an Applet Works
Applet Code
Applet Code
Javac compiler
Javac compiler
byte
code
.class file
byte code
.class file
HTML
envelope
Hello.java
Hello.class
Hello.html
Java enabled
Browser
OUTPUT
Java enabled
Browser
OUTPUT:
Hello,World!
Java Run-time
Environment
Classes.zip
Java Run-time
Environment
Classes.zip
Session 3 - Exception-Handling
Java Programming
27
27
TCS Confidential
Applet Display Methods
void drawString(String msg, int
x, int y)
Member of Graphics class.
update() or paint().
Session 3 - Exception-Handling
Java Programming
28
28
TCS Confidential
Applet Display Methods
void setBackground(Color
newColor)
void setForeground(Color newColor)
The colors can be changed during
execution.
Session 3 - Exception-Handling
Java Programming
29
29
TCS Confidential
Applet Display Methods
Current setting of
background/foreground color can
be obtained by
getBackground()/getForeground().
Session 3 - Exception-Handling
Java Programming
30
30
TCS Confidential
Overriding update()
Change default color in the Update
methods instead of Paint method.
public void update(Graphics g) {
// Redisplay the window, here. }
public void paint(Graphics g) {
update(g); }
Session 3 - Exception-Handling
Java Programming
31
31
TCS Confidential
Requesting Repainting
One of architectural constraints
imposed on applet is that
it must quickly return control to the
AWT run-time system.
If the applet is displaying a moving
banner, how can it itself update the
window for its changing contents?
Session 3 - Exception-Handling
Java Programming
32
32
TCS Confidential
Requesting Repainting
It cannot create a loop inside paint()
Well, it can simply call repaint()
whenever it needs to update the
information to be displayed.
In turn, update() is called which then
calls paint() by default.
Since the scrolling of message is a
repetitive task, it should be performed by
a separate thread created by applet when
it is initialized.
Session 3 - Exception-Handling
Java Programming
33
33
TCS Confidential
Demo of MovingBanner.java
Threads in applets: This applet scrolls a
message, from right to left, across the applets
window with the help of a thread.
import java.awt.*;
import java.applet.*;
public class MovingBanner extends Applet implements
Runnable {
String msg = HELLO WORLD;
Thread t = null; boolean stopFlag;
public void init() { // set colors
setBackground(Color.cyan);
setForeground(Color.red);
} // end of init
Session 3 - Exception-Handling
Java Programming
34
34
TCS Confidential
MovingBanner.java ...
public void start( ) { // start thread
t = new Thread(this);
stopFlag = false; t.start();
} // end of start
public void run() { char ch;
for ( ; ; ) {
try {repaint();
Thread.sleep(250);
ch = msg.charAt(0);
msg = msg.substring(1, msg.length());
msg += ch;
if (stopFlag) break;
} catch(InterruptedException e) { }
}
}
Session 3 - Exception-Handling
Java Programming
35
35
TCS Confidential
MovingBanner.java ...
public void stop() {
stopFlag = true; t = null;
} // end of stop
public void paint(Graphics g) {
g.drawString(msg,100,100);
} // end of paint
} // end of class MovingBanner
Applet Viewer: MovingBanner.class
WORLD HELLO
Applet
Applet started.
Sample
Output:
Session 3 - Exception-Handling
Java Programming
36
36
TCS Confidential
Using the Status Window
Also output a message to status window of the
browser or applet viewer.
By calling showStatus().
Lets write paint() again:
public void paint(Graphics g) {
g.drawString(msg,10,10);
showStatus(This is shown in status
window.);
}
Applet Viewer: MovingBanner.class
HELLO WORLD
Applet
This is shown in status window.
Session 3 - Exception-Handling
Java Programming
37
37
TCS Confidential
The HTML APPLET Tag
The APPLET tag is used to start
an applet.
An applet viewer will execute
each APPLET tag in a separate
window
Browsers allow many applets on
a single page.
Syntax of Applet tag
Session 3 - Exception-Handling
Java Programming
38
38
TCS Confidential
The HTML APPLET Tag
<APPLET [CODEBASE = codebaseURL] CODE =
appletFile
[ALT = alternateText] [NAME = appletInstanceName]
WIDTH = pixels HEIGHT = pixels
[ALIGN =alignment] [VSPACE =pixels] {HSPACE
=pixels]
>
[<PARAM NAME = pname VALUE = pvalue >]
[< PARAM NAME = pname VALUE = pvalue >

[HTML displayed in the absence of Java]


</APPLET>
Session 3 - Exception-Handling
Java Programming
39
39
TCS Confidential
Demo of ParamDemo.java
// Passing Parameters to Applets
import java.awt.*;
import java.applet.*;
/*<applet code=ParamDemo width=600 height=400>
<param name=font value=TimesNewRoman>
<param name=size value=24>
<param name=leading value=25.68>
</applet> */
public class ParamDemo extends Applet {
String fontName;
int fontSize;
float leading;
Session 3 - Exception-Handling
Java Programming
40
40
TCS Confidential
ParamDemo.java ...
public void start( ) { String param;
fontName = getParameter(font);
if (fontName.equals("")) fontName=Not Found;
param = getParameter(size);
try { if (param.equals("")) fontSize = 0;
else fontSize = Integer.parseInt(param);
} catch(NumberFormatException e) {fontSize=-1;}
param = getParameter(leading);
try { if (param.equals("")) leading = 0;
else leading=Float.parseFloat();
} catch(NumberFormatException e) {leading=-1;}
}
Session 3 - Exception-Handling
Java Programming
41
41
TCS Confidential
ParamDemo.java ...
public void paint(Graphics g) {
g.drawString(Font name: + fontName, 40, 50);
g.drawString(Font size: + fontSize, 40, 150);
g.drawString(Leading: + leading, 40, 200);
}
}
Applet Viewer: ParamDemo
Font name: TimesNewRoman
Font size: 24
Leading: 25.68
Applet
Applet started.
Session 3 - Exception-Handling
Java Programming
42
42
TCS Confidential
Event Handling
Event Classes
Sources of Events
Event Listeners and Interfaces
Handling Mouse Events
Handling Keyboard events
Session 3 - Exception-Handling
Java Programming
43
43
TCS Confidential
Event Handling
Applets are event-driven programs.
The most-commonly handled events
are clicking of a mouse, pressing
keyboard keys and controls like
push button. Events are supported
by java.awt.event package. In old
Java 1.0 approach, an event was
propagated up the containment
hierarchy until it was handled by a
component, wasting valuable time.
Session 3 - Exception-Handling
Java Programming
44
44
TCS Confidential
Event Handling
The modern approach to handling
events is based on the delegation
event model in which listeners must
register with a source in order to
receive an event notification. A
Source generates an event and
sends it to one or more listeners The
listener processes the event and
then returns.
Session 3 - Exception-Handling
Java Programming
45
45
TCS Confidential
Event Handling ...
An event is an object that describes a
state change in a source. It can be
generated due to interaction with the
elements of a graphical user interface -
pressing a button, keying a character,
selecting an item in a list, and clicking
the mouse. Other events may also occur
like a timer expires, counter exceeds a
value, soft/hardware failure occurs, etc.
source
listener
listener
Session 3 - Exception-Handling
Java Programming
46
46
TCS Confidential
Event Handling ...
Source is an object that
generates an event. Sources
may generate more than one
type of events.
A listener is an object that is
notified when an event occurs.
Session 3 - Exception-Handling
Java Programming
47
47
TCS Confidential
Event Classes
The classes that represent events
are the core of Javas event
handling mechanism. The
superclass of all events is
EventObject which is in java.util.
AWTEvent, defined within java.awt,
is a subclass of EventObject. It is a
superclass of all AWT events that
are handled by the delegation event
model.
Session 3 - Exception-Handling
Java Programming
48
48
TCS Confidential
Event Classes
Package java.awt.event defines
several types of events. Below
are enumerated the most
important of the event classes
of this package:
ActionEvent, AdjustmentEvent,
ComponentEvent,
ContainerEvent, FocusEvent, InputEvent,
ItemEvent, KeyEvent, MouseEvent,
TextEvent,
WindowEvent.
Session 3 - Exception-Handling
Java Programming
49
49
TCS Confidential
Sources of Events
Button
CheckBox
Option1 Option2
Text Components
Session 3 - Exception-Handling
Java Programming
50
50
TCS Confidential
Sources of Events
Here are some of the user interface
components that can generate events:
Event Source & Description
Button: causes action events when button is
pressed.
CheckBox: causes item events when
checkbox is (de)selected.
Choice : causes item events when choice is
changed.
List: causes action events when item is
double-clicked; causes item events when item
is (de)selected.
Session 3 - Exception-Handling
Java Programming
51
51
TCS Confidential
Sources of Events
Menu Item: causes action events when
menu item is selected; causes item
events when a checkable one is
(de)selected.
Scrollbar: causes adjustment events
when it is manipulated.
Text Components: causes text events on
a character entry.
Window: causes window events when a
window is activated, closed, deactivated,
opened, quit, (de)iconified.
Session 3 - Exception-Handling
Java Programming
52
52
TCS Confidential
Event Listeners and Interfaces
Event listeners are objects that
are notified when an event
occurs. The methods that
receive and process events are
defined in a set of interfaces
found in java.awt.event package:
Session 3 - Exception-Handling
Java Programming
53
53
TCS Confidential
Event Listeners and Interfaces
ActionListener
actionPerformed(ActionEvent)
AdjustmentListener
adjustmentValueChanged(AdjustmentEv
ent)
ComponentListener
componentResized(ComponentEvent e)
componentMoved(ComponentEvent e)
componentShown(ComponentEvent e)
componentHidden(ComponentEvent e)
Session 3 - Exception-Handling
Java Programming
54
54
TCS Confidential
Event Listeners and Interfaces
MouseListener
mouseClicked(MouseEvent e)
mousePressed(MouseEvent e)
mouseReleased(MouseEvent e)
mouseEntered(MouseEvent e)
mouseExited(MouseEvent e)
MouseMotionListener
mouseDragged(MouseEvent e)
mouseMoved(MouseEvent e)
Session 3 - Exception-Handling
Java Programming
55
55
TCS Confidential
Event Listeners and Interfaces
TextListener
textValueChanged(TextEvent e)
WindowListener
windowOpened(WindowEvent e)
windowClosing(WindowEvent e)
windowClosed(WindowEvent e)
windowIconified(WindowEvent e)
windowDeiconified(WindowEvent e)
windowActivated(WindowEvent e)
windowDeactivated(WindowEvent e)
Session 3 - Exception-Handling
Java Programming
56
56
TCS Confidential
Event Listeners and Interfaces
FocusListener
focusGained(FocusEvent e)
focusLost(FocusEvent e)
ItemListener
itemStateChanged(ItemEvent e)
KeyListener
keyTyped(KeyEvent e)
keyPressed(KeyEvent e)
keyReleased(KeyEvent e)
Session 3 - Exception-Handling
Java Programming
57
57
TCS Confidential
Demo of MouseEvents.java
Handling Mouse Events: The MouseListener
and the MouseMotionListener interfaces must
be implemented to handle the mouse events.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class MouseEvents extends Applet
implements
MouseListener, MouseMotionListener {
String msg = " ";
int mouseX = 0, mouseY = 0; // coordinates of
mouse
public void init() {addMouseListener(this);
addMouseMotionListener(this);
Session 3 - Exception-Handling
Java Programming
58
58
TCS Confidential
MouseEvents.java ...
public void mouseClicked(MouseEvent me) {
msg = Mouse clicked.;
mouseX=0; mouseY=10; repaint();
} // Handling mouse clicked.
public void mouseEntered(MouseEvent me) {
msg = Mouse entered.;
mouseX=0; mouseY=10; repaint();
} // Handling mouse entered.
public boolean mouseExited(MouseEvent me)
{
msg = Mouse exited.;
mouseX=0; mouseY=10; repaint();
}
Session 3 - Exception-Handling
Java Programming
59
59
TCS Confidential
MouseEvents.java ...
public void mousePressed(MouseEvent me) {
mouseX = me.getX(); mouseY = me.getY();
msg = Down"; repaint( );
} // Handling mouse pressed.
public void mouseReleased(MouseEvent me) {
mouseX = me.getX(); mouseY = me.getY();
msg = Up"; repaint( );
} // Handling mouse released
public void mouseMoved(MouseEvent me) {
showStatus(Moving mouse at +
me.getX() + , + me.getY()); // Handling
mouse moved.
}
Session 3 - Exception-Handling
Java Programming
60
60
TCS Confidential
MouseEvents.java ...
public void mouseDragged(MouseEvent me) {
mouseX = me.getX(); mouseY = me.getY();
msg = *";
showStatus(Dragging mouse at +
mouseX + , + mouseY);
repaint( );
} // Handling Mose dragged
public void paint(Graphics g) {
g.drawString(msg, mouseX, mouseY);
} // Display msg in applet window at current
} // X,Y location.
Session 3 - Exception-Handling
Java Programming
61
61
TCS Confidential
Handling Keyboard events
On pressing a key, a
KEY_PRESSED event is generated;
this results in a call to keyPressed()
event handler. When the key is
released, a KEY_RELEASED event
is generated and the keyReleased()
handler is executed. If a character
is generated by the keystroke, then
KEY_TYPED event is sent and
keyTyped() handler is invoked.
Session 3 - Exception-Handling
Java Programming
62
62
TCS Confidential
Handling Keyboard events
Thus, on each key-press at least 2
and often 3 events are generated. If
we care about only the actual
characters, the key press and
release events can be ignored, but
to handle special keys (arrow /
function keys), the key press events
must watch for them through
keyPressed() handler. Next program
demonstrates keyboard input.
Session 3 - Exception-Handling
Java Programming
63
63
TCS Confidential
Demo of SimpleKey.java
// Demo of Keyboard Events
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class SimpleKey extends Applet
implements KeyListener {String msg = ;
int X = 10, Y = 20; // output coordinates
public void init() { addKeyListener(this);
requestFocus();} // request input focus
public void keyPressed(KeyEvent ke)
{ showStatus(Key Down); }
Session 3 - Exception-Handling
Java Programming
64
64
TCS Confidential
SimpleKey.java ...
public void keyReleased(KeyEvent ke) {
showStatus(Key UP);
}
public void keyTyped(KeyEvent ke) {
msg += ke.getKeyChar( ); repaint( );
}
public void paint(Graphics g) {
g.drawString(msg, X, Y);
}
}
Session 3 - Exception-Handling
Java Programming
65
65
TCS Confidential
Creating animation using thread
Animation is an ideal use of threads
The program given below creates an animation
and plays a sound as well in the background
import java.awt.*;
import java.applet.AudioClip;
public class ImageAnim extends
java.applet.Applet implements Runnable {
Image pics[]=new Image[10];
Image currimage;
AudioClip c1;
Thread timage;
Session 3 - Exception-Handling
Java Programming
66
66
TCS Confidential
Creating animation using thread

public void init() {


String picsource[]={"T1.gif","T2.gif","T3.gif","T4.gif",
"T5.gif","T6.gif","T7.gif","T8.gif","T9.gif", "T10.gif"};
for (int i=0;i<10;i++)
pics[i]=getImage(getCodeBase(),"image/"+ picsource [i]);
c1 = getAudioClip(getCodeBase(),"ding.au");
}
public void start() {
if (timage==null) {
timage = new Thread(this);
timage.start();
}
}
Session 3 - Exception-Handling
Java Programming
67
67
TCS Confidential
Creating animation using thread

public void stop() {


timage=null;
if (c1!=null) c1.stop();
}
public void run() {
setBackground(Color.pink);
int i=0;
Thread thisThread=Thread.currentThread();
while(timage == thisThread) {
currimage = pics[i];
repaint();
Session 3 - Exception-Handling
Java Programming
68
68
TCS Confidential
Creating animation using thread

if (c1!=null) c1.loop();
try { Thread.sleep(1000);
} catch(InterruptedException e) {}
i++;
if (i==pics.length) i=0;
}
}
public void paint(Graphics g) {
if (currimage != null)
g.drawImage(currimage,10,40,this);
}
}
Session 3 - Exception-Handling
Java Programming
69
69
TCS Confidential
Reducing Animation Flickering
While creating animation, a call
to repaint() method is made
The repaint() method in turn
calls update() method before
calling paint() method
The update() method clears the
screen which in turn causes
animation flickering
Session 3 - Exception-Handling
Java Programming
70
70
TCS Confidential
Reducing Animation Flickering
Animation flickering can be
reduced if the update() method s
overridden in your application
public void update(Graphics g) {
paint(g); }
Sometimes animation flickering
persists even after overriding
update() method
Session 3 - Exception-Handling
Java Programming
71
71
TCS Confidential
Reducing Animation Flickering
In such a case double-buffering
technique can be used that
eliminates flickering
In double-buffering, the entire
frame is first painted on a non-
visible area called buffer
Then this frame is printed on the
screen
Session 3 - Exception-Handling
Java Programming
72
72
TCS Confidential
Double Buffering
However, double buffering takes
a lot of memory space and isnt
always the most efficient method
to reduce flickering
The following program shows
the movement of a ball along a
trajectory
Session 3 - Exception-Handling
Java Programming
73
73
TCS Confidential
Double Buffering
import java.awt.*;
public class BallWithBuff extends java.applet.Applet
implements Runnable {
Thread t;
int xPos=5, yPos=5;
int xMove=2, yMove=4;
Session 3 - Exception-Handling
Java Programming
74
74
TCS Confidential
Double Buffering
Image offscreenImage;
Graphics offscreeng;
public void init() {
offscreenImage = createImage(getSize().width,
getSize().height );
offscreeng=offscreenImage.getGraphics(); }
public void start() {
if (t==null) {
t=new Thread(this);
t.start();
}
}
public void stop() {t=null;}
Session 3 - Exception-Handling
Java Programming
75
75
TCS Confidential
Double Buffering
public void run() {
Thread currThread =
Thread.currentThread();
while(t == currThread) {
xPos+=xMove;
yPos+=yMove;
if (yPos>=300) yMove*=-1;
if (yPos<=0) {
yMove*=-1;
xMove*=-1;
}
repaint();
try{ Thread.sleep(100);
} catch (InterruptedException e){}
}
}
Session 3 - Exception-Handling
Java Programming
76
76
TCS Confidential
Double Buffering
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
offscreeng.setColor(Color.yellow);
offscreeng.fillRect(0,0,360,351);
offscreeng.setColor(Color.red);
offscreeng.fillOval(xPos,yPos,50,50);
g.drawImage(offscreenImage,0,0,this);
}
public void destroy() {
offscreeng.dispose();
}
}
Session 3 - Exception-Handling
Java Programming
77
77
TCS Confidential
Summary
Participants are familiarized with the:
Java threads - the Thread class, thread states,
priorities, synchronization, the Runnable
interface and creating threads.
Applet - architecture, initialization &
termination, restrictions, display methods,
writing simple applets, the HTML APPLET Tag,
and passing parameters to applets.
Event - classes, sources of events, event
listeners and interfaces, handling mouse and
keyboard events.
Creating animation using thread

También podría gustarte