Tuesday 18 February 2014

Creating a Custom Java AWT Component - Part 1: Getting Started

As part of the course I'm on, I'm creating a custom AWT component. It's a derivative of the Panel component and has a number of shapes drawn on its surface using the Graphics2D package.

Figure8

To draw the graphic, I created two methods, createSegment and createSegmentPoints. First createSegment:

private GeneralPath createSegment(int[][] points){
    GeneralPath polygon = new GeneralPath(GeneralPath.WIND_EVEN_ODD, points.length);
    polygon.moveTo(points[0][0], points[0][1]);

    for(int index = 1; index < points.length; index++) {
        polygon.lineTo(points[index][0], points[index][1]);
    }
    polygon.closePath();
    return polygon;
}

This method creates and returns a GeneralPath object, a polygon drawn (using the method lineTo) by a set of points, starting then finally completed with a call to the method closePath. The createSegmentPoints method creates an array of six points:

private int[][] createSegmentPoints(int originX, int originY, int width, int height) {
    int[][] points = new int[6][2];
    if(width >= height) {
        points[0] = new int[]{originX + height/2, originY};
        points[1] = new int[]{originX + width - height/2, originY};
        points[2] = new int[]{originX + width, originY + height/2};
        points[3] = new int[]{originX + width - height/2, originY + height};
        points[4] = new int[]{originX + height/2, originY + height};
        points[5] = new int[]{originX, originY + height/2};
    } else {
        points[0] = new int[]{originX + width/2, originY};
        points[1] = new int[]{originX + width, originY + width/2};
        points[2] = new int[]{originX + width, originY + height - width/2};
        points[3] = new int[]{originX + width/2, originY + height};
        points[4] = new int[]{originX, originY + height - width/2};
        points[5] = new int[]{originX, originY + width/2};
    }
    return points;
}

It uses the ration of height and width to determine if the segment is horizontal or vertical and then figures out the points from there.

Segment


SegmentEnd

Each segment is then rendered to the surface of the Panel in the paint method:

public void paint(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;

    int height = 20;
    int width = 100;
    GeneralPath polygon;
    //top
    polygon = createSegment(createSegmentPoints(height, 0, width, height));
    g2.setPaint(Color.red);
    g2.fill(polygon);
    ...
}


SegmentArrangements

There is a problem with flickering on resize as it repaints and this could be solved using double-buffering, which I'll write about later.

No comments:

Post a Comment