This document discusses different approaches for implementing multithreaded graphics in Java, including: redrawing everything in paint, having other routines draw directly on the window, overriding update to do incremental painting, and using double buffering. It provides code examples for each approach and discusses their advantages and disadvantages in terms of flicker, efficiency, and handling overlapping graphics. It also covers using timers to control animations.
The game API is one of the most interesting and unique concepts of Java ME. It consists of very useful classes that help you with typical tasks that are required in almost ever game — for example sprite handling, tiled backgrounds or collision detection. This module will explain those concepts and how to create an own game loop. The challenge is the largest project yet and involves writing your own game called "Schlabo". The player moves his avatar at the bottom of the screen and has to shoot the enemy that moves randomly at the top.
Contents:
* Performance
* Game API
* Game loop
* GameCanvas
* Bitmaps
* Sprite
* Layer and TiledLayer
* LayerManager
Currently, Java ME is mainly used for games. Especially there it is very important to know how to handle the low level graphics facilities that are available in Java ME. This includes directly drawing to the screen as well as handling key input yourself. Most major applications also implement their own user interface themselves instead of using the high level UI provided by Java ME. The first challenge of this module is a simply key code analyzer so that you can familiarize yourself with the concepts of the Canvas and event processing. The second challenge is more sophisticated and requires you to write a small paint application.
Contents:
* Canvas
* Key Events
* Game Actions
* Geometry and Text
* Images
* PNG Optimization
Современный мир – это мир конкуренции. И любое преимущество перед другими может сыграть большую роль в бизнесе. Разработчиков в области 3D становится всё больше. Креативные дизайнеры изобретают всё более улётные проекты, и чтобы оставаться в тренде, нужно идти в ногу со временем. Я познакомлю вас с крутыми проектами и научу, как просто сделать 3D на сайте. Может и у вас появятся собственные идеи, как применить новейшие технологии уже сейчас!
Портируем существующее Web-приложение в виртуальную реальность / Денис Радин ...Ontico
РИТ++ 2017, Frontend Сonf
Зал Мумбаи, 5 июня, 17:00
Тезисы:
http://frontendconf.ru/2017/abstracts/2478.html
Виртуальная реальность - мощный тренд, который до текущего момента обходил стороной веб-разработчиков. Данный доклад о том, как интегрировать существующие Web-приложения в миры виртуальной реальности, предоставляя вашим пользователям новые возможности и UX, а себе дозу фана.
Должны ли мы использовать CSS или WebGL для проброса приложения в VR?
Какие решения доступны на текущий момент, и каких ошибок стоит остерегаться?
Почему HTML так же хорош для разработки VR-интерфейсов, как и для обычного, плоского Web?
Как веб-разработчик может быть частью VR-революции?
The game API is one of the most interesting and unique concepts of Java ME. It consists of very useful classes that help you with typical tasks that are required in almost ever game — for example sprite handling, tiled backgrounds or collision detection. This module will explain those concepts and how to create an own game loop. The challenge is the largest project yet and involves writing your own game called "Schlabo". The player moves his avatar at the bottom of the screen and has to shoot the enemy that moves randomly at the top.
Contents:
* Performance
* Game API
* Game loop
* GameCanvas
* Bitmaps
* Sprite
* Layer and TiledLayer
* LayerManager
Currently, Java ME is mainly used for games. Especially there it is very important to know how to handle the low level graphics facilities that are available in Java ME. This includes directly drawing to the screen as well as handling key input yourself. Most major applications also implement their own user interface themselves instead of using the high level UI provided by Java ME. The first challenge of this module is a simply key code analyzer so that you can familiarize yourself with the concepts of the Canvas and event processing. The second challenge is more sophisticated and requires you to write a small paint application.
Contents:
* Canvas
* Key Events
* Game Actions
* Geometry and Text
* Images
* PNG Optimization
Современный мир – это мир конкуренции. И любое преимущество перед другими может сыграть большую роль в бизнесе. Разработчиков в области 3D становится всё больше. Креативные дизайнеры изобретают всё более улётные проекты, и чтобы оставаться в тренде, нужно идти в ногу со временем. Я познакомлю вас с крутыми проектами и научу, как просто сделать 3D на сайте. Может и у вас появятся собственные идеи, как применить новейшие технологии уже сейчас!
Портируем существующее Web-приложение в виртуальную реальность / Денис Радин ...Ontico
РИТ++ 2017, Frontend Сonf
Зал Мумбаи, 5 июня, 17:00
Тезисы:
http://frontendconf.ru/2017/abstracts/2478.html
Виртуальная реальность - мощный тренд, который до текущего момента обходил стороной веб-разработчиков. Данный доклад о том, как интегрировать существующие Web-приложения в миры виртуальной реальности, предоставляя вашим пользователям новые возможности и UX, а себе дозу фана.
Должны ли мы использовать CSS или WebGL для проброса приложения в VR?
Какие решения доступны на текущий момент, и каких ошибок стоит остерегаться?
Почему HTML так же хорош для разработки VR-интерфейсов, как и для обычного, плоского Web?
Как веб-разработчик может быть частью VR-революции?
Shem will share development tips while explaining how things work under-the-hood. As part of his talk, he will demonstrate the right way of working with images, custom views, ListViews and Animations, with an emphasis of how to make your app feel slick and fast on all Android devices.
Ever since we broke apart the front and back-end of our systems, we’ve longed to partially reunite them with a shared language. The benefits of code reuse and shared tooling are compelling but is this nirvana possible? In this session we will explore building both the front (mobile and web) and back-end of an application with a shared Kotlin codebase. You will learn how to setup the build, share code, and deploy the back-end as a serverless app.
I wanted to change the cloudsrectangles into an actuall image it do.pdffeelinggifts
I wanted to change the clouds/rectangles into an actuall image it doesnt matter the image.
import javax.swing.*;
import java.awt.*;
/**
* Created by Thomas on 11/27/2016.
*/
public class Renderer extends JPanel{
//private static final long serialVersionUID = 1L;
protected void paintComponent(Graphics g) {
Main.main.repaint(g);
}
public static int clamp(int greenValue, int i, int j) {
// TODO Auto-generated method stub
return 0;
}
}
OTHER PART:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.*;
/**
* Created by Thomas on 11/27/2016.
*/
public class Main implements ActionListener, KeyListener{
public static Main main;
public final int WIDTH = 1400;
public final int HEIGHT = 600;
public HUD Hud;
public Renderer renderer;
public Rectangle character;
public ArrayList cloud;
public Random rand;
public boolean start = false, gameover = false;
public int tick;
public Main() {
JFrame jFrame = new JFrame();
Timer timer = new Timer(20, this);
renderer = new Renderer();
rand = new Random();
jFrame.setTitle(\"Example\");
jFrame.add(renderer);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setSize(WIDTH, HEIGHT);
jFrame.addKeyListener(this);
jFrame.setVisible(true);
cloud = new ArrayList();
character = new Rectangle(200, 220, 20, 20);
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
timer.start();
}
public void repaint(Graphics g) {
g.setColor(Color.black);
g.fillRect(0,0, WIDTH, HEIGHT);
g.setColor(Color.blue);
g.fillRect(0, HEIGHT - 100, WIDTH, 100);
g.setColor(Color.green);
g.fillRect(character.x, character.y, character.width, character.height);
if (character.y >= HEIGHT - 100 || character.y < 0) {
gameover = true;
}
for (Rectangle rect : cloud) {
g.setColor(Color.white);
g.fillRect(rect.x, rect.y, rect.width, rect.height);
}
g.setColor(Color.WHITE);
g.setFont(new Font(\"Times New Roman\", 1 ,100));
if (!start) {
g.drawString(\"Press to start!\", 450, HEIGHT / 2);
}
else if (gameover) {
g.drawString(\"Game Over!\", 450, HEIGHT / 2);
}
}
public void addCloud(boolean start) {
int width = 400;
int height = 200;
if (start) {
cloud.add(new Rectangle(WIDTH + width + cloud.size() * 300, rand.nextInt(HEIGHT-120),
80, 100));
}
else {
cloud.add(new Rectangle(cloud.get(cloud.size() - 1).x + 300, rand.nextInt(HEIGHT-120), 80,
100));
}
}
public void flap() {
if (gameover) {
character = new Rectangle(300, 400, 40, 40);
cloud.clear();
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
gameover = false;
}
if (!start) {
start = true;
}
else if (!gameover) {
character.y -= 70;
tick = 0;
}
}
@Override
public void actionPerformed(ActionEvent e) {
int speed = 15;
//System.out.println(\"Space\");
if (start) {
for (int i = 0; i .
Initially created for the Python User Group Freiburg meeting on December 11, 2013. Last updated November 2014.
Source, including codesamples, available at https://github.com/Felix11H/LaTeX-presentations-pygame_intro
Useful Tools for Making Video Games - XNA (2008)Korhan Bircan
A presentations I gave back in 2008 when I was the teaching assistant for Innovating Game Development course in Brown University.
This is an introductory tutorial of Microsoft XNA Game Studio. I talk about displaying 3D models, handling keyboard and mouse input, 3rd person shooter camera, and creating spline animations.
Shem will share development tips while explaining how things work under-the-hood. As part of his talk, he will demonstrate the right way of working with images, custom views, ListViews and Animations, with an emphasis of how to make your app feel slick and fast on all Android devices.
Ever since we broke apart the front and back-end of our systems, we’ve longed to partially reunite them with a shared language. The benefits of code reuse and shared tooling are compelling but is this nirvana possible? In this session we will explore building both the front (mobile and web) and back-end of an application with a shared Kotlin codebase. You will learn how to setup the build, share code, and deploy the back-end as a serverless app.
I wanted to change the cloudsrectangles into an actuall image it do.pdffeelinggifts
I wanted to change the clouds/rectangles into an actuall image it doesnt matter the image.
import javax.swing.*;
import java.awt.*;
/**
* Created by Thomas on 11/27/2016.
*/
public class Renderer extends JPanel{
//private static final long serialVersionUID = 1L;
protected void paintComponent(Graphics g) {
Main.main.repaint(g);
}
public static int clamp(int greenValue, int i, int j) {
// TODO Auto-generated method stub
return 0;
}
}
OTHER PART:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.*;
/**
* Created by Thomas on 11/27/2016.
*/
public class Main implements ActionListener, KeyListener{
public static Main main;
public final int WIDTH = 1400;
public final int HEIGHT = 600;
public HUD Hud;
public Renderer renderer;
public Rectangle character;
public ArrayList cloud;
public Random rand;
public boolean start = false, gameover = false;
public int tick;
public Main() {
JFrame jFrame = new JFrame();
Timer timer = new Timer(20, this);
renderer = new Renderer();
rand = new Random();
jFrame.setTitle(\"Example\");
jFrame.add(renderer);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setSize(WIDTH, HEIGHT);
jFrame.addKeyListener(this);
jFrame.setVisible(true);
cloud = new ArrayList();
character = new Rectangle(200, 220, 20, 20);
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
timer.start();
}
public void repaint(Graphics g) {
g.setColor(Color.black);
g.fillRect(0,0, WIDTH, HEIGHT);
g.setColor(Color.blue);
g.fillRect(0, HEIGHT - 100, WIDTH, 100);
g.setColor(Color.green);
g.fillRect(character.x, character.y, character.width, character.height);
if (character.y >= HEIGHT - 100 || character.y < 0) {
gameover = true;
}
for (Rectangle rect : cloud) {
g.setColor(Color.white);
g.fillRect(rect.x, rect.y, rect.width, rect.height);
}
g.setColor(Color.WHITE);
g.setFont(new Font(\"Times New Roman\", 1 ,100));
if (!start) {
g.drawString(\"Press to start!\", 450, HEIGHT / 2);
}
else if (gameover) {
g.drawString(\"Game Over!\", 450, HEIGHT / 2);
}
}
public void addCloud(boolean start) {
int width = 400;
int height = 200;
if (start) {
cloud.add(new Rectangle(WIDTH + width + cloud.size() * 300, rand.nextInt(HEIGHT-120),
80, 100));
}
else {
cloud.add(new Rectangle(cloud.get(cloud.size() - 1).x + 300, rand.nextInt(HEIGHT-120), 80,
100));
}
}
public void flap() {
if (gameover) {
character = new Rectangle(300, 400, 40, 40);
cloud.clear();
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
addCloud(true);
gameover = false;
}
if (!start) {
start = true;
}
else if (!gameover) {
character.y -= 70;
tick = 0;
}
}
@Override
public void actionPerformed(ActionEvent e) {
int speed = 15;
//System.out.println(\"Space\");
if (start) {
for (int i = 0; i .
Initially created for the Python User Group Freiburg meeting on December 11, 2013. Last updated November 2014.
Source, including codesamples, available at https://github.com/Felix11H/LaTeX-presentations-pygame_intro
Useful Tools for Making Video Games - XNA (2008)Korhan Bircan
A presentations I gave back in 2008 when I was the teaching assistant for Innovating Game Development course in Brown University.
This is an introductory tutorial of Microsoft XNA Game Studio. I talk about displaying 3D models, handling keyboard and mouse input, 3rd person shooter camera, and creating spline animations.
Android Studio (Java)The SimplePaint app (full code given below).docxamrit47
Android Studio (Java)
The SimplePaint app (full code given below) allows users to draw pictures by pressing the screen in the app.
The existing SimplePaint app allows users to draw using "circles" using the "SimpleDrawingView.java (using circles)" code given below. Add a button at the top of the app to allow users to toggle between drawing:
(a) using circle
(b) using path (path code is given below)
activity_main.xml
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
/>
MainActivity.java
package com.example.simplepaint;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
SimpleDrawingView.java (using circles)
package com.example.simplepaint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
public class SimpleDrawingView extends View {
// setup initial color
private final int paintColor = Color.BLACK;
// defines paint and canvas
private Paint drawPaint;
// Store circles to draw each time the user touches down
private List circlePoints;
public SimpleDrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
setupPaint(); // same as before
circlePoints = new ArrayList();
}
// Draw each circle onto the view
@Override
protected void onDraw(Canvas canvas) {
for (Point p : circlePoints) {
canvas.drawCircle(p.x, p.y, 5, drawPaint);
}
}
// Append new circle each time user presses on screen
@Override
public boolean onTouchEvent(MotionEvent event) {
float touchX = event.getX();
float touchY = event.getY();
circlePoints.add(new Point(Math.round(touchX), Math.round(touchY)));
// indicate view should be redrawn
postInvalidate();
return true;
}
private void setupPaint() {
drawPaint = new Paint();
drawPaint.setColor(paintColor);
.
Flash over the years, has been used to prop up the regular browser like a sad old man drinking alone in a pub.
Today browsers come shipped with technology designed to rival flash and aim to shut it squarely out of the game.
Are browser ready to rock without Flash?
This tutorial offers a step-by-step guide on how to effectively use Pinterest. It covers the basics such as account creation and navigation, as well as advanced techniques including creating eye-catching pins and optimizing your profile. The tutorial also explores collaboration and networking on the platform. With visual illustrations and clear instructions, this tutorial will equip you with the skills to navigate Pinterest confidently and achieve your goals.
Brushstrokes of Inspiration: Four Major Influences in Victor Gilbert’s Artist...KendraJohnson54
Throughout his career, Victor Gilbert was influenced heavily by various factors, the most notable being his upbringing and the artistic movements of his time. A rich tapestry of inspirations appears in Gilbert’s work, ranging from their own experiences to the art movements of that period.
Fashionista Chic Couture Maze & Coloring Adventures is a coloring and activity book filled with many maze games and coloring activities designed to delight and engage young fashion enthusiasts. Each page offers a unique blend of fashion-themed mazes and stylish illustrations to color, inspiring creativity and problem-solving skills in children.
The cherry: beauty, softness, its heart-shaped plastic has inspired artists since Antiquity. Cherries and strawberries were considered the fruits of paradise and thus represented the souls of men.
Heart Touching Romantic Love Shayari In English with ImagesShort Good Quotes
Explore our beautiful collection of Romantic Love Shayari in English to express your love. These heartfelt shayaris are perfect for sharing with your loved one. Get the best words to show your love and care.
Hadj Ounis's most notable work is his sculpture titled "Metamorphosis." This piece showcases Ounis's mastery of form and texture, as he seamlessly combines metal and wood to create a dynamic and visually striking composition. The juxtaposition of the two materials creates a sense of tension and harmony, inviting viewers to contemplate the relationship between nature and industry.
2. Multithreaded Graphics2 www.corewebprogramming.com
Agenda
• Approaches for multithreaded graphics
– Redraw everything in paint
– Have routines other than paint draw directly on window
– Override update and have paint do incremental updating
– Double buffering
• Reducing flicker in animations
• Implementing double buffering
• Animating images
• Controlling timers
3. Multithreaded Graphics3 www.corewebprogramming.com
Multithreaded Graphics:
Alternative Approaches
• Redraw everything in paint
– Simple and easy, but if things change quickly it is slow and can
result in a flickering display
• Have routines other than paint directly do drawing
operations
– Easy, efficient, and flicker-free, but results in “transient” drawing
that is lost next time the screen is redrawn
• Override update and have paint do incremental
updating
– Eliminates the flicker and improves efficiency somewhat, but
requires the graphics to be non-overlapping
• Double buffering
– Most efficient option and has no problem with overlapping graphics.
– More complex and requires additional memory resources
4. Multithreaded Graphics4 www.corewebprogramming.com
Redraw Everything in paint
• Idea
– Have user actions change non-graphical data structures,
then call repaint.
– The repaint method sets a flag that tells the event-
handling process to call update.
– The standard update method clears the screen and then
calls paint.
– The paint method completely redraws everything.
• Advantage
– Easy
• Disadvantages
– Flickers, slow.
5. Multithreaded Graphics5 www.corewebprogramming.com
Redrawing Everything in
paint: Example
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
/** Applet that draws a small circle where you click. */
public class DrawCircles extends Applet {
private Vector circles;
public void init() {
circles = new Vector();
addMouseListener(new CircleDrawer());
setBackground(Color.white);
}
...
6. Multithreaded Graphics6 www.corewebprogramming.com
Redrawing Everything in paint:
Example (Continued)
/** When you click the mouse, create a SimpleCircle,
* put it in the Vector, and tell the system
* to repaint (which calls update, which clears
* the screen and calls paint).
*/
private class CircleDrawer extends MouseAdapter {
public void mousePressed(MouseEvent event) {
circles.addElement(new SimpleCircle(event.getX(),
event.getY(),
25));
repaint();
}
}
7. Multithreaded Graphics7 www.corewebprogramming.com
Redrawing Everything in paint:
Example (Continued)
...
/** This loops down the available SimpleCircle
* objects, drawing each one.
*/
public void paint(Graphics g) {
SimpleCircle circle;
for(int i=0; i<circles.size(); i++) {
circle = (SimpleCircle)circles.elementAt(i);
circle.draw(g);
}
}
}
8. Multithreaded Graphics8 www.corewebprogramming.com
Redrawing Everything in
paint: Example (Continued)
public class SimpleCircle {
private int x, y, radius;
public SimpleCircle(int x, int y, int radius) {
setX(x);
setY(y);
setRadius(radius);
}
/** Given a Graphics, draw the SimpleCircle
* centered around its current position.
*/
public void draw(Graphics g) {
g.fillOval(x - radius, y - radius,
radius * 2, radius * 2);
}
...
}
9. Multithreaded Graphics9 www.corewebprogramming.com
Redrawing everything in paint:
Result
By storing results in a permanent data structure and redrawing the whole structure every
time paint is invoked, you cause the drawing to persist even after the window is covered
up and reexposed
10. Multithreaded Graphics10 www.corewebprogramming.com
Have Other Routines Draw
Directly on Window
• Idea
– Arbitrary methods (i.e., other than paint) can call
getGraphics to obtain the window’s Graphics object
– Use that Graphics object to draw
– Drawing lost if
• Window covered up and reexposed
• The update method called (e.g., via repaint)
• Advantage
– Fast
• Disadvantage
– Temporary
11. Multithreaded Graphics11 www.corewebprogramming.com
Drawing Directly on Window:
Example
public class Rubberband extends Applet {
private int startX, startY, lastX, lastY;
...
private void drawRectangle(Graphics g, int startX,
int startY, int stopX, int stopY ) {
int x, y, w, h;
x = Math.min(startX, stopX);
y = Math.min(startY, stopY);
w = Math.abs(startX - stopX);
h = Math.abs(startY - stopY);
g.drawRect(x, y, w, h);
}
...
private class RectRecorder extends MouseAdapter {
public void mousePressed(MouseEvent event) {
startX = event.getX();
startY = event.getY();
lastX = startX;
lastY = startY;
}
12. Multithreaded Graphics12 www.corewebprogramming.com
Drawing Directly on Window:
Example (Continued)
public void mouseReleased(MouseEvent event) {
Graphics g = getGraphics();
g.setXORMode(Color.lightGray);
drawRectangle(g, startX, startY, lastX, lastY);
}
}
private class RectDrawer extends MouseMotionAdapter {
public void mouseDragged(MouseEvent event) {
int x = event.getX();
int y = event.getY();
Graphics g = getGraphics();
g.setXORMode(Color.lightGray);
drawRectangle(g, startX, startY, lastX, lastY);
drawRectangle(g, startX, startY, x, y);
lastX = x;
lastY = y;
}
}
}
14. Multithreaded Graphics14 www.corewebprogramming.com
Override update and Have
paint do Incremental Updating
• Idea
– Have repaint (which triggers update) avoid clearing the
screen each time by overriding update as follows:
public void update(Graphics g) {
paint(g);
}
– Then, assuming objects don’t overlap, erase each object
at its old location by drawing over it in the background
color then drawing it at the new location
• Advantages
– No flicker, faster
• Disadvantage
– Fails for overlapping images
15. Multithreaded Graphics15 www.corewebprogramming.com
Incremental Updating:
Bounce Applet
public class Bounce extends Applet
implements Runnable, ActionListener {
private Vector circles;
private int width, height;
private Button startButton, stopButton;
private Thread animationThread = null;
...
public void actionPerformed(ActionEvent event) {
if (event.getSource() == startButton) {
if (circles.size() == 0) {
// Erase any circles from previous run.
getGraphics().clearRect(0, 0, getSize().width,
getSize().height);
animationThread = new Thread(this);
animationThread.start();
}
int radius = 25;
int x = radius + randomInt(width - 2 * radius);
int y = radius + randomInt(height - 2 * radius);
int deltaX = 1 + randomInt(10);
int deltaY = 1 + randomInt(10);
circles.addElement(new MovingCircle(x, y, radius,
deltaX, deltaY));
20. Multithreaded Graphics20 www.corewebprogramming.com
Option 4: Double Buffering
• Idea
– Draw into an off-screen pixmap, then draw that pixmap on window
• Outline
1. Override update to simply call paint
• This prevents the flicker that would normally occur each time
update clears the screen before calling paint
2. Allocate an Image using createImage
• Note that since this image uses native window-system support,
it cannot be done until a window actually appears
3. Look up its Graphics object using getGraphics
• Unlike with windows, where you need to look up the Graphics
context each time you draw, with images it is reliable to look it
up once, store it, and reuse the same reference thereafter
4. For each step, clear the image and redraw all objects onto it
• Dramatically faster than drawing onto a visible window
5. Draw the offscreen image onto the window
• Use drawImage
21. Multithreaded Graphics21 www.corewebprogramming.com
Double Buffering: Pros & Cons
• Advantages
– Much faster
– Can easily handle overlapping objects
• Disadvantages
– More complex
– Memory requirements for offscreen pixmap
– Sometimes less incremental update of display
22. Multithreaded Graphics22 www.corewebprogramming.com
Double Buffering: Example
public class DoubleBufferBounce extends Applet implements
Runnable, ActionListener {
private Vector circles;
private int width, height;
private Image offScreenImage;
private Graphics offScreenGraphics;
private Button startButton, stopButton;
private Thread animationThread = null;
public void init() {
setBackground(Color.white);
width = getSize().width;
height = getSize().height;
offScreenImage = createImage(width, height);
offScreenGraphics = offScreenImage.getGraphics();
// Automatic in some systems, not in others.
offScreenGraphics.setColor(Color.black);
circles = new Vector();
...
}
23. Multithreaded Graphics23 www.corewebprogramming.com
Double Buffering: Example
public void run() {
MovingCircle circle;
Thread myThread = Thread.currentThread();
// Really while animationThread not null.
while(animationThread == myThread) {
for(int j=0; j<circles.size(); j++) {
circle = (MovingCircle)circles.elementAt(j);
circle.move(width, height);
}
repaint();
pause(100);
}
}
public void paint(Graphics g) {
offScreenGraphics.clearRect(0, 0, width, height);
MovingCircle circle;
for(int i=0; i<circles.size(); i++) {
circle = (MovingCircle)circles.elementAt(i);
circle.draw(offScreenGraphics);
}
g.drawImage(offScreenImage, 0, 0, this);
}
}
25. Multithreaded Graphics25 www.corewebprogramming.com
Array-Based Animation
• Idea
– Load a sequence of images into an array
– Start a thread to cycle through the images and draw to the
graphics object
• Each time the thread loops through the while loop,
the array index is incremented and repaint (which
triggers update) is called to update the images on the
screen
– Stop the animation by setting a flag
• In an applet, end the animation from the applet’s stop
method
26. Multithreaded Graphics26 www.corewebprogramming.com
Array-Based Animation:
Example
public class ImageAnimation extends Applet {
private static final int NUMDUKES = 2;
private Duke[] dukes; // Duke has array of images
private int i;
public void init() {
dukes = new Duke[NUMDUKES];
setBackground(Color.white);
}
public void start() {
int tumbleDirection;
for (int i=0; i<NUMDUKES ; i++) {
tumbleDirection = (i%2 == 0) ? 1 :-1;
dukes[i] = new Duke(tumbleDirection, this);
dukes[i].start();
}
}
...
27. Multithreaded Graphics27 www.corewebprogramming.com
Animation Example (Continued)
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
for (i=0 ; i<NUMDUKES ; i++) {
if (dukes[i] != null) {
g.drawImage(Duke.images[dukes[i].getIndex()],
200*i, 0, this);
}
}
}
public void stop() {
for (int i=0; i<NUMDUKES ; i++) {
if (dukes[i] != null) {
dukes[i].setState(Duke.STOP);
}
}
}
}
28. Multithreaded Graphics28 www.corewebprogramming.com
Animation Example (Continued)
public class Duke extends Thread {
...
public static Image[] images;
private static final int NUMIMAGES = 15;
private static Object lock = new Object();
private int state = RUN;
public Duke(int tumbleDirection, Applet parent) {
this.tumbleDirection = tumbleDirection;
this.parent = parent;
synchronized(lock) {
if (images == null) { // If not previously loaded.
images = new Image[ NUMIMAGES ];
for (int i=0; i<NUMIMAGES; i++) {
images[i] = parent.getImage( parent.getCodeBase(),
"images/T" + i + ".gif");
}
}
}
}
...
29. Multithreaded Graphics29 www.corewebprogramming.com
Animation Example (Continued)
public void run() {
while (checkState()!=STOP) {
index += tumbleDirection;
if (index < 0) {
index = NUMIMAGES - 1;
} else if (index >= NUMIMAGES) {
index = 0;
}
parent.repaint();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
break; // Break while loop.
}
}
}
}
31. Multithreaded Graphics31 www.corewebprogramming.com
Timers
• Swing defines a Timer class
– A Timer can ring for a single cycle or fire periodically
– At each ring an ActionEvent is fired
– Useful for animations, simulations, and timing out secure
network connections
• Approach
Timer timer = new Timer(milliseconds, listener);
timer.start();
...
...
timer.stop();
32. Multithreaded Graphics32 www.corewebprogramming.com
Useful Timer Methods
• start/stop
– Starts or stops the timing sequence
• restart
– Cancels any undelivered time events and starts the timer again
• setCoalesce
– Turns coalescing off or on
– By default, if a timer event is in the event queue (coalesce
true), a new ActionEvent is not created at the next firing
interval
• setRepeats
– Sets the timer to ring once (false) or to ring periodically (true)
– Default behavior is to ring periodically
33. Multithreaded Graphics33 www.corewebprogramming.com
Timer: Example
import java.awt.*;
import javax.swing.*;
public class TimedAnimation extends JApplet {
private static final int NUMDUKES = 2;
private TimedDuke[] dukes;
private int i, index;
public void init() {
dukes = new TimedDuke[NUMDUKES];
setBackground(Color.white);
dukes[0] = new TimedDuke( 1, 100, this);
dukes[1] = new TimedDuke(-1, 500, this);
}
// Start each Duke timer.
public void start() {
for (int i=0; i<NUMDUKES ; i++) {
dukes[i].start();
}
} ...
34. Multithreaded Graphics34 www.corewebprogramming.com
Timer Example (Continued)
...
public void paint(Graphics g) {
for (i=0 ; i<NUMDUKES ; i++) {
if (dukes[i] != null) {
index = dukes[i].getIndex();
g.drawImage(TimedDuke.images[index], 200*i, 0, this);
}
}
}
// Stop each Duke timer.
public void stop() {
for (int i=0; i<NUMDUKES ; i++) {
dukes[i].stop();
}
}
}
35. Multithreaded Graphics35 www.corewebprogramming.com
Timer Example (Continued)
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TimedDuke extends Timer
implements ActionListener {
private static final int NUMIMAGES = 15;
private static boolean loaded = false;
private static Object lock = new Object();
private int tumbleDirection;
private int index = 0;
private Applet parent;
public static Image[] images = new Image[NUMIMAGES];
public TimedDuke(int tumbleDirection, int msec,
Applet parent) {
super(msec, null);
addActionListener(this);
this.tumbleDirection = tumbleDirection;
this.parent = parent; ...
36. Multithreaded Graphics36 www.corewebprogramming.com
Timer Example (Continued)
synchronized (lock) {
if (!loaded) {
// Load images using MediaTracker
...
}
}
}
// Return current index into image array.
public int getIndex() { return index; }
// Receives timer firing event. Increments the index into
// image array and forces repainting of the new image.
public void actionPerformed(ActionEvent event) {
index += tumbleDirection;
if (index < 0){
index = NUMIMAGES - 1;
}
if (index >= NUMIMAGES) {
index = 0;
}
parent.repaint();
}
}
37. Multithreaded Graphics37 www.corewebprogramming.com
Timer Example: Result
Each Duke moves at a different speed
Duke is a registered trademark of Sun Microsystems, Inc.
All restrictions apply (http://www.sun.com/policies/trademarks/).
Used with permission.
38. Multithreaded Graphics38 www.corewebprogramming.com
Summary
• Options
– Redraw everything in paint
– Have routines other than paint directly do drawing
operations
– Override update and have paint do incremental updating
– Double buffering
• Animation can be achieved by cycling through
a sequence of images
• Timers are restartable threads that fire an
ActionEvent once or periodically