Filling a rectangle - paint method (MIDP) - java

Im trying to slowly paint a rectangle using two calls of .fillrect method with Thread.sleep call between each method. What is happening is that the sleep method is getting called before the rectangle is initialised, so it appears that the rectange has already been painted. I just want to paint part of the rectange, pause for five seconds and then paint antother part.
Here is my code -
public void paint(Graphics g, int w, int h) {
g.drawRect(0, 0, w - 1, h - 1);
g.fillRect(0, 0, 10, h-1);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
g.fillRect(0, 0, 50, h-1);
}
Thanks

It is always a very BAD idea to cause an event thread to block, no matter what the platform.
What you should be doing is defining variables somewhere that store the current extent of the area you want painted. Update those variables on a separate thread (you can block that thread all you want) and call the repaint() method to schedule a repaint whenever you update the variables.

Related

Image loads after 1 second

For some reason my image loads after 1 second even though I call render before my thread.sleep ()
public void init (){
image=new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
g= (Graphics2D) image.getGraphics();
running=true;
}
public void run (){
init();
while(running){
long start=System.nanoTime();
update();
render();
drawToScreen();
try{
thread.sleep(1000);
}
catch (Exception e){
e.printStackTrace();
}
}
}
public void update (){
}
public void render (){
g.clearRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.white);
g.fillRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.red);
for(int r=0; r<16; r++){
for(int c=0; c<16; c++){
MazeCell m=maze[15-r][c];
int y=15-m.getRow();
int x=m.getCol();
if(m.getWallUp()) g.drawLine(x*50, y*50, (x+1)*50, y*50);
if(m.getWallDown()) g.drawLine(x*50, (y+1)*50, (x+1)*50, (y+1)*50);
if(m.getWallLeft()) g.drawLine(x*50, y*50, x*50, (y+1)*50);
if(m.getWallRight()) g.drawLine((x+1)*50, y*50, (x+1)*50, (y+1)*50);
}
}
g.drawImage(mouseImage, mouse.getCol()*50, (15-mouse.getRow())*50, null);
}
public void drawToScreen (){
Graphics g2=getGraphics();
g2.drawImage (image, 0, 0, null);
g2.dispose();
}
Everything draws but at first there is a blank gray screen and it only loads after 1 second (the time the thread sleeps) even though render and drawToScreen are called first. I don't really know the reason.
Change your:
g2.dispose();
To:
g2.finalize();
Also, the description of the Graphics.drawImage() method states:
Draws as much of the specified image as is currently available. The image is drawn with its top-left corner at (x, y) in this graphics context's coordinate space. Transparent pixels in the image do not affect whatever pixels are already there.
This method returns immediately in all cases, even if the complete image has not yet been loaded, and it has not been dithered and converted for the current output device.
If the image has completely loaded and its pixels are no longer being changed, then drawImage returns true. Otherwise, drawImage returns false and as more of the image becomes available or it is time to draw another frame of animation, the process that loads the image notifies the specified image observer.
In other words, the call returns immediately, whether or not the image drawing has completed.
You can use MediaTracker to first make sure the image is loaded before you call Graphics.drawImage():
long timeout = 60000; // 60 seconds
MediaTracker tracker = new MediaTracker(this);
tracker.addImage(image, 0);
try {
if (!tracker.waitForID( 0, timeout ) ) {
System.out.println( "Timed Out!" );
return;
}
}
catch( Exception ex) {
System.out.println( "Error waiting for the image to load." );
return;
}
boolean isFinished = g.drawImage(image, 0, 0, this);

Thread.sleep not displaying image properly in paintComponent

When drawing a BufferedImage , the transition image does not display. I am trying to create a game in which when the user wins, it displays a loading transitional screen and then proceeds to the img2 screen. I want to create a 1 or 2 second delay to make it seem as though the second level is in the process of loading however when I add thread.sleep it delays it but does not display the transition image, instead, it just jumps straight toimg2. I have tried creating separate flags,methods and increasing the time but nothing seems to work!
Below is the paintComponenetmethod (I have tried separating into separate methods):
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(img, 0, 0, this);
if (win1 == true) {
try {
Thread.sleep(1000);
} catch (Exception exc) {
}
g2d.drawImage(transition, 0, 0, this);
try {
Thread.sleep(1000);
} catch (Exception exc) {
}
g2d.drawImage(img2, 0, 0, this);
}
}
}
An explanation would be very helpful as well!
All painting is done on the Event Dispatch Thread.
When you invoke Thread.sleep() in the paintComponent() method the GUI can't repaint itself until all the code is finished executing which means only the last image will ultimately get painted as the two paint requests will be combined into one. Read the section from the Swing tutorial on Concurrency for more information.
Don't use Thread.sleep() in a painting method.
The better solution is to not even do custom painting. Instead you can just use a JLabel and change the Icon of the label.
Then you can use use a Swing Timer to schedule the animation. So you would set the Icon and then set the Timer to fire in 2 seconds. When the Timer fires you reset the Icon of the label.

JAVA: Unformed Sprite When trying to Read SpriteSheet

So Im a beginner experimenting with ImageIO. Can someone tell me why im getting this pixelated-incomplete sprite?
Here's the code
public BufferedImage getImage(String location)
{
try
{
File file = new File(location);
image = ImageIO.read(file);
}
catch (IOException e)
{
System.err.println("It don't work!!");
e.printStackTrace();
}
return image;
}
And Im using this method to display it
public void paint(Graphics g)
{
g.drawImage(getImage("Numbers/icon0.png"), 0, 0, 32, 32, null);
repaint();
}
And here's what it gives me
If you want to display the first (single) cell of your sprite, you probably meant to write:
g.drawImage(getImage("Numbers/icon0.png").getSubimage(0, 0, 32, 32), 0, 0, null);
Notice the getSubimage(x, y, w, h) part, to get a single cell.
If you wanted to draw the entire sprite sheet, you could use:
g.drawImage(getImage("Numbers/icon0.png"), 0, 0, null);
Your original code will draw the entire sprite sheet, rescaled to 32x32.
PS: You should probably not invoke repaint() from the paint method, as that will create an endless repaint loop. If you want your component to repaint, use some kind of timer that repaints your component at fixed intervals.
PPS: You should probably not do I/O (ie. read the image) inside the paint method, because any I/O operation may take time and make your UI sluggish and unresponsive. It's also unnecessary, as the sprite sheet does not change every time you repaint. Instead, read the image up front, and only draw it in the paint method.

java drawOval repeated circles

When redrawing circles, the window is not cleared; the new circles get added to the existing content.
The goal is to create three circle, one for each color.
The thread calls move function which draws the circles with different radii.
public void run() {
try {
while(true){
box.removeAll();
move();
box.removeAll();
sleep(500);
}
} catch (InterruptedException e) {
}
}
public synchronized void move() {
Graphics g = box.getGraphics();
g.setXORMode(box.getBackground());
x1= one.x + ofset;
y1= one.y + ofset;
System.out.println("My Point ("+ x1 + " , " + y1 +")" );
g.setColor(Color.green);
g.drawOval(pointA.x-(int)distance1, pointA.y-(int)distance1, (int)distance1*2, (int)distance1*2);
g.setColor(Color.blue);
g.drawOval(pointB.x-(int)distance2, pointB.y-(int)distance2, (int)distance2*2, (int)distance2*2);
g.setColor(Color.red);
g.drawOval(pointC.x-(int)distance3, pointC.y-(int)distance3, (int)distance3*2, (int)distance3*2);
g.dispose();
}
First of all, your approach is not recommended. But, if you only want a quick and dirty fix, you have to clear the panel before drawing the circles.
Graphics g = box.getGraphics();
g.clearRect(0, 0, box.getWidth(), box.getHeight()); // this should do it
g.setXORMode(box.getBackground());
Graphics g = box.getGraphics();
No. Don't use getGraphics(). Any painting done with that Graphics object is only temporary and will be deleted any time Swing determines a component needs to be repainted.
For custom painting override the getPreferredSize() method of a JPanel:
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g); // clears the background
// add your custom painting here
}
Also, don't forget to override the getPreferredSize() method of your panel. Read the section from the Swing tutorial on Custom Painting for more information.

Processing code doesn't work (Threads, draw(), noLoop(), and loop())

The code below should make a shape flash twice, I triple checked the methods from root and I'm 99% sure it's that those methods are correct (I will post that code if needed though). What's the best way to make the current state of root pause on screen for a few seconds?
noLoop();
root.setVal(newVal);
root.highlight(0,255,0);
root.setopacity(200);
redraw();
try {Thread.sleep((long)1500);}
catch (InterruptedException ex) {println("Error!");}
root.setopacity(0);
redraw();
try {Thread.sleep((long)1500);}
catch (InterruptedException ex) {println("Error!");}
root.setopacity(200);
root.clearHL();//just to make sure I repeated these methods
root.highlight(0,255,0);
redraw();
try {Thread.sleep((long)1500);}
catch (InterruptedException ex) {println("Error!");}
root.clearHL();
redraw();
loop();
return root;
You can only have one thread doing the drawing, and if you jam that thread up with sleep etc, it will "hang" until it gets a chance to get out of your code and back to rendering code inside the JRE.
There are plenty of tutorials around about it, Google is your friend!
e.g.: http://www.java-tips.org/java-se-tips/java.awt/how-to-create-animation-paint-and-thread.html
Think of it as you drawing onto a page, and every now and then the page is pulled out of your notebook to be displayed. Doesn't matter if you take 10 seconds to draw a circle, then rub it out. All that matters is what is on the page when it gets displayed.
I'm not sure if i got your problem, and the code is not runnable, but...maybe you need a simpler approach? A little timer made by yourself? The thing is that draw() executes all instructions before rendering a frame at the end of draw(). So if you stop draw() it will pause, without doing any draw, and then continues making all changes and drawing at the end. I mean if I do:
draw(){
fill(0);
ellipse(10,10,10,10);
delay(1000);
fill(255,255,0);
ellipse(10,10,10,10);
}
I will never see the black ellipse as it is covered by the yellow one before render takes place...at the end of draw. But the program is gonna hang for one second every frame...
So maybe a simple timer could do it for you. Here a general sample of a timer you could try to adapt for your needs:
PFont font;
String time = "000";
int initialTime;
int interval = 1000;
int times;
color c = color(200);
void setup() {
size(300, 300);
font = createFont("Arial", 30);
background(255);
fill(0);
smooth();
//set the timer as setup is done
initialTime = millis();
}
void draw()
{
background(255);
//compare elapsed time if bigger than interval...
if (millis() - initialTime > interval)
{
//display the time
time = nf(int(millis()/1000), 3);
// reset timer
initialTime = millis();
//increment times
times++;
}
// an arbitrary ammount
if (times == 3) {
//do somethng different
c = color(random(255), random(255), random(255));
// reset times
times = 0;
}
//draw
fill(0);
text(time, width/2, height/2);
fill(c);
ellipse(75, 75, 30, 30);
}

Categories

Resources