Painting in swing. repaint doesn't work.

K

Kgbol

Hi, today I hve a problem with painting. I created a class Szescian
that extends JPanel and implements Runnable. I want that class to
paint a square that moves. I move it using a thread. The problem is
that when i use repaint in the thread the screen doesn't repaints( the
compiler doesn't jump tu paintComponent(gDC) method) Here is how i
create this object in the class with frame

private Szecian s1;

//COnstructor
public Main(){
.........
s1 = new Szescian();
s1.setLocation(0,0);
s1.setOpaque(true);
s1.setVisible(true);
s1.setSize(panelSzescian.getSize());;
s1.setOpaque(true);
panelSzescian.add(s1); // a JPanel to which i add s1
s1.uruchom(); //start the thread
.........
}

and here is my Szescian class:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import javax.imageio.*;

public class Szescian extends JPanel implements Runnable{
public int x,y;
public Rectangle rect;
public Szescian(){
x=0; y=0;
rect = new Rectangle(0,0,getWidth(), getHeight());
}

public void run(){
for(int i=0; i<50; i++)
{
x=i; y=i;

System.out.println(i);

try
{
Thread.sleep(100);
}
catch(InterruptedException e){e.printStackTrace();}
// repaint(rect);
repaint();

}
}

protected void paintComponent(Graphics gDC)
{
// podwojne buforowanie
super.paintComponent( gDC );
Image img = createImage(getWidth(), getHeight());
Graphics g = img.getGraphics();
g.setColor(Color.yellow);
g.drawRect(x,y,20,20);
g.fillRect(x,y,20,20);
//gDC.drawImage(img,0,0,getWidth(), getHeight(),this);//
wyswietla obraz z bufora
gDC.drawImage(img,0,0,this);
}

protected void paintBorder(){

}
protected void paintChildren(){

}

public void uruchom(){
Runnable r = new Szescian();
Thread t = new Thread(r);
t.start();
}
}
 
S

SadRed

Hi, today I hve a problem with painting. I created a class Szescian
that extends JPanel and implements Runnable. I want that class to
paint a square that moves. I move it using a thread. The problem is
that when i use repaint in the thread the screen doesn't repaints( the
compiler doesn't jump tu paintComponent(gDC) method) Here is how i
create this object in the class with frame

private Szecian s1;

//COnstructor
public Main(){
........
s1 = new Szescian();
s1.setLocation(0,0);
s1.setOpaque(true);
s1.setVisible(true);
s1.setSize(panelSzescian.getSize());;
s1.setOpaque(true);
panelSzescian.add(s1); // a JPanel to which i add s1
s1.uruchom(); //start the thread
........

}

and here is my Szescian class:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import javax.imageio.*;

public class Szescian extends JPanel implements Runnable{
public int x,y;
public Rectangle rect;
public Szescian(){
x=0; y=0;
rect = new Rectangle(0,0,getWidth(), getHeight());
}

public void run(){
for(int i=0; i<50; i++)
{
x=i; y=i;

System.out.println(i);

try
{
Thread.sleep(100);
}
catch(InterruptedException e){e.printStackTrace();}
// repaint(rect);
repaint();

}
}

protected void paintComponent(Graphics gDC)
{
// podwojne buforowanie
super.paintComponent( gDC );
Image img = createImage(getWidth(), getHeight());
Graphics g = img.getGraphics();
g.setColor(Color.yellow);
g.drawRect(x,y,20,20);
g.fillRect(x,y,20,20);
//gDC.drawImage(img,0,0,getWidth(), getHeight(),this);//
wyswietla obraz z bufora
gDC.drawImage(img,0,0,this);
}

protected void paintBorder(){

}
protected void paintChildren(){

}

public void uruchom(){
Runnable r = new Szescian();
Thread t = new Thread(r);
t.start();
}

}
Your 's1' and 'r' are completely different objects.
Very bad design.
You should radically refactor it.
Panel should be simply a panel.
Don't make it to be an executable/runnable!
 
T

Twisted

Your 's1' and 'r' are completely different objects.

This much is true. The uruchom method should just do:
(new Thread(this)).start();

I guess the OP's intent with this design is to have a component that
auto-updates on a timer. There should really be some facility for
terminating the thread later on when the component no longer needs
updating. I suppose the component can detect in the run loop or paint
method if it's been told to deactivate or is no longer visible or
whatever; maybe handling that is planned but unimplemented by the OP
yet, or omitted from the code posted here to save space. Right now it
looks like it updates only fifty times and then stops anyway, which is
really odd, but that may again be temporary until a more robust system
is in place to determine when to stop the updating. I suppose the code
we've seen is a test to get the updating working first, and then
refine into the final code later.

The more usual design would probably be to have an external Runnable
calling repaint on a set of components registered with it as needing
automatic updating. I'm not sure also of the effect of calling repaint
from arbitrary threads. I checked the JComponent docs and it doesn't
say that it should be done on the event-dispatch thread, at least not
in the repaint method descriptions themselves. If so you'd need to use
a SwingUtilities.invokeLater on a runnable that calls repaint once on
the component.

Another thing to consider is whether the compiler or JVM is choking on
identifiers with too high a consonant-to-vowel ratio. ;)
 
K

Kgbol

Ok, now this works fine, thanks very much. I was creating my thread
wrong. Funny is taht it was based on an example from a book:) It
should be as you said.

(new Thread(this)).start();

This program is just for testing how to paint in swing. Could you
explain me also, why in "run()" method i can only use methods and
variables from the class that run method is used in.
 
L

Lew

Kgbol said:
This program is just for testing how to paint in swing. Could you
explain me also, why in "run()" method i can only use methods and
variables from the class that run method is used in.

That's not strictly true - you can access an object's accessible methods and
variables via a reference to that object even if that object is of a different
class than the caller.

You can eliminate the explicit object reference (class reference for statics)
only when the reference is 'this' (respectively, the class of 'this').

Within any call via a referenced object, this or otherwise, you can only
invoke the methods defined for the type of that object. That is fundamental Java.

How is the system supposed to know that a call like
foo( something );

is supposed to use the foo() from another class? Of course it can only use
methods from the class making the call, because that call is equivalent to
this.foo( something );
.. You are limited to methods defined in the class for 'this'.

This is very basic Java syntax and semantics.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top