I'm trying to replicate the ray-looking design, just like in the first image.

Here's my code:

When the user clicks on the button:

private class drawInnerShape implements ActionListener{
        public void actionPerformed( ActionEvent e){
            paintInnerDesign = true;
            repaint();
        }
    }

The following code executes:

class DrawArtwork extends JPanel {
        @Override
        public void paintComponent(Graphics g) 
        {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            if(paintInnerDesign)
            {
                Color nextColor = new Color(255, 216, 0);
                int arcEnd = 2;
                for(int i = 0; i <= 89; i++)
                {
                    g2d.setColor(nextColor);
                    g2d.fillArc((int) ((canvasWidth / 4) + 35), (int) (canvasHeight / 12) + 100, (int)(canvasHeight * .75), (int)(canvasHeight * .75), arcStart, arcEnd);

                    g2d.setColor(Color.BLACK);
                    g2d.fillArc((int) ((canvasWidth / 4) + 35), (int) (canvasHeight / 12) + 100, (int)(canvasHeight * .75), (int)(canvasHeight * .75), arcEnd, arcEnd + 2);
                    arcStart = arcStart + 4;
                    arcEnd = arcEnd + 4;
                }
        }
    }
}

However, I'm getting the results in image two. And if I change i value from 89 to 79, I get the results in image three.

I can't figure out why it won't paint the object just like in the first image.

Dani AI

Generated

Short practical fix for , with a few cleanup tips tied to and ’s points.

The behaviour you saw comes from using a changing value as the arc extent and from letting the start angle/state persist between paints. Make the wedge width a fixed value and step the start angle by that fixed amount each iteration. Reset the start angle inside paintComponent so every repaint begins the same way. A simple, clear pattern:

int left  = canvasWidth/4 + 35;
int top   = canvasHeight/12 + 100;
int size  = (int)(canvasHeight * 0.75);
final int wedge = 4; // degrees per segment

g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

g2d.setColor(Color.BLACK);
g2d.fillOval(left, top, size, size);

for (int start = 0; start < 360; start += wedge) {
    if (((start / wedge) & 1) == 0) {            // alternate color
        g2d.setColor(new Color(255,216,0));
        g2d.fillArc(left, top, size, size, start, wedge);
    }
}

Extra tips and traps to avoid

  • Compute left/top/size once outside the loop for clarity and a tiny speed win.
  • Make the start-angle variable local to paintComponent; don’t increment a field that survives repaints.
  • Use antialiasing for smoother edges.
  • If the wedges should be straight rays (not curved), draw triangular polygons from the circle center instead of arcs.
  • If this artwork is static, render it once to a BufferedImage and draw the image in paintComponent to avoid recomputing on every repaint.

If results still look wrong, log the start and wedge values during drawing to confirm you’re stepping by the intended degree and that 360 % wedge == 0 (or handle the remainder explicitly).

Recommended Answers

All 5 Replies

The last parameter for fillArc is the size of the arc in degrees, not the angle at which it finishes. So it should always be 2 or 4 (sorry, don't have the time to work out which)

rproffitt, forgot to include arcStart, but it's initialized at 0. Here's the link to the code paly ground: https://goo.gl/m0a3tZ

JamesCherrill, I know that the size is in degrees. I'm iterating through, and for degrees 0 to 2, the arc is filled with gold, from 2 to 4, its black, and so on until 356 degrees.

I'm looking at line 14 where the last argument is arcEnd (also line 17) which should be 2 but is actually increasing by 4 on each pass of the loop.
It looks like you think the last two parameters are the starting and ending angle for the arc, but they are not. To quote the api doc "The resulting arc begins at startAngle and extends for arcAngle degrees".
Your last parameter should be 2, and you do not need endArc at all.

commented: That makes sense. I must've overlooked the fact that the second parameter is the degrees to which it needs to draw for. Thank you so much. Now it work +3

OK!

A couple of small suggestions:

you could start by drawing a single complete black circle, then you only need to do the gold arcs in the loop. Depending on the application context, drawing 90 separate black arcs could be a performance hit.

If you compute int left,top,width,height once at the start then the code will be much easier to read, and possibly more efficient than having all those calculations repeated inside the loop.

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.