André Carvalho André Carvalho - 9 days ago 6
Java Question

JPanel problems with drawing ovals

I created an application that draws a random number of ovals (with random sizes and colors) with JPanel and JFrame. Everything seems to be right... but no oval is draw when I execute the code. I receave just a blank screen (JFrame appears, but only blank).

It have 3 classes: MyOval, DrawPanel and DrawTest.

MyOval Class

package drawingovals;

import java.awt.Color;
import java.awt.Graphics;

public class MyOval {
private int x1;
private int y1;
private int x2;
private int y2;
private Color myColor;
private boolean isFilled;

public MyOval(int x1, int y1, int x2, int y2, Color color, boolean isFilled) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.x2 = x2;
myColor = color;
this.isFilled = isFilled;
}

public int getUpperLeftX(){
return x1;
}

public int getUpperLeftY(){
return y1;
}

public int getWidth(){
return x2 - x1;
}

public int getHeight() {
return y2 - y1;
}

public String getColor() {
return myColor.toString();
}

public boolean getFilling(){
return isFilled;
}

public void setUpperLeftX(int value) {
x1 = value;
}

public void setUpperLeftY(int value) {
y1 = value;
}

public void setDownRightX(int value) {
x2 = value;
}

public void setDownRightY(int value) {
y2 = value;
}

public void drawNoFill(Graphics g) {
g.setColor(myColor);
g.drawOval(getUpperLeftX(), getUpperLeftY(), getWidth(), getHeight());
}

public void drawFill(Graphics g) {
g.setColor(myColor);
g.fillOval(getUpperLeftX(), getUpperLeftY(), getWidth(), getHeight());
}
}


DrawPanel Class

package drawingovals;

import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JPanel;

public class DrawPanel extends JPanel{
private Random randomNumbers = new Random();
private MyOval[] ovals;

public DrawPanel() {
setBackground(Color.WHITE);

ovals = new MyOval[5 + randomNumbers.nextInt(5)];

for (int count = 0; count < ovals.length; count++) {
int x1 = randomNumbers.nextInt(300);
int y1 = randomNumbers.nextInt(300);
int x2 = randomNumbers.nextInt(300);
int y2 = randomNumbers.nextInt(300);

Color color = new Color(randomNumbers.nextInt(256),
randomNumbers.nextInt(256), randomNumbers.nextInt(256));

boolean fill = randomNumbers.nextBoolean();

ovals[count] = new MyOval(x1, y1, x2, y2, color, fill);
}
}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (int count = 0; count < ovals.length - 1; count++) {
ovals[count].drawFill(g);
}
}
}


DrawTest Class

package drawingovals;

import javax.swing.JFrame;

public class DrawTest {

public static void main(String[] args) {
DrawPanel panel = new DrawPanel();
JFrame application = new JFrame();

application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.add(panel);
application.setSize(400, 400);
application.setVisible(true);
}

}

Answer

You need to take care that your oval heights and widths contain only positive values -- your code does not do this. Consider using Math.max, Math.min, or Math.abs when obtaining your oval properties to help you achieve this.

Also, this is wrong as you're duplicating setting x2 bug ignoring y2:

    this.x1 = x1;
    this.y1 = y1;
    this.x2 = x2;  // *** these are the same
    this.x2 = x2;  // *** these are the same

Something like this would work:

public MyOval(int x1, int y1, int x2, int y2, Color color, boolean isFilled) {
    this.x1 = Math.min(x1, x2);
    this.y1 = Math.min(y1, y2);
    this.x2 = Math.max(x1, x2);
    this.y2 = Math.max(y1, y2);;
    myColor = color;
    this.isFilled = isFilled;
}

In the future, the key to solving these types of issues is to use a debugger to check the fields of your program, here the oval properties, as the program runs, and then see if they don't make sense, and then why.