drawing from an external class


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 6 of 6

Thread: drawing from an external class

  1. #1
    Join Date
    Dec 2004
    Posts
    4

    drawing from an external class

    hello,

    I am trying to make a java program that simulates a glass of water with bubbles moving from the bottom to the top of the glass.
    what I want to do is make a class, lets call it the driver class, which has the glass and the drawing surface (and maybe add to it some sliders to increase the number of bubbles or their speed) and another class "bubble". class bubble is a thread, when instantiated, I want it to move from the bottom to the top of the glass. so...I pass to the constructor of the bubble the starting y and the ending y, and it has to move.

    my problem is in drawing this bubble. I am going to be instantiating the bubbles in the driver class, and the bubble has to take care of drawing itself, how will I draw from the bubble class on the drawing surface of the driver class? I tried passing the driver class's graphics object but that surely didnt work....any suggestions?

    thanks a lot in advance

  2. #2
    Join Date
    Nov 2004
    Location
    Norway
    Posts
    1,560
    You should have submitted your code. If the bubbles don't show then they are either not working or they are being overdrawn.
    I would have loaded a small squence of images that showed a growing bubble and a few bubble bursts. Tha is, - each bubble was a projector showing this sequence onscreen at a position given by the class that instantiated the set of bubbles. Bubble that burst or reaches the surface will 'relocate' somewhere at the bottom and go throug the 'lift' once again.

    like...
    eschew obfuscation

  3. #3
    Join Date
    Dec 2004
    Posts
    4
    thanks a lot for your reply, and sorry for not being able to reply before this.

    I have here tow pieces of code, one works and the other doesnt, but I cant figure out why:

    the working one:

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


    public class graph extends JFrame {

    Graphics G;

    public graph() {
    setSize(500,500);
    setVisible(true);
    }

    public void paint(Graphics g) {
    G=g;
    generate();
    }

    public void generate() {
    bubble b = new bubble(G);
    }


    public static void main(String[] args) {
    graph gg = new graph();
    gg.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    }


    class bubble {

    public bubble(Graphics g) {
    g.drawOval(20, 20, 100, 100);
    }
    }


    now when I make the second class a thread and draw in the run function it stops drawing.

    here is the code :

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


    public class graph extends JFrame implements ActionListener{

    Graphics G;
    Timer timer;

    public graph() {
    setSize(500,500);
    setVisible(true);

    timer = new Timer(100, this);
    timer.start();
    }

    public void paint(Graphics g) {
    G=g;
    generate();
    }

    public void generate() {
    System.out.println("generate");
    bubble b = new bubble(G);
    b.start();
    }

    public void actionPerformed(ActionEvent event) {
    repaint();
    }

    public static void main(String[] args) {
    graph gg = new graph();
    gg.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    }


    class bubble extends Thread{

    Graphics G;
    int x=0;

    public bubble(Graphics g) {

    G = g;
    }

    public void run() {
    while (x<100) {
    G.drawOval(x++, 20, 100, 100);
    System.out.println(x);

    try{
    Thread.sleep(100);
    }catch(InterruptedException i){}
    }
    }
    }

    notice that System.out.println(x) is reached , and the multithreading is going OK....but it is not drawing!!

    any help? I would be very very greatful.

    waiting....

  4. #4
    Join Date
    Nov 2004
    Location
    Norway
    Posts
    1,560
    Here is the code for a bubblepanel. I've not used images for the bubbles, but plain ovals. The ways to vary this animation are innumerable,

    Note: you may want to catch the event of the frame closing, and stop the bubble thread there (when the 'x' instead of 'stop' is clicked).

    Also: the more bubbles you choose to have the longer the animation takes to start.

    There is one thing I have left out: the algorithm for making the bubbles expand in size as they float up, wanna have a go ?

    There is no easy two step way to make bubbles.....

    Code:
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.*;
    import javax.swing.*;
    import java.util.*;
    
    /*****************************************************************************
     * 
    
    Title: Bubble</p>
     * 
    
    Description: A bubbling bubble</p>
     * @author sjalle
     * @version 1.0
     */
    class Bubble  {
      private Point pos=null; // the bubbles position at all time
      private BubblesPan bubblesPan=null; // the container
      private int vertAdvance=0; // vertical advance for each bubble move
      private int moveCnt=0; // counter for bubbles moves
      private int elevInterval=0; // nOf moves between each bubble's expansion
      private Random rand=null; // the bubbles random number generator
      private int bubbleDim=-1; // the square size of the bubble at start
      /**
       * Bubble constructor ************
       * @param bubblesPan
       */
      public Bubble(BubblesPan bubblesPan) {
        this.bubblesPan=bubblesPan;
        pos=new Point();
        // seed the random number generator for this bubble
        rand=new Random(System.currentTimeMillis());
      }
      /**
       * A little debug utility.
       */
      public String toString() {
        return " vertAdvance: "+vertAdvance+" pos: "+pos.x+","+pos.y;
      }
      /**
       * Starts a bubble somewhere in the lower region of the display
       */
      public void initializeBubble() {
        this.vertAdvance=BubblesPan.getRandom(rand,4,10);
        // get startpos somewhere below 50
        pos.y=BubblesPan.getRandom(rand,BubblesPan.MEMIMG_H-50,BubblesPan.MEMIMG_H);
        // get hor.startpos somewhere between 0 and max width
        pos.x=BubblesPan.getRandom(rand,0,BubblesPan.MEMIMG_W);
        // no moves done yet
        moveCnt=0;
        // set bubble size
        bubbleDim=BubblesPan.getRandom(rand,5,15);
      }
      /**
       * A bubble is given a graphics context, it knows its own position
       * and decides its own size and draws itself.
       */
      public void drawBubble(Graphics2D g) {
        Color c=g.getColor(); // save graphics contexts color
        g.setColor(Color.white);
        g.drawOval(pos.x,pos.y,bubbleDim, bubbleDim);
        g.fillOval(pos.x,pos.y,bubbleDim, bubbleDim);
        g.setColor(c); // reset graphics contexts color
      }
      /**
       * Do a bubble move, on every 5th  move, - an x 'wiggle' move is done.  This
       * could have been made better with a sinusoid (...) swimming movement...
       * Also, every bubble is at peril of bursting on each move, the odds are
       * 1 to 100.
       */
      public void move() {
        moveCnt++;
        int xMove=1;
        if ((moveCnt%5)==0) {
          xMove=BubblesPan.getRandom(rand,1,4);
          int fact=(BubblesPan.getRandom(rand,0,5) >= 3) ? 1 : -1;
          xMove*=fact;
          pos.x+=xMove;
        }
        if (pos.x < 0) {
          pos.x+=Math.abs(xMove);
        } else if (pos.x > BubblesPan.MEMIMG_W) {
          pos.x-=Math.abs(xMove);
        }
        pos.y -= this.vertAdvance;
        if (pos.y <= 0) { // this bubble is at top
          initializeBubble();
        } else { // shall it burst ?
          int n=BubblesPan.getRandom(rand, 1,100);
          if (n==50) initializeBubble(); // plopp
        }
      }
    }
    /******************************************************************************
     * 
    
    Title: BubblesPan</p>
     * 
    
    Description: Bubbles, bubbles,  bubbles</p>
     * @author sjalle
     * @version 1.0
     */
    
    public class BubblesPan extends JPanel implements Runnable, ActionListener {
      /**
       * A random number generator, using each calling object's Random
       * number generator instance.
       */
      public static int getRandom(java.util.Random rand, int min, int max) {
        double d=rand.nextDouble()*(double)max;
        return (int)(d+min);
      }
      /**
       * Bubbler thread
       */
      Thread bubbler=null;
      Font introFont=new Font ("Tahoma", Font.BOLD, 28); // intro text font
      /**
       * Memory image for flickerfree animation
       */
      private Graphics2D memG=null;
      private BufferedImage memImg=null;
      public final static int MEMIMG_W=400;
      public final static int MEMIMG_H=1000;
      private Bubble [] bubbles=null; // a set of bubbles
      private int nOfBubbles=-1;
      private boolean isRunning=false; // bubbler threads start/stop flag
    
      /************* MAIN **********************************
       * Set up a JFrame w. three buttons and a bubblepanel
       */
      public static void main(String [] args) {
        // make frame window
        JFrame f=new JFrame("Bubbles");
        f.getContentPane().setLayout(new BorderLayout());
        // make buttons and bubbles panel
        JPanel btnPan=new JPanel(new FlowLayout(FlowLayout.CENTER));
        BubblesPan bubblesPan=new BubblesPan(70); // 30 bubbles
        // make buttons and add to buttonspanel
        JButton closeBtn=new JButton("Close");
        JButton startBtn=new JButton("Start");
        JButton stopBtn=new JButton("Stop");
        btnPan.add(closeBtn);
        btnPan.add(startBtn);
        btnPan.add(stopBtn);
        // make bubblespanel a listener to the buttons
        closeBtn.addActionListener(bubblesPan);
        startBtn.addActionListener(bubblesPan);
        stopBtn.addActionListener(bubblesPan);
        // add the buttonspanel and the bubblespanel to the frame window
        f.getContentPane().add(btnPan,BorderLayout.SOUTH);
        f.getContentPane().add(bubblesPan,BorderLayout.CENTER);
        // size frame window and show it.
        f.setBounds(20,20,400,800);
        f.setVisible(true);
      }
      /**
       * Handle buttons callback
       */
      public void actionPerformed(ActionEvent e) {
        String cmd=e.getActionCommand();
        if (cmd.equals("Close")) {
          this.stopBubbles();
          System.exit(0);
        } else if (cmd.equals("Start")) {
          this.startBubbles();
        } else if (cmd.equals("Stop")) {
          this.stopBubbles();
        }
      }
      /*******************************************************
       * Panel Constructor
       * @param noOfBubbles
       */
      public BubblesPan(int nOfBubbles) {
        initialize();
        this.nOfBubbles=nOfBubbles;
      }
      public Dimension getPreferredSize() {
        return new Dimension (MEMIMG_W,MEMIMG_H);
      }
      /**
       * Establish the memeorybuffer image and get the graphics context.
       */
      void initialize() {
        memImg = new BufferedImage(MEMIMG_W,MEMIMG_H, BufferedImage.TYPE_INT_RGB);
        memG = memImg.createGraphics();
      }
      /**
      * Invoked by buttons in parent JFrame
      */
      public void stopBubbles () {
        setRunning (false);
        bubbles=null;
        this.repaint();
      }
      public void startBubbles() {
        bubbler=new Thread(this);
        setRunning (true);
        bubbler.start();
      }
      /**
       * The way to stop threads, - don't use a Thread's stop method.
       */
      public synchronized void setRunning(boolean isRunning) {
        this.isRunning=isRunning;
      }
      public synchronized boolean getRunning() {
        return this.isRunning;
      }
    
      /**
       * The BubblesPan thread starts the bubbles at varying intervals.
       * Note: creating the bubbles in time intervals gives the
       * desired randomness for the parameters.
       * (they are also using System.currentTimeMillis for seed)
       */
      public void run () {
        while (getRunning()) {
          bubbles=new Bubble[nOfBubbles];
          Random rand = new Random(System.currentTimeMillis());
          for (int i = 0; i < bubbles.length; i++) {
            bubbles[i] = new Bubble(this);
            bubbles[i].initializeBubble();
            try {
              int pause = getRandom(rand, 50, 100);
              bubbler.sleep(pause);
            } catch (Exception ex) {
              return;  // a return from the run method is the threads death.
            }
          }
          while (getRunning()) {
            try {
              bubbler.sleep(20);
              for (int i=0;i<bubbles.length;i++) {
                bubbles[i].move();
              }
              this.repaint();
            } catch (Exception ex) {
              return; // a return from the run method is the threads death.
            }
          }
        }
      }
      /**
       * Draw bubbles on the memoryImage, and transfer whole image to the display
       * grapics when all have finished drawing.  The null tests sorts under the
       * R.O.T.N. directive (Reassurance Of The Nervous) ...:))
       * @param g
       */
      public void update (Graphics g) {
        Color c=memG.getColor();
        memG.setColor(Color.blue);
        memG.fillRect(0,0,MEMIMG_W, MEMIMG_H);  // wipe out w. blue
        if (bubbles!=null) {
          for (int i = 0; i < bubbles.length; i++) {
            if (bubbles[i]!=null) bubbles[i].drawBubble(memG);
          }
        } else {
          memG.setColor(Color.red);
          Font f=memG.getFont();
          memG.setFont(this.introFont);
          memG.drawString("Hit \"Start\" to bubble", 30,30);
          memG.setFont(f); // reset graphics contexts font
        }
        memG.setColor(c);
        g.drawImage(this.memImg,0,0,this);
      }
      public void paint (Graphics g) {
        update(g);
      }
    
    }
    eschew obfuscation

  5. #5
    Join Date
    Dec 2004
    Posts
    4
    thanksvery much for the program you posted, it really helped a lot, and I have learned many thnigs from it, although it did not answer my question regarding the graphics object and why it is not drawing.

    thanks again for your concern..

  6. #6
    Join Date
    Nov 2004
    Location
    Norway
    Posts
    1,560
    The reasons for your code's failure to draw where too many to use as a reference when I was going to explain this. The code showed at least three basic misconceptions: using threads, graphics context and using animated objects.

    Basically you came w. a dysfunctional coffebakingmachine and wondered why it didn't fly
    eschew obfuscation

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center