I created a program that is supposed to draw a circle with each click(Random size and random color), and each circle is going to be an object. I don't know what is going on but my code doesn't work and I am pretty sure I am almost there.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
public class Circle
{
private JFrame frame;
CircleObj circleObj;
Random rand;
int rColor;
int gColor;
int bColor;
int radius;
public static void main (String [] arg)
{
frame = new JFrame("Circles");
frame.setBounds(200, 100, 600, 480);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
JPanel top = new JPanel();
rand = new Random();
top.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
int xstart = e.getX();
int ystart = e.getY();
rColor = rand.nextInt(256);
gColor = rand.nextInt(256);
bColor = rand.nextInt(256);
radius = rand.nextInt(20);
circleObj = new CircleObj(xstart, ystart, rColor, gColor, bColor, radius);
repaint();
}
});
frame.add(top, BorderLayout.CENTER);
frame.setVisible(true);
}
}
and here is my CircleObj class
import javax.swing.*;
import java.awt.*;
public class CircleObj extends JPanel
{
private int xVal;
private int yVal;
private int red;
private int green;
private int blue;
private int circleRadius;
public CircleObj (int x, int y, int r, int g, int b, int rad)
{
xVal = x;
yVal = y;
red = r;
green= g;
blue = b;
circleRadius = rad;
}
public void paintComponent (Graphics g) {
super.paintComponent(g);
g.setColor(new Color(red, green, blue));
g.fillOval(xVal,yVal,circleRadius,circleRadius);
}
}
You add a MouseListener to the top JPanel, but when do you add the top JPanel to the top-level window, the GUI? --- In the MouseListener! So this will never work since the top JPanel is not part of the GUI initially, and only gets added when a MouseListener that is added to it is triggered. The MouseListener only works on components that are visible and on the GUI.
Next you create a CircleObj object, but never draw with it in any JComponent's or JPanel's paiintComponent method.
I am pretty sure I am almost there.
So no, not quite. You will want to re-start and:
Create a JPanel that has a decent paintComopnent method override,
Add this JPanel to the JFrame to the GUI from the beginning.
Add an ArrayList<CircleObj> to this drawing JPanel
Change your CircleObj class so that it doesn't extend JPanel, but does have a public void draw(Grpahics g) method that will draw it.
Add a MouseListener to the JPanel that controls this drawing. In your MouseListener, add a new CircleObj to the ArrayList and call repaint() to get the drawing JPanel to draw.
In the JPanel's paintComponent override, iterate through the ArrayList<CircleObj> calling each object's draw(g) method.
Read the Swing graphics tutorials.
Here is a second approach... How would I be able to tweak it store each circle in an object (Arraylist of objects) ?
public class Circle {
public static void main (String[] arg) {
JFrame frame = new JFrame("Circles");
CircleObj canvas = new CircleObj();
frame.add(canvas, BorderLayout.CENTER);
frame.setBounds(250, 98, 600, 480);
//frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
} // end main
} //end Circle
CircleObj Class
public class CircleObj extends JPanel {
private int rColor;
private int gColor;
private int bColor;
private int radius;
private Random rand = new Random();
private int xStart;
private int yStart;
public CircleObj () {
addMouseListener(new MouseAdapter() {
public void mouseClicked (MouseEvent e) {
xStart = e.getX();
yStart = e.getY();
rColor = rand.nextInt(256);
gColor = rand.nextInt(256);
bColor = rand.nextInt(256);
radius = rand.nextInt(20);
System.out.println("xstart : " + xStart + ", ystart : " + yStart + ", rColor : " + rColor + ", gColor = " +
gColor + ", bColor: " + bColor + ", radius: " + radius);
repaint();
}
}); // end addMouseListener
}
public void paintComponent (Graphics g) {
super.paintComponent(g);
g.setColor(new Color(rColor, gColor, bColor));
g.fillOval(xStart, yStart, radius, radius);
}
}
Related
Hello I am currently making a small game in java, and I am running into problems trying to making the gamepanel. I am using a JPanel as the basis and JPanel to the top to put in a HUD, and a gamepanel for the playable protion of the game. I can add the two panels the HUD and gamepanel fine. However the objects which are JComponents will not show up at all. I know they are created I'm not sure how to make them visible though.
Here are my classes:
This is my window class that holds the panels:
public class Window extends JFrame {
public static final int ScreenWidth = 1000;
public static final int ScreenHeight = 700;
public static JFrame frame;
private StatesHandler statesHandler;
public Window(JFrame frame) throws IOException {
this.frame = frame;
this.statesHandler = new StatesHandler();
displaywindow();
}
public void paint(Graphics g) {
super.paint(g);
}
public void displaywindow() {
this.frame.setLayout(new FlowLayout());
this.frame.setPreferredSize(new Dimension(ScreenWidth,ScreenHeight));
this.frame.setMaximumSize(new Dimension(ScreenWidth,ScreenHeight));
this.frame.setMinimumSize(new Dimension(ScreenWidth,ScreenHeight));
this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.frame.setResizable(false);
this.frame.setBackground(Color.pink);
this.frame.setLocationRelativeTo(null);
this.frame.pack();
this.frame.setVisible(true);
}
public JFrame getFrame() {
return this.frame;
}
This is this the level class:
it holds the hud and the gamepanel
private Window win;
Level(Window win) {
this.setPreferredSize(new Dimension(gw,gh));
this.win = win;
this.setFocusable(true);
this.requestFocus();
Hud hud = new Hud();
getwinframe().getContentPane().add(hud);
getwinframe().getContentPane().validate();
gamepanel gmp = new gamepanel();
getwinframe().getContentPane().add(gmp);
getwinframe().getContentPane().revalidate();
Ball ball = new Ball(600, 200, 3, 3);
System.out.println(this);
gmp.add(ball);
gmp.revalidate();
}
Here is the Ball which I am trying to add to gamepanel
public Ball(int xpos, int ypos,int vx, int vy) {
this.xpos =xpos;
this.ypos = ypos;
this.vx = vx;
this.vy = vy;
this.collsionbox = new Rectangle(xpos, ypos, bwidth, bheight);
}
This is the gamepanel which I'm trying to add the ball to
public gamepanel(){
this.setPreferredSize(new Dimension(Window.ScreenWidth, Window.ScreenHeight -Window.ScreenHeight/6));
this.setLayout(new FlowLayout());
System.out.println(Window.ScreenWidth +" " + Window.ScreenHeight/6);
this.setBackground(Color.pink);
Ball ball2 = new Ball(500, 100, 3, 3);
System.out.println(ball2);
add(ball2);
validate();
}
I'm writing a program that displays a circle every time you click the Jpanel. I have it all set up and I want to be able to use the drawCircle method I created in my circle class to draw the circles in the paintComponent method. I'm storing all of the circles created in a linked list. Then I interate through each Circle in the list and try to use the method in my Circle class called drawCircle().
For some reason, if I try to use c1.drawCircle() in a for loop in the My panel class it only draws the last circle that was created. But if I just use g.fillOval(with the correct parameters grabbing the values from the Circle class) in the for loop it works properly and displays all the circles. Why is it doing this and how do I go about using the method in the Circle class properly
I'm unsure what to try right now.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.LinkedList;
public class MouseTest {
private int borderWidth = 20;
private JFrame frame;
private boolean tracking;
private boolean start;
private boolean clearBol;
private int xstart;
private int ystart;
private int xend;
private int yend;
private LinkedList<Circle> circles;
public MouseTest() {
tracking = false;
start = false;
circles = new LinkedList<Circle>();
frame = new JFrame();
frame.setBounds(250, 98, 600, 480);
frame.setTitle("Window number three");
Container cp = frame.getContentPane();
JButton clear = new JButton("Clear");
JToggleButton circleButton = new JToggleButton()("Circles");
JToggleButton drawButton = new JToggleButton("Draw");
ButtonGroup circleOrDraw = new ButtonGroup();
MyPanel pane = new MyPanel();
clear.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
clearBol = true;
frame.repaint();
}
});
JPanel top = new JPanel();
top.setLayout(new FlowLayout());
top.add(clear);
circleOrDraw.add(circleButton);
circleOrDraw.add(drawButton);
top.add(circleOrDraw);
cp.add(top, BorderLayout.NORTH);
cp.add(pane, BorderLayout.CENTER);
pane.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
xstart = e.getX();
ystart = e.getY();
start = false;
}
public void mouseReleased(MouseEvent e) {
xend = e.getX();
yend = e.getY();
if (xend < xstart) {
int tmp = xstart;
xstart = xend;
xend = tmp;
}
if (yend < ystart) {
int tmp = ystart;
ystart = yend;
yend = tmp;
}
start = true;
frame.repaint();
}
});
pane.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
if (tracking) {
int x = e.getX();
int y = e.getY();
msg("(" + x + ", " + y + ")");
}
}
});
frame.setVisible(true);
} // constructor
public static void main(String[] arg) {
MouseTest first = new MouseTest();
} // main
public void msg(String s) {
System.out.println(s);
}
public void trackMouse() {
tracking = !tracking;
} // trackMouse
public class Circle extends JPanel {
Graphics g;
int x;
int y;
int r;
Color color;
public Circle(Graphics g, int x, int y, int r) {
this.g = g;
this.x = x;
this.y = y;
this.r = r;
int red = (int) (256 * Math.random());
int green = (int) (256 * Math.random());
int blue = (int) (256 * Math.random());
this.color = new Color(red, green, blue);
}
public void drawCircle() {
int x2 = x - (r / 2);
int y2 = y - (this.r / 2);
g.setColor(color);
g.fillOval(x2, y2, this.r, this.r);
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Color getColor() {
return color;
}
public int getR() {
return r;
}
}
public class MyPanel extends JPanel {
public void paintComponent(Graphics g) {
if (start) {
circles.add(new Circle(g, xend, yend,
(int) ((250 * Math.random() + 4))));
//Area where I'm having issues
for (Circle c1 : circles) {
msg("" + c1.getX());
// this method that I created in the circle class will only draw the first circle
//c1.drawCircle();
int r = c1.getR();
int x = c1.getX();
int y = c1.getY();
g.setColor(c1.getColor());
g.fillOval((c1.getX() - (r / 2)), (c1.getY() - (r / 2)),
r, r); // this will display all the circles
}
int size = circles.size();
msg(size + " Size");
msg("" + circles.getLast().getX());
}
if (clearBol) {
super.paintComponent(g);
circles.clear();
clearBol= false;
}
Thank you!
Most of the structure of your class needs to be changed
Your MyPanel should have a better name to give its functionality, maybe something like DrawingPanel.
The DrawingPanel is then responsible for managing the Circles to be painted. So typically you would just use an ArrayList to hold the Circle information.
Then you would add a method to the class, like addCircle(...) to add the Circle information to the ArrayList and then invoke repaint().
Then in your paintComponent(...) method the first thing you do is invoke super.paintComponent(...) to clear the panel. Then you iterate through the ArrayList and paint all the Circles. There will be no need for the Boolean values to check the state of the class. The ArrayList will either have circles or it won't.
You would also need a method like clearCircles(). This would simply remove all the Circles from the ArrayList and invoke repaint() on itself.
Your Circle class should NOT extend JPanel. It should just be a class that contains the information need to paint the circle: x/y location, size of circle and color of circle.
Now your frame is responsible of displaying your DrawingPanel and the buttons.
When you click the "Clear" button you simply invoke the clearCircles() method of the DrawingPanel.
For your MouseListener you simply invoke the addCircle(...) method of your DrawingPanel once you have all the information needed to create a Circle instance.
For a complete working example that incorporates all these suggestions check out the DrawOnComponent example found in Custom Painting Approaches
It runs, the buttons work, but i just can't get it to draw with the paint(). I think it has something to do with the main method on SwingDraw, but i'm not 100% sure. Thanks for any help and sorry for the long code :/
SwingDraw:
// Import Core Java packages
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.*;
import javax.swing.*;
public class SwingDraw extends JFrame implements ActionListener, ItemListener{
// Initial Frame size
static final int WIDTH = 1500; // frame width
static final int HEIGHT = 1000; // frame height
// Color choices
static final String[] COLOR_NAMES = new String[]{"None", "Red", "Blue", "Green"};
static final Color COLORS[] = {null, Color.red, Color.blue, Color.green };
// Button control
JButton circle;
JButton roundRec;
JButton threeDRec;
JButton line;
JButton square;
JButton oval;
JButton clear;
JButton delete;
// List to keep track of shapes
JList<String> shapesKeeper;
// Color choice box
JComboBox<String> colorChoice = new JComboBox<>(COLOR_NAMES);
SwingDrawCanvas betterCanvas = new SwingDrawCanvas();
/**
* Constructor
*/
public SwingDraw() {
// Create a frame
setSize(WIDTH, HEIGHT);
setLocation(130, 100);
// add window closing listener
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// create panel for controls
JPanel topPanel = new JPanel();
JPanel leftList = new JPanel();
// create button control
JPanel buttonPanel = new JPanel();
topPanel.add(buttonPanel, BorderLayout.NORTH);
circle = new JButton("Circle");
buttonPanel.add(circle);
roundRec = new JButton("Rounded Rectangle");
buttonPanel.add(roundRec);
threeDRec = new JButton("3D Rectangle");
buttonPanel.add(threeDRec);
line = new JButton("Line");
buttonPanel.add(line);
square = new JButton("Square");
buttonPanel.add(square);
oval = new JButton("Oval");
buttonPanel.add(oval);
clear = new JButton("Clear");
buttonPanel.add(clear);
JPanel listPanel = new JPanel();
leftList.add(listPanel, BorderLayout.WEST);
JList<String> shapesKeeper = new JList<>();
listPanel.add(shapesKeeper);
delete = new JButton("Delete Shape");
listPanel.add(delete);
// add button listener
circle.addActionListener(this);
roundRec.addActionListener(this);
threeDRec.addActionListener(this);
line.addActionListener(this);
square.addActionListener(this);
oval.addActionListener(this);
clear.addActionListener(this);
// create panel for color choices
JPanel colorPanel = new JPanel();
JLabel label = new JLabel("Filled Color:");
topPanel.add(colorPanel);
colorPanel.add(label);
JComboBox<String> colorChoice = new JComboBox<>(COLOR_NAMES);
colorPanel.add(colorChoice);
colorChoice.addItemListener(this);
add(topPanel, BorderLayout.NORTH);
add(leftList, BorderLayout.WEST);
setVisible(true);
} // end of constructor
/**
* Implementing ActionListener
*/
public void actionPerformed(ActionEvent event) {
if(event.getSource() == circle) { // circle button
betterCanvas.setShape(SwingDrawCanvas.CIRCLE);
}
else if(event.getSource() == roundRec) { // rounded rectangle button
betterCanvas.setShape(SwingDrawCanvas.ROUNDED_RECTANGLE);
}
else if(event.getSource() == threeDRec) { // 3D rectangle button
betterCanvas.setShape(SwingDrawCanvas.RECTANGLE_3D);
}
else if(event.getSource() == clear){
betterCanvas.setShape(SwingDrawCanvas.CLEAR);
}
else if(event.getSource() == line){
betterCanvas.setShape(SwingDrawCanvas.LINE);
}
else if(event.getSource() == square){
betterCanvas.setShape(SwingDrawCanvas.SQUARE);
}
else if(event.getSource() == oval){
betterCanvas.setShape(SwingDrawCanvas.OVAL);
}
}
/**
* Implementing ItemListener
*/
public void itemStateChanged(ItemEvent event) {
Color color = COLORS[colorChoice.getSelectedIndex()];
betterCanvas.setFilledColor(color);
}
/**
* the main method
*/
public static void main(String[] argv) {
new SwingDraw();
}
}
SwingDrawCanvas:
public class SwingDrawCanvas extends JPanel implements MouseListener, MouseMotionListener {
// Constants for shapes
public static final int CIRCLE = 1;
public static final int ROUNDED_RECTANGLE = 2;
public static final int RECTANGLE_3D = 3;
public static final int LINE = 4;
public static final int SQUARE = 5;
public static final int OVAL = 6;
public static final int CLEAR = 7;
// Coordinates of points to draw
private int x1, y1, x2, y2;
// shape to draw
private int shape = CIRCLE;
/**
* Method to set the shape
*/
public void setShape(int thisShape) {
System.out.println("HEY");
this.shape = thisShape;
System.out.println(shape);
}
// filled color
private Color filledColor = null;
/**
* Method to set filled color
*/
public void setFilledColor(Color color) {
filledColor = color;
}
/**
* Constructor
*/
public SwingDrawCanvas() {
addMouseListener(this);
addMouseMotionListener(this);
} // end of constructor
/**
* painting the component
*/
public void paint(Graphics g) {
System.out.println("ARHFHASJDASHDHAs");
super.paint(g);
System.out.println("AHAHAHAHAHAHAHA");
g.drawString("FUCK", 1, 1);
// the drawing area
int x, y, width, height;
// determine the upper-left corner of bounding rectangle
x = Math.min(x1, x2);
y = Math.min(y1, y2);
// determine the width and height of bounding rectangle
width = Math.abs(x1 - x2);
height = Math.abs(y1 - y2);
if(filledColor != null)
g.setColor(filledColor);
switch (shape) {
case ROUNDED_RECTANGLE :
if(filledColor == null)
g.drawRoundRect(x, y, width, height, width/4, height/4);
else
g.fillRoundRect(x, y, width, height, width/4, height/4);
break;
case CIRCLE :
int diameter = Math.max(width, height);
if(filledColor == null)
System.out.println("HRE BITCHS");
else
System.out.println("HEY FUCK YOU GUY");
break;
case RECTANGLE_3D :
if(filledColor == null)
g.draw3DRect(x, y, width, height, true);
else
g.fill3DRect(x, y, width, height, true);
break;
}
}
/**
* Implementing MouseListener
*/
public void mousePressed(MouseEvent event) {
x1 = event.getX();
y1 = event.getY();
}
public void mouseReleased(MouseEvent event) {
x2 = event.getX();
y2 = event.getY();
repaint();
}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
/**
* Implementing MouseMotionListener
*/
public void mouseDragged(MouseEvent event) {
x2 = event.getX();
y2 = event.getY();
repaint();
}
public void mouseMoved(MouseEvent e) {}
}
I'm not very good at this, I'm just looking for any help you guys can give me :D
Instead of having paint(), your function should be name paintComponent(Graphics g).
When creating the paintComponent(Graphics g) functions, you need #Override so that java recognizes the function because you can not call paintComponent(Graphics g) directly.
In addition, any time you want to refresh your panel, you can call repaint() or you can resize your JFrame after the code as compiled. Both of these methods will call the paintComponent(Graphics g) function.
So I have a button listener that is external in scope to the function setPaintFlag() and I need to call it, but java is giving me runtime errors. In addition my drawing panel is not showing up. Can anyone spot my mistake? the purpose of the program is to draw either a circle or a square in a random position with a random size and a color. The program compiles and the window will show up, only the buttons are visible but they do not fire. the error visible when i hover over the setPaintFlag() is The method setPaintFlag(int) is undefined for the type PaintLab.buttonListener
A more verbose error message after a button press is
Exception in thread "AWT-EventQueue-0" java.lang.Error: Unresolved compilation problems:
The method setPaintFlag(int) is undefined for the type PaintLab.ButtonListener
The method setPaintFlag(int) is undefined for the type PaintLab.ButtonListener
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PaintLab extends JPanel {
private JButton circle, square;
private JPanel drawingPanel;
public PaintLab() {
circle = new JButton("Draw Circle");
circle.addActionListener(new ButtonListener());
square = new JButton("Draw Square");
square.addActionListener(new ButtonListener());
JPanel buttonPanel = new JPanel();
JPanel drawingPanel = new DrawingPanel(400, 400);
add(drawingPanel);
BoxLayout bX = new BoxLayout(buttonPanel, BoxLayout.X_AXIS);
buttonPanel.setLayout(bX);
buttonPanel.add(circle);
buttonPanel.add(square);
add(buttonPanel);
}
private class DrawingPanel extends JPanel { // outer
private boolean paintFlag = false;
private int theMode = -1;
private int width, height;
private DrawingPanel(int width, int height) { // inner
this.width = width;
this.height = height;
}
public void setPaintFlag(int current) { // inner
paintFlag = true;
theMode = current;
}
public void paintComponent(Graphics g) { // inner
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
int r = (int) (Math.random() * 255) + 1;
int gn = (int) (Math.random() * 255) + 1;
int b = (int) (Math.random() * 255) + 1;
g2.setColor(new Color(r, gn, b));
int w = (int) (Math.random() * width) + 1;
int h = (int) (Math.random() * height) + 1;
int x = (int) (Math.random() * width) + 1;
int y = (int) (Math.random() * height) + 1;
if (theMode == 0) {
g2.drawOval(x, y, w, h);
g2.fillOval(x, y, w, h);
} else if (theMode == 1) {
g2.drawRect(x, y, w, h);
g2.fillRect(x, y, w, h);
}
g2.dispose();
}
}
private class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
if (event.getSource() == circle) {
setPaintFlag(0);
drawingPanel.repaint();
} else if (event.getSource() == square) {
setPaintFlag(1);
drawingPanel.repaint();
}
}
}
}
And this is the main.
public class paintLabMain {
public static void main(String[] args) {
JFrame frame=new JFrame("Paint Lab");
frame.setPreferredSize(new Dimension (300,600));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new PaintLab());
frame.pack();
frame.setVisible(true);
}
}
The buttons don't fire because they have no action listener:
Circle = new JButton("Draw Circle")
Circle.addActionListener(new buttonListener())
The error message is because you call setPaintFlag(int current) form ButtonListener but it is defined in DrawingPanel.
Edit:
Please see comments (The code can't compile because I removed parts of it and left a skeleton):
public class PaintLab extends JPanel {
private JButton circle, square;
private DrawingPanel drawingPanel;//declare drawingPanel as field
public PaintLab() {
circle = new JButton("Draw Circle");
circle.addActionListener(new ButtonListener());
square = new JButton("Draw Square");
square.addActionListener(new ButtonListener());
JPanel buttonPanel = new JPanel();
/*JPanel already declared as field*/
drawingPanel = new DrawingPanel(400, 400);
add(drawingPanel);
BoxLayout bX = new BoxLayout(buttonPanel, BoxLayout.X_AXIS);
buttonPanel.setLayout(bX);
buttonPanel.add(circle);
buttonPanel.add(square);
add(buttonPanel);
}
private class DrawingPanel extends JPanel { // outer
//code removed
}
public void paintComponent(Graphics g) { // inner
//code removed
}
//add setters
void setPaintFlag(boolean paintFlag) {
this.paintFlag = paintFlag;
}
void setTheMode(int theMode) {
this.theMode = theMode;
}
}
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
if (event.getSource() == circle) {
drawingPanel.setPaintFlag(true);
drawingPanel.repaint();
} else if (event.getSource() == square) {
drawingPanel.setPaintFlag(false);
drawingPanel.repaint();
}
}
}
}
I have JPanel in a container of a JFrame called Box
public Box(){
add(new Ball());
}
public void paint(Graphics g){
g.setColor(Color.WHITE);
g.fillRect(OFFSET, OFFSET, WIDTH, HEIGHT);
g.setColor(Color.BLACK);
g.drawRect(OFFSET, OFFSET, WIDTH, HEIGHT);
}
Ball extends Component and draws a ball
public class Ball extends Component{
...
public void paint(Graphics g){
g.setColor(Color.BLACK);
g.fillOval(xCoord, yCoord, radius, radius);
}
...
}
When I add a Box with a Ball to the container I can only ever see the Box. If I just add a Ball I can see the Ball.
Does anyone know why the Ball is not visible when added to a Box?
In addition to overriding paintComponent, use a LayoutManager to set bounds automatically. For testing purposes, you can set the LayoutManager of the Box instance to null and use setBounds on the Ball instance.
Do not mix heavyweight and lightweight components. You should be extending JComponent instead.
You should be overriding paintComponent(), not paint().
Does Ball have a size? If you haven't supplied Ball with a Dimension, it won't be visible.
In Swing, you should normally never override the paint method. Use paintComponent instead.
there are three possible mistake
1/ simpliest paint by using JLabel
2/ timing by javax.swing.Timer
3/ paintComponents instead of paint (for AWT Compoents and painting DefaultXxxUI)
and put that together, for example
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class AnimationJPanel extends JPanel {
private static final long serialVersionUID = 1L;
private int cx = 0;
private int cy = 150;
private int cw = 20;
private int ch = 20;
private int xinc = 1;
private int yinc = 1;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
AnimationJPanel panel = new AnimationJPanel();
panel.setPreferredSize(new Dimension(400, 300));
panel.animate();
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public AnimationJPanel() {
setLayout(new BorderLayout());
JLabel label = new JLabel("This is an AnimationJPanel");
label.setForeground(Color.RED);
label.setHorizontalAlignment(SwingConstants.CENTER);
add(label);
setBackground(Color.BLACK);
setForeground(Color.RED);
setOpaque(true);
}
public void animate() {
new Timer(15, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Rectangle oldCircle = new Rectangle(cx - 1, cy - 1, cw + 2, ch + 2);
cx += xinc;
cy += yinc;
if (cx >= getWidth() - cw || cx <= 0) {
xinc *= -1;
}
if (cy >= getHeight() - ch || cy <= 0) {
yinc *= -1;
}
repaint(oldCircle);
repaint(cx - 1, cy - 1, cw + 2, ch + 2);
}
}).start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawOval(cx, cy, cw, ch);
}
}