imgolden62
imgolden62

Reputation: 426

Why does my Java program create an infinite # of windows? (Uses threads and NO WHILE LOOPS)

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

Answers (2)

Alex
Alex

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

Makoto
Makoto

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

Related Questions