Reputation: 426
Question: So I am attempting to understand how threads work with graphics so I created a program that should set the color of the screen to red using a user thread. However, when I run the program, it opens my JFrame window an infinite number of times on top of each other and I have to quit the program for it to stop. How do I prevent this from happening? Thanks in advance.
UPDATE: So a lot of you have explained to me the culprit (commented out now): frame.add(new MWT) that repeatedly calls the constructor and creates a new object. However, How do I simply add the Canvas to the JFrame without any static instances? Thanks
Class Code
public class MWT extends Canvas implements Runnable
{
private Thread fast;
public static void main(String [] args){
MWT draw = new MWT();
}
public MWT(){
JFrame frame = new JFrame("Thread Drawings");
frame.setVisible(true);
frame.setFocusable(true);
frame.setSize(600,500);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
// CULPRIT
//frame.add(new MWT());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
start();
}
private void stop() {
if (fast== null){
return;
}
else{
System.exit(0);
}
}
private void start() {
if (fast != null){
return;
}
else{
fast = new Thread(this);
fast.start();
}
}
@Override
public void run() {
BufferStrategy bs = this.getBufferStrategy();
if (bs == null){
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
Graphics2D g2d = (Graphics2D) g;
render(g2d);
}
public void render(Graphics2D g2d){
g2d.setColor(Color.RED);
g2d.fillRect(0, 0,600,500);
stop();
}
}
Upvotes: 0
Views: 1142
Reputation: 3181
The problem is with the constructor for MWT
at the line add(new MWT())
. So when you construct a new MWT
, you create a new JFrame
, then you called MWT()
again, creating a new JFrame
, calling MWT()
again, and so on. Eventually you should run into a stack overflow though.
To solve that, you could either extend JFrame
, and add components that go inside it in its constructor, or just add the current instance.
public class MWT extends Canvas implements Runnable {
// change the constructor so it doesn't make a new JFrame
// change the constructor so it doesn't add a new instance to the JFrame
// leave the rest unchanged
}
public class ThreadedGraphicsDemo extends JFrame {
private MWT mwt;
public ThreadedGraphicsDemo(MWT mwt) {
this.mwt = mwt;
add(mwt);
// set exit behavior, size, pack, visible etc
}
}
public class Demo {
public static void main(String[] args) {
MWT mwt = new MWT();
ThreadedGraphicsDemo tgd = new tgd(mwt);
}
}
This approach will allow you to easily change the GUI, and behavior in the future.
The quick fix:
instead of add(new MWT())
, change it to add(this)
to add the instance of MWT
that you've instantiated
Upvotes: 7
Reputation: 106430
Well, I tracked down the source of your infinitely spawning windows. You're instantiating the object you're constructing in constructor.
frame.add(new MWT());
The thing with this is that, since the object isn't completely done constructing your instance, it's going to still go off and create an instance of that, which leads to a lot of calls to the MWT
object.
If you want to add the current instance of the MWT
object you're constructing, you can use this
instead:
frame.add(this);
Upvotes: 2