0

EDIT: Fixed up code:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Dimension;


public class JumpingBall extends JPanel{
@Override
public Dimension getPreferredSize()
{
    return new Dimension(300,300);
}


public void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D rectangle = (Graphics2D) g;
    rectangle.setColor(Color.BLACK);
    rectangle.fillRect(0,270,300,30);
}


public static void main(String[] args) {
    JFrame frame = new JFrame("Jumping Ball");


    frame.getContentPane().add(new JumpingBall());
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
}
}

I've set myself the task of writing some code that simple makes a ball jump from the floor at the users command. Step 1 was to create a window and a floor - I noticed that the location I added my floor tended to be off screen and discovered here that frame.setSize(x,y) includes the borders and you should embed a JPanel inside the frame and size that instead. However upon attempting to make these changes my rectangle.fillRect(x,y,width,height) seems to appear as a small square top center regardless of the variables. Why could this be happening?

Code:

    import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Dimension;

public class JumpingBall extends JPanel{
    public void paint(Graphics g){
        Graphics2D rectangle = (Graphics2D) g;
        rectangle.setColor(Color.BLACK);
        rectangle.fillRect(0,0,300,30);
    }

public static void main(String[] args) {
    JFrame frame = new JFrame("Jumping Ball");
    JPanel panel = new JPanel();

    panel.setPreferredSize(new Dimension(300,300));
    panel.add(new JumpingBall());

    frame.getContentPane().add(panel);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
}
}

Here's a screenshot of my failed floor.

Community
  • 1
  • 1
Jonathan
  • 77
  • 1
  • 12
  • 1
    1) `public void paint(Graphics g){ Graphics2D rectangle = (Graphics2D) g;` should instead be `public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D rectangle = (Graphics2D) g;` for any `JComponent` or anything that extends it. 2) See [Detection/fix for the hanging close bracket of a code block](http://meta.stackexchange.com/q/251795/155831) for a problem I could no longer be bothered fixing. 3) `JumpingBall` should also `@Override` the `getPreferredSize()` method to return a suitable size as hint to the layout manager of the parent container (`panel`). – Andrew Thompson Sep 27 '16 at 13:13

1 Answers1

2

When you do custom painting:

  1. You should override paintComponent() not paint() and invoke super.paintComponent(g) as the first statement to make sure the background is cleared.

  2. Override the getPreferredSize() method of the class to return the size of the panel so layout managers can do there job. So in your case it should be (300, 300).

In your code you should not be setting the preferred size of any components. It is the job of the layout manager to determine the preferred size of a component.

panel.setPreferredSize(new Dimension(300,300));

You currently set the preferred size of the panel holding the jumping ball. This doesn't help because the preferred size of the jumping ball has not been set. You see a (10, 10) square because the FlowLayout of the panel determines the preferred size of your jumping ball panel is only (10, 10).

Also, there is no need to create a separate panel. You can just add the JumpingBall panel directly to the frame.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • Thanks for your help, I think I've adjusted everything accordingly and learnt about overriding and setting frame/panel sizes. I'm editing in my fixed code above, feel free to let me know if there's anything glaring I've missed or is still problematic from a more experienced coding viewpoint! – Jonathan Sep 27 '16 at 13:41
  • I noticed you added another comment suggesting I missed the first point and offered some recommended reading but it seems to have gone now - was it still relevant? – Jonathan Sep 27 '16 at 14:19
  • @Jonathan, I was going to suggest that you read the section from the Swing tutorial on [Custom Painting](http://docs.oracle.com/javase/tutorial/uiswing/painting/index.html) for more general information and examples. When you look at the example you can also notice how the GUI is created using a `SwingUtiltities.invokeLater()`. This is to make sure the GUI us updated on the `Event Dispatch Thread (EDT)`. You can also read the section on `Concurrency in Swing` for more information about the EDT. – camickr Sep 27 '16 at 20:43