import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class controlBall extends JFrame {
	private JButton jbtRight = new JButton("Right");
	private JButton jbtLeft = new JButton("Left");
	private BallCanvas canvas = new BallCanvas();
	
	public controlBall(){
		JPanel panel = new JPanel();//use the panel to group buttons
		panel.add(jbtLeft);
		panel.add(jbtRight);
		
		this.add(canvas, BorderLayout.CENTER);//add canvas to the center
		this.add(panel, BorderLayout.SOUTH);///add buttons to the frame
		
		jbtLeft.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				canvas.moveLeft();
			}
		});
		
		jbtRight.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				canvas.moveRight();	
			}
		});
	}
	
	//main method
	public static void main(String[] args){
		JFrame frame = new controlBall();
		frame.setTitle("Control Ball");
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(200, 200);
		frame.setVisible(true);
	}
	
	
	public static class BallCanvas extends JPanel{
		private int yCoordinate = 25;
		private int xCoordinate;
		
		public void moveRight(){
			xCoordinate += 10;
			repaint();
		}
		
		public void moveLeft(){
			xCoordinate -= 10;
			repaint();
		}
		
		protected void paintComponent(Graphics g){
			super.paintComponents(g);
			g.drawOval(xCoordinate, yCoordinate, 10, 10);
		}
		
	}

}

it does run but after pressing the button for right or left the position in which the ball was before doesn't erase.. any idea why? thanks.

Dani AI

Generated

Nice catch by . The trails happen because the panel is never clearing its own background before you draw the next frame. Inside your paintComponent, you are calling the plural paintComponents(...), which repaints child components but does not clear this panel. Use the singular paintComponent(...) so Swing clears the background first, then draw the ball. That also explains why resizing the window seemed to fix it in Post #3: a resize triggers a full repaint, which clears the old drawings.

A minimal fix looks like this:

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);        // singular: clears the panel
    g.fillOval(xCoordinate, yCoordinate, 10, 10); // solid ball reads better
}

Make sure the canvas is actually opaque and has a background so there is something to clear:

public BallCanvas() {
    setOpaque(true);
    setBackground(Color.WHITE);
}

A few quality-of-life tweaks you may find helpful:

  • Give the canvas a preferred size and pack() the frame instead of hard-coding size.
  • Clamp the x position so the ball does not disappear off the edges.
@Override
public Dimension getPreferredSize() { return new Dimension(200, 200); }

// after updating xCoordinate
xCoordinate = Math.max(0, Math.min(getWidth() - 10, xCoordinate));

If you later want smooth motion instead of button taps, use a javax.swing.Timer to update xCoordinate on the EDT and call repaint(). This keeps painting responsive and avoids manual loops.

Recommended Answers

All 4 Replies

Take a closer look at line 56 and note which method you are calling. It may not be the one you want.

I took it off and it works the same.. another thing is that when I drag the mouse to enlarge the size of the windows the other images are gone and is like is working fine.. so I don't know if is just my java compiler or the code itself..

I didn't say remove it - I said it may be the wrong one. Spelling counts.

OMG...!!!! Dude you are awesome thank you!!! thank you!! very much ^^ program works fine now :D...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.