• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Graphics Graphics Graphics - Where are my circles?

 
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Why won't this paint the circles??? This program is supposed to paint the number of circles that I enter into the JText field (I will max it at 99 circles probably), but as it stands, it will not even paint the one circle in the following code. I have tried adding if circle != null in the paintComponent to catch the nullPointerException, but still no circles. By the way, I am new to Java (a few weeks) so any replies should speak in terms of only the items I've used here. In other words, I don't have the know-how to completely re-write the program. Is there something structurally wrong with it as it is (such as a loop being inside of the listener method, or something like that)?

MAIN (Circles class) ---------------------------------------

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

public class Circles
{
public static final short FRAME_WIDTH = 400;
public static final short FRAME_HEIGHT = 300;
public static final short TEXT_AREA = 80;

public static void main (String[] args)
{
Panel bottomPanel;
TopPanel topPanel;

topPanel = new TopPanel();
bottomPanel = new Panel();

JFrame frame = new JFrame ("Brian Turnpaugh");
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

//Center frame on screen & set visibility state

Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension framesize = frame.getSize();

if (framesize.height > screensize.height)
framesize.height = screensize.height;

if (framesize.width > screensize.width)
framesize.width = screensize.width;

frame.setLocation((screensize.width - framesize.width) / 2,
(screensize.height - framesize.height) / 2);

JPanel primary = new JPanel();
primary.setBackground (Color.black);

primary.add (topPanel);
primary.add (bottomPanel);

frame.getContentPane().add(primary);
frame.setVisible(true);
}
}

Panel Class and TopPanel class------------------------------

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

public class Panel extends JPanel
{
public final short FRAME_WIDTH = 400;
public final short FRAME_HEIGHT = 300;
public final short TEXT_AREA = 80;
JTextField inputBox;
JLabel inputLabel, holdingLabel;
private Circle circle;

public Panel ()
{
final short LABEL_WIDTH = 215;
final short LABEL_HEIGHT = 20;

setBackground (Color.black);
setPreferredSize (new Dimension(FRAME_WIDTH, TEXT_AREA));

inputLabel = new JLabel ("Enter the number of circles:");
inputLabel.setFont (new Font("Arial", Font.BOLD, 16));
inputLabel.setPreferredSize (new Dimension(LABEL_WIDTH, LABEL_HEIGHT));
inputLabel.setForeground (Color.yellow);
add (inputLabel);

inputBox = new JTextField("", 2);
inputBox.addActionListener (new TextListener());
add (inputBox);

holdingLabel = new JLabel ();
holdingLabel.setForeground (Color.yellow);
holdingLabel.setPreferredSize (new Dimension(20, 20));
add (holdingLabel);
}

private class TextListener extends JPanel implements ActionListener
{
public static final short LOWEST_WHITE = 245;

private String circleCount;
private byte count;
private int x, y, rgb, size;
private Color randomWhite;
private Color shade;
private Circle circle;

public void actionPerformed (ActionEvent event)
{
circleCount = inputBox.getText();
holdingLabel.setText(circleCount);
//System.out.println(circleCount);
count = Byte.parseByte(circleCount);

Random randomizer = new Random();

for (byte index = 0; index <= count - 1; index++)
{
size = (randomizer.nextInt(41) + 10);
rgb = randomizer.nextInt(11) + LOWEST_WHITE;
Color randomWhite = new Color(rgb, rgb, rgb);
Color shade = randomWhite;

x = (randomizer.nextInt(FRAME_WIDTH + 1));
y = (randomizer.nextInt(FRAME_HEIGHT - TEXT_AREA + 1));

circle = new Circle (size, shade, x, y);

};
}

}

public void paintComponent (Graphics page)
{
super.paintComponent(page);

circle.draw(page);
}
}

final class TopPanel extends JPanel
{
public final short FRAME_WIDTH = 400;
public final short FRAME_HEIGHT = 300;
public final short TEXT_AREA = 80;

public TopPanel ()
{
setBackground (Color.black);
setPreferredSize (new Dimension(FRAME_WIDTH, FRAME_HEIGHT - TEXT_AREA));
}
}

CIRCLE CLASS--------------------------------------------

import java.awt.*;

public class Circle
{
private int diameter, x, y;
private Color color;

public Circle (int size, Color shade, int upperX, int upperY)
{
diameter = size;
color = shade;
x = upperX;
y = upperY;
}

public void draw (Graphics page)
{
page.setColor (color);
page.fillOval (x, y, diameter, diameter);
}
}
 
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, there are probably many other problems, but the two that I see are...

1. You only have one circle object. You create many random circle objects, but you store it in the same place. Hence, only the last circle can be referrenced.

2. You never request a repaint of you component.

Henry
 
Brian Turnpaugh
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the quick reply, Henry.

Perhaps I'm think too linear. I'm thinking that the loop will create a new circle, paint it right then, (dispose of it), then repeat the process. I'm sure finding out that object-oriented programming and event-driven are two different creatures entirely.

I experimented with the repaint(). I tried it in both the paintComponent and after creating the new Circle object....to no avail.

Any suggestions at this point?
 
Henry Wong
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
As you already mentioned, you have to think in "events". Your event listener is simply storing the value of the number of circles -- and "prep" for the repaint. When it is done, it must then request a repaint.

Your paintComponent() method will get called at a later time, after your listener has completed.

Henry
 
Brian Turnpaugh
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If that's the case, I'm guessing that I need to try using an array again. I tried at one point but probably had other problems then.

Something like:

circle[ArrayIndex] = new Circle (size, shade, x, y);
};

repaint();

} //end of actionPerformed

} //end of text listener

AND

public void paintComponent (Graphics page)
{
super.paintComponent(page);

if (circle[ARRAY] != null) circle[ARRAY].draw(page);
}

If there's a completely different way to re-structure this supposedly simple program, I'm open to re-writing it. Suggestions? Comments?
 
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'd suggest that you start over with a simple program that opens a window and draws a single circle on it immediately. You can do all this inside the paintComponent() method. Once you get that working, modify the program so that the circle is painted when you click a button. From there add an array (or ArrayList) to store multiple circles in.

I often find this kind of incremental coding to be very beneficial. This allows me to concentrate on a single detail at a time. Once I get it working, then I can move onto the next detail.

Let me know if this works for you. And if you come up with any difficulties, let us know.

Keep Coding!

Layne
 
Brian Turnpaugh
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for being straight-forward. That's kind of what I thought, too. Scrap it. It wasn't right structurally.

I'll probably have stupid questions then. My professor isn't very good and neither is my text book. Both are to vague and the Sun site is cryptic for a newbie. I even picked up two books at the library today in a fit of rage. LOL. This sure isn't anything like Visual Basic!

Drawing in applets is covered semi-well in the book but not drawing in apps. The paintComponent will go into a class outside of the main, correct? Like in the Panel class that I used before?

----ADDITIONAL----

Oh yeah, I'll caught the "we're not doing your homework" comments on other posts. Well, this project is over two weeks late. The urgency is well past. I just want to get it working just for the sake of it. It is spring break after all.

The original project? Write a program to draw random sized circles (large enough to see). Must be various shades of white. (I used 245,245,245...246,246,246...and up). User must be able to enter the number of circles and the prompt must be at the bottom of the screen. (We hadn't covered layout managers yet, hence the empty panel I used at the top.) Window must be 300 x 400. (No problem!) The text listener was not required, but I like the idea. I'd love to see the listener accept a new entry and update according to it, too, ideally.


Following your advice for now and trying the paintComponent OUTSIDE of the main.
 
Brian Turnpaugh
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I give up! I simply do not know how to do it that way! There are no simple examples in any of my books.

Wait a minute. Do I just write it as if I were writing into the paint method of an applet, putting it instead into the paintComponent method?
 
Brian Turnpaugh
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here's another approach. The following app is straight from the book and is what I originall tried to modify. The question was where to put the listener and where to put the loop:


//********************************************************************
// xxx.java Author: Lewis/Loftus
//
// Demonstrates
//********************************************************************

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

public class Splat
{
//-----------------------------------------------------------------
// Presents a collection of circles.
//-----------------------------------------------------------------
public static void main (String[] args)
{
JFrame frame = new JFrame ("Splat");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

frame.getContentPane().add(new SplatPanel());

frame.pack();
frame.setVisible(true);
}
}

//********************************************************************
// SplatPanel.java Author: Lewis/Loftus
//
// Demonstrates the use of graphical objects.
//********************************************************************

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

public class SplatPanel extends JPanel
{
private Circle circle1, circle2, circle3, circle4, circle5;

//-----------------------------------------------------------------
// Constructor: Creates five Circle objects.
//-----------------------------------------------------------------
public SplatPanel()
{
circle1 = new Circle (30, Color.red, 70, 35);
circle2 = new Circle (50, Color.green, 30, 20);
circle3 = new Circle (100, Color.cyan, 60, 85);
circle4 = new Circle (45, Color.yellow, 170, 30);
circle5 = new Circle (60, Color.blue, 200, 60);

setPreferredSize (new Dimension(300, 200));
setBackground (Color.black);
}

//-----------------------------------------------------------------
// Draws this panel by requesting that each circle draw itself.
//-----------------------------------------------------------------
public void paintComponent (Graphics page)
{
super.paintComponent(page);

circle1.draw(page);
circle2.draw(page);
circle3.draw(page);
circle4.draw(page);
circle5.draw(page);
}
}

//**************************************
//* PROGRAM -> Circle.java
//* AUTHOR -> Brian Turnpaugh
//* DATE -> 02 / 28 / 2005
//**************************************

import java.awt.*;

public class Circle
{
private int diameter, x, y;
private Color color;

public Circle (int size, Color shade, int upperX, int upperY)
{
diameter = size;
color = shade;
x = upperX;
y = upperY;
}

public void draw (Graphics page)
{
page.setColor (color);
page.fillOval (x, y, diameter, diameter);
}

public void setDiameter (int size)
{
diameter = size;
}

public void setColor (Color shade)
{
color = shade;
}

public void setX (int upperX)
{
x = upperX;
}

public void setY (int upperY)
{
y = upperY;
}

public int getDiameter ()
{
return diameter;
}

public Color getColor ()
{
return color;
}

public int getX ()
{
return x;
}

public int getY ()
{
return y;
}
}
 
Ranch Hand
Posts: 342
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, the paintComponent() method is roughly equivalent to the Applet paint() method.

Take a look at this possible implementation of a class which inherits from the JPanel and uses the paintComponent() method to draw any circle data that is given to it...



Here I am storing the circles that are added to the panel inside an ArrayList. At first the panel may have no circle data, so it just writes a message to say there are no circles.

Elsewhere let's say you have an instance of this CirclePanel which you have added to your GUI. Let's say it's called cPanel. Now, in the listener code you can do something like...



this code may not be perfect by the way, although the CirclePanel does compile
[ March 17, 2005: Message edited by: Ben Wood ]
 
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Moving to Swing/AWT...
 
Ranch Hand
Posts: 1535
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
 
Brian Turnpaugh
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
For those who may follow this thread later....

Here's another solution, a modification of my original attempt.

2 files, with the second containing 2 classes.
-------------------------------------------------------




Thanks to all for the tips!
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic