1

I have a thread which drops a circle in the y direction. I want to now create several circles on screen dropping at the same time with random x positions.

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Goo 
{
protected GooPanel gooPanel;
private boolean loop = true;
protected int width , height;
private int frameTimeInMillis = 50;
private RenderingHints renderingHints = new RenderingHints(
RenderingHints.KEY_ANTIALIASING , RenderingHints.
VALUE_ANTIALIAS_ON);
@SuppressWarnings("serial")

class GooPanel extends JPanel 
{
    public void paintComponent(Graphics g) 
    {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHints(renderingHints);
        draw(g2d);
    }
}

public Goo() 
{
    this (800, 500);
}

public Goo(int w, int h) 
{
    width = w;
    height = h;
    JFrame frame = new JFrame ();

    frame.setSize(width , height);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    gooPanel = new GooPanel ();
    gooPanel.setPreferredSize(new Dimension(w, h));
    frame.getContentPane ().add(gooPanel);
    frame.pack();
    frame.setVisible(true);
}

public void go() 
{
    while (loop) 
    {
        gooPanel.repaint();
        try 
        {
            Thread.sleep(frameTimeInMillis);
        } catch (InterruptedException e) {}
    }
}

public void draw(Graphics2D g) {}

public void setFrameTime(int millis)
{
    frameTimeInMillis = millis;
}

public Component getGooPanel () 
{
    return gooPanel;
}
}

My FallingDrop class:

import java.awt.*;

public class FallingDrops extends Goo
{
    double x, y, r;
    int red, green, blue = 0;
    Color a;

FallingDrops() 
{
    x = width / 2;
    r = 10;
    y = -r;
}

FallingDrops(double x) 
{
    this.x = x;
    r = 10;
    y = -r;
}

public void draw(Graphics2D g) 
{
    g.setColor(Color.GRAY);
    g.fillRect(0, 0, width , height);
    g.setColor(Color.WHITE);

    g.fillOval ((int) (x - r), (int) (y - r), (int) (2 * r),
            (int) (2 * r));

    y++;
    if (y - r > height)
        y = -r;

}


public static void main(String [] args) 
{
    int num = 10;
    Goo gooDrop [] = new FallingDrops[num];

    for(int i = 0; i < gooDrop.length; i++)
    {
        double x = Math.random()*800;
        gooDrop[i] = new FallingDrops(x);
        System.out.println(x);
        gooDrop[i].go();
    }

}


}

At current, the loop fails to complete when the go() method is executed; thus only painting ONE object on screen, and not several as indicated in my loop. This is a simple fix I am sure. Any ideas what I am doing wrong?

tshepang
  • 10,772
  • 21
  • 84
  • 127
AWb
  • 151
  • 3
  • 10

2 Answers2

2
while (loop) .. gooPanel.repaint();  

Not the way to do custom painting. Establish a Swing Timer and call repaint() in the actionPerformed() method of the listener.

See the Custom Painting lesson in the tutorial for details and working examples.

Andrew Thompson
  • 163,965
  • 36
  • 203
  • 405
  • Hi, this doesn't quite answer my question. In my main() method, the loop begins but fails to make any more passes once it reaches the go() method. I want the loop to paint the circle several times on screen, and each of them dropping in the y direction at the same time – AWb Dec 09 '11 at 11:00
  • *"this doesn't quite answer my question"* I'm still waiting for the SSCCE. What are *you* waiting for? – Andrew Thompson Dec 09 '11 at 11:09
  • I never asked for your 'full code' (with no imports and missing brackets, BTW). Which part of 'SSCCE' are you having trouble understanding? Also, make an attempt at implementing painting the correct way. – Andrew Thompson Dec 09 '11 at 11:36
  • I am new to Stackoverflow, so still figuring out how to provide a SSCCE. I have read your document, but it doesn't provide any examples of a valid SSCCE. Just information of what it means. As part of a task I am doing, I am not allowed to actually change the way the objects are painted. This was already predefined. My task was to EXTEND the class, and make several circles drop rather than just one. I apologise for taking up your time; if you have a better link to understand SSCCE's, please do share it. – AWb Dec 09 '11 at 11:56
  • *"examples of a valid SSCCE."* Try [this one](http://stackoverflow.com/questions/7861724/is-there-some-word-wrap-property-of-jlabel-exist/7861833#7861833) or [this one](http://stackoverflow.com/questions/7143287/how-to-best-position-swing-guis/7143398#7143398) or [these 2](http://stackoverflow.com/questions/5853879/java-swing-obtain-image-of-jframe/5853992#5853992).. – Andrew Thompson Dec 09 '11 at 12:12
  • excelent answer & comments, but only my allowed +1 – mKorbel Dec 09 '11 at 16:28
2

The method go() never returns. when it is called on the first object in the array, it continues working infinitely. you should either make the repainting in a separate thread that is constantly repainting. or if you want repainting only when drops are added, then remove the while in your go method

public void go() 
{

        gooPanel.repaint();
        try 
        {
            Thread.sleep(frameTimeInMillis);
        } catch (InterruptedException e) {}

}

this way it will returns after it had made a repaining and a pause.

  • The while loop is definitely the issue, which prevents the for loop from completing all passes. Unfortunately, your solution does not seem to work. I forgot to mention that go() is being called from a different class of where main() is executed. – AWb Dec 09 '11 at 11:11
  • actually i was writing my answer when @Andrew Thompson posted his. His solution is the correct way as it seems after your comment regarding different class calling go and if you give an SSCCE as he suggested then I am sure your problem will get solved fast. –  Dec 09 '11 at 11:24