Hi,
My problem is that I need to tell class A to repaint, but from class B.
Class B will be a thread that updates components of class A and will eventually tell A to repaint.
The basic idea of my code is as follows:

class A extends JPanel{
    Thread b;
    ...
    b = new B();

    paint(Graphics g){
    ...
    }
}

class B extends A implements Runnable{
    run(){
        ...
        //Tell A to repaint
    }
}

From my understanding of swing, I need to tell A to repaint when referring directly to it
For example:

class X{
    A a;
    ...
    a.repaint();
}

Or I could call repaint inside of Class A

class A{
   ...
  repaint();
}

But how do I do this from the run() method of class B?

Thanks in advance.

Recommended Answers

All 4 Replies

Why exactly does class B have to extend A?

From an immediate glance I can see a potential cycle instantiation issue.

Think about it--

1) Class A, after static initialization, will instantiate a class B object--

2) Class B extends A, so when a B object is constructed, the super constructor of A is called but between that process the pre-initialization is done again leading back to step 1!

--which means that your program will cause new memory to be called and constructors to be (in theory) pushed on stack memory along with variables that are used within them, and additional growth of objects in the heap due to subsequent calls of new that are not resolved to make objects unreachable since there is a valid reference pointing to it.

What you want to do is something like this--

import javax.swing.*;

public class NameSpaceClass001{

	class A extends JPanel{

		// blah... mumble...
		private B myB = null;
		public A(){
			myB = new B(this);
			Thread t = new Thread(myB);
			t.setDaemon(true);
			t.start();
		}
	}

	class B implements Runnable{

		private A panel = null;
		public boolean running = true;

		public B(A ref){
			panel = ref;
		}

		private int safeWait(int seconds){
			long l = System.currentTimeMillis(); // get current time
			long next = l + (seconds * 1000); // get current time + future time
			while(l < next) l = System.currentTimeMillis(); // wait specified seconds
			return seconds;
		}

		@Override public void run(){
			while(running){
				System.out.println("Calling repaint after " + safeWait(3) + " seconds...");
				panel.repaint();

			}
		}
	}

	public static void main(String... args){
		NameSpaceClass001 nsc001 = new NameSpaceClass001();
		nsc001.new A();
	}
}

I marked the Thread daemon as a good practice. Unfortunately it makes the example hard to see, the way the code is currently written. Consider this example instead--

import javax.swing.*;

public class NameSpaceClass001{

	class A extends JPanel{

		// blah... mumble...
		private B myB = null;
		public A(){
			myB = new B(this);
			Thread t = new Thread(myB);
			t.setDaemon(true);
			t.start();
		}

		public B getB(){
			return myB;
		}
	}

	class B implements Runnable{

		private A panel = null;
		public boolean running = true;

		public B(A ref){
			panel = ref;
		}

		public int safeWait(int seconds){
			long l = System.currentTimeMillis(); // get current time
			long next = l + (seconds * 1000); // get current time + future time
			while(l < next) l = System.currentTimeMillis(); // wait specified seconds
			return seconds;
		}

		@Override public void run(){
			while(running){
				System.out.println("Calling repaint after " + safeWait(3) + " seconds...");
				panel.repaint();

			}
		}
	}

	public static void main(String... args){
		NameSpaceClass001 nsc001 = new NameSpaceClass001();
		NameSpaceClass001.A myA = nsc001.new A();

		myA.getB().safeWait(15);
	}
}
commented: The good guy guiding everyone to the finish and ensuring people get there ;) +3

Thankyou that was the problem, plenty of good karma is coming your way...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.