Question

I'm having a frustrating problem with my app. What I want (in the provided example, that is) is 3 filled rectangles like this:

##
 #

Alas, only the top-left rectangle is drawn. Here is an sscce version of my code:

import static java.lang.System.out;
import java.awt.*;
import javax.swing.*;
import java.awt.geom.*;

public class Main {
    public static void main(String args[]) {
        Map map = new Map();

        Point[] poly1 = new Point[] { new Point(10, 10), new Point(40, 10), new Point(40, 40), new Point(10, 40) };
        Point[] poly2 = new Point[] { new Point(50, 10), new Point(80, 10), new Point(80, 40), new Point(50, 40) };
        Point[] poly3 = new Point[] { new Point(50, 50), new Point(80, 50), new Point(80, 80), new Point(50, 80) };

        Point[][] polys = new Point[][] { poly1, poly2, poly3 };

        ShowWindow(polys);
    }


    private static void ShowWindow(Point[][] polys) {
        GameWindow frame = new GameWindow(polys);
        frame.setVisible(true);
    }
}

class GameWindow extends JFrame {   
    public GameWindow(Point[][] polys) {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        MapPanel panel = new MapPanel(polys);
        Container c = getContentPane();
        c.setPreferredSize(panel.getPreferredSize());
        add(panel);
        pack();
    }
}

class MapPanel extends JPanel { 
    public MapPanel(Point[][] polys) {
        setLayout(null);
        for (Point[] poly : polys) {
            CountryPolygon boundaries = new CountryPolygon(poly);
            add(boundaries);
        }
        setBounds(0, 0, 800, 600);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(getBounds().width, getBounds().height);
    }
}

class CountryPolygon extends JComponent {
    private Path2D.Double CountryBounds;

    public CountryPolygon(Point[] points) {
        CountryBounds = GetBoundaries(points);
        setBounds(CountryBounds.getBounds());
    }

    private Path2D.Double GetBoundaries(Point[] points) {       
        Path2D.Double bounds = new Path2D.Double();
        bounds.moveTo(points[0].x, points[0].y);
        for(Point p : points) {
            if(p == points[0]) continue;
            bounds.lineTo(p.x, p.y);
        }
        bounds.closePath();

        return bounds;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g.create();
        g2.setColor(new Color(175, 100, 175));
        g2.fill(CountryBounds);
        g2.dispose();
    }

}

My real code is not quite like this, but the problem is very much the same. You may be wondering why I'm not using a layout manager. Well, I'm trying to create a RISK-like game, so I'm having lots of irregular shapes that must all be in the correct place.

I'm quite new to Java, and I couldn't find a single similar problem by googling.

Thanks for your help!

Was it helpful?

Solution

You custom painting is done in the CountryPolygon class. Since you are using a null layout the default size of these components is (0, 0), so the painting of your polygons is done outside the bounds of the class and there is nothing to see.

You need to set the size of each of these components.

Not sure, but maybe you can use the approach found in Custom Painting Approaches. The DrawOnComponent example keeps an ArrayList of Rectangles to draw. In your case you can change this to use to hold Shape objects and then use the fillShape(...) method of Graphics2D to do the painting.

Edit:

The width/height of (30, 30) would still be wrong

Point[] poly2 = new Point[] { new Point(50, 10), new Point(80, 10), new Point(80, 40), new Point(50, 40) };

You are using points like (80, 10) which is well outside the (30, 30) size. You really need to make the size of each component the size of the parent panel.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top