-
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
-
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
-
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....
-
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
-
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..
-
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
Forum Rules
|
Top DevX Stories
Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL
|
Bookmarks