Title: Drawing Sizing
Course: CPS 261: Advanced Java Concepts ~ DL & MM MASTER

Drawing Sizing

The Forida.java example below is a better example of good artwork.

Florida.java


import java.awt.Graphics;
import java.awt.Polygon;
import javax.swing.*;


public class Florida extends JFrame {

	public Florida (String name)
	{
        super(name);
        setSize(600,400);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

	}
    public void paint(Graphics screen) {
        super.paint(screen);



        // Draw the Florida text with a line under it and
        // surrounded by a rounded rectangle

        screen.drawString("Florida", 185, 75);
        screen.drawLine(185,80,222,80);
        screen.drawRoundRect(182,61,43,24,10,8);

        // Draw Florida Boundary
        int x[] = { 10, 234, 253, 261, 344, 336, 295, 259, 205, 211,
            195, 191, 120, 94, 81, 12, 10 };
        int y[] = { 12, 15, 25, 71, 209, 278, 310, 274, 188, 171, 174,
            118, 56, 68, 49, 37, 12 };
        int pts = x.length;
        Polygon poly = new Polygon(x, y, pts);
        screen.drawPolygon(poly);

        // Mickey Mouse
        screen.fillOval(235,140,15,15);
        screen.fillOval(225,130,15,15);
        screen.fillOval(245,130,15,15);

        // Draw the Waves
        for (int ax = 50; ax < 150; ax += 10)
            for (int ay = 120; ay < 320 ; ay += 10)
                screen.drawArc(ax, ay, 10, 10, 0, -180);
    }

    public static void main(String[] args)
    {
    	Florida florida = new Florida("My Florida map");
    }
}


Note that the Florida drawing was done without taking the border into account.

The Insets class can tell you how big the border is. For example, we can write the following code to know about the border:


    Insets insets = getInsets();
    int top = insets.top;
    int bottom = insets.bottom;
    int left = insets.left;
    int right = insets.right;


Update Florida.java to adjust the Polygon by the "top" and "left" amounts.

Resizing

1. Using the Florida app, add a print statement inside paint, which paints the number of times it has been called.
2. Do a minimize and bring the app back.
3. Pull on the lower right and resize and note that paint gets called a lot
4. Note that if you don't intend to make your application resizable, you can add the statement in your JFrame constructor
setResizable(false); // the default is true
5. To find the current size of the screen, you can do one of 2 things:


  //Approach 1:
  int width = getWidth();
  int height = getHeight();

  //Approach 2
  Dimension d = getSize();
  int width=d.width;
  int height = d.height;


6. Screen Calculations: Create a simple Program(screen starts out as 600, 600) that displays a Filled Rectangle that has a width of 300 and a height of 200.
  - Display the Rectangle centered on the screen
  - Display the Rectangle(unscaled) in the corners of the screen.
  - Display the Rectangle centered, but Scale it bigger or smaller as the window is resized. In otherwords, the Rectangle's size scales linearly with the window size.
RectanglePlacement.java


package scaling;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;

import javax.swing.JFrame;

public class RectanglePlacement extends JFrame {

    RectanglePlacement(String name)
    {
        super(name);
        setSize(600,600);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

    }
    public void paint(Graphics g) {
        super.paint(g);

        Dimension d = getSize();
        Insets insets = getInsets();
        int top = insets.top;
        int bottom = insets.bottom;
        int left = insets.left;
        int right = insets.right;

        int w=300;
        int h = 200;
        int x_center = left + (d.width - left -right)/2;
        int y_center = top + (d.height -top - bottom)/2;

        //Center Rectangle
        g.setColor(Color.red);
        g.drawRect(x_center -w/2, y_center - h/2, w, h);

        //Lower Right
        g.setColor(Color.green);
        g.drawRect(d.width-right-w -1, d.height-bottom-h-1, w, h);

        //Upper Left
        g.setColor(Color.green);
        g.drawRect(left, top, w, h);
    }
    public static void main(String[] args)
    {
        RectanglePlacement s = new RectanglePlacement("Rectangle Placement");
    }
}


RectangleScaling.java


package scaling;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;

import javax.swing.JFrame;

public class RectangleScaling extends JFrame {

    static final int WIDTH_STARTING=600;
    static final int HEIGHT_STARTING=600;

    RectangleScaling(String name)
    {
        super(name);
        setSize(WIDTH_STARTING,HEIGHT_STARTING);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

    }
    public void paint(Graphics g) {
        super.paint(g);

        Dimension dimen = getSize();
        Insets insets = getInsets();
        int top = insets.top;
        int bottom = insets.bottom;
        int left = insets.left;
        int right = insets.right;

        int w=300;
        int h = 200;
        int x_center = left + (dimen.width - left -right)/2;
        int y_center = top + (dimen.height -top - bottom)/2;

        //Center Rectangle
        g.setColor(Color.red);
        g.drawRect(x_center -w/2, y_center - h/2, w, h);

        double scale_w = dimen.width/(double)WIDTH_STARTING;
        double scale_h = dimen.height/(double)HEIGHT_STARTING;
        int w_new = (int)(w * scale_w);
        int h_new = (int)(h * scale_h);

        //Scaled Centered Rectangle (NOT maintaining aspect ratio)
        g.setColor(Color.green);
        g.drawRect(x_center -w_new/2, y_center - h_new/2, w_new, h_new);


        //Scaled Centered Rectangle (Maintaining aspect ratio)
        double scale = Math.min(scale_w, scale_h);

        w_new = (int)(w * scale);
        h_new = (int)(h * scale);
        g.setColor(Color.blue);
        g.drawRect(x_center -w_new/2, y_center - h_new/2, w_new, h_new);
    }
    public static void main(String[] args)
    {
        RectangleScaling s = new RectangleScaling("Rectangle Scaling");
    }
}


7. Take the Florida Application, and remove everything except for the Polygon of Florida. Write code that Expands Florida to perfectly fit inside the viewable window scaled to fill the whole screen.


package scaling;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Polygon;

import javax.swing.JFrame;


public class Florida extends JFrame {

    public Florida (String name)
    {
        super(name);
        setSize(600,400);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

    }
    int max(int[] x)
    {
        int maxVal=-1;
        for (int i=0; i < x.length; i++)
        {
            if (x[i] > maxVal)
                maxVal = x[i];
        }
        return maxVal;
    }
    public void paint(Graphics screen) {
        super.paint(screen);
        Dimension d = getSize();
        System.out.println(" Dimension=" + d);

        Insets insets = getInsets();
        int top = insets.top;
        int bottom = insets.bottom;
        int left = insets.left;
        int right = insets.right;


        // Draw Florida Boundary
        int x[] = { 10, 234, 253, 261, 344, 336, 295, 259, 205, 211,
            195, 191, 120, 94, 81, 12, 10 };
        int y[] = { 12, 15, 25, 71, 209, 278, 310, 274, 188, 171, 174,
            118, 56, 68, 49, 37, 12 };

        int xMax = max(x);
        int yMax = max(y);
        double xScale = (d.width-left-right) / (double)xMax;
        double yScale = (d.height-top-bottom)/ (double)yMax;
        double scale = Math.min(xScale, yScale); // In order to maintain the aspect ratio

        for (int i=0; i < x.length; i++)
        {
            x[i] = left + (int)(scale * x[i]);
            y[i] = top + (int)(scale * y[i]);
        }

        int pts = x.length;
        Polygon poly = new Polygon(x, y, pts);
        screen.drawPolygon(poly);


    }

    public static void main(String[] args)
    {
        Florida florida = new Florida("My Florida map");
    }
}



Font Work

In a previous set of notes, we mentioned you can create your own Font with something like:


Font font = new Font(Font.SERIF, Font.BOLD, 36);
g.setFont(font);
g.drawString("Are you Going?", 100, 200);


How to work with positioning strings:

1. The point 100, 200 represents the point on the "green line" just to the left of the first character in the string
2. To find out the basic parameters for this text, check out the followng code:


  Font font = getFont();
  FontMetrics fm = getFontMetrics(font);
  int height = fm.getHeight();
  int maxAscent = fm.getMaxAscent();
  int strWidth = fm.stringWidth("Are you Going?");


3. Using these parameters, see if you can center the text in the center of the screen.
4. See if you can center the text at the top of the screen.
5. See if you can perfectly place the text in the lower right corner
6. See if you can perfectly place the text in the upper left corner.


package scaling;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;

import javax.swing.JFrame;

public class TextScaling extends JFrame {

    static final int WIDTH_STARTING=600;
    static final int HEIGHT_STARTING=600;

    TextScaling(String name)
    {
        super(name);
        setSize(WIDTH_STARTING,HEIGHT_STARTING);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

    }
    public void paint(Graphics g) {
        super.paint(g);

        Dimension dimen = getSize();
        Insets insets = getInsets();
        int top = insets.top;
        int bottom = insets.bottom;
        int left = insets.left;
        int right = insets.right;

        Font font = new Font("SansSerif", Font.BOLD, 72);
        g.setFont(font);
        String text = "Are you going?";

        FontMetrics fm = getFontMetrics(font);
        int fontHeight = fm.getHeight();
        int maxAscent = fm.getMaxAscent();
        int strWidth = fm.stringWidth(text);

        int x_center = left + (dimen.width - left -right)/2;
        int y_center = top + (dimen.height -top - bottom)/2;

        // Center Text
        g.drawString(text, x_center - strWidth/2, y_center - fontHeight/2 + maxAscent);
        g.drawRect(x_center - strWidth/2, y_center- fontHeight/2, strWidth, fontHeight);

        // Changing Font
        font = new  Font("SansSerif", Font.BOLD, 12);
        g.setFont(font);

        fm = getFontMetrics(font);
        fontHeight = fm.getHeight();
        maxAscent = fm.getMaxAscent();
        strWidth = fm.stringWidth(text);

        //Upper Left Corner
        g.drawString(text, left, top+ maxAscent);

        //Upper Right Corner
        g.drawString(text, dimen.width - right - strWidth, top+ maxAscent);

        //Lower Left Corner
        g.drawString(text, left, dimen.height - bottom - fontHeight + maxAscent);


        //Lower Right Corner
        g.drawString(text, dimen.width - right - strWidth, dimen.height - bottom - fontHeight + maxAscent);


    }
    public static void main(String[] args)
    {
        TextScaling s = new TextScaling("Text Scaling");
    }
}


Exercises

The following is the beginning of a program that you could write to do bar Graphs:


package scaling;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.util.ArrayList;

import javax.swing.JFrame;

class GBar
{
    String text;
    int value;
    GBar(String t, int v)
    {
        text=t;
        value =v;
    }
}

public class GraphBeginnings extends JFrame{

    ArrayList<GBar> gbarArr = new ArrayList<GBar>();

    GraphBeginnings(ArrayList<GBar> garr)
    {
        super("Graph Beginnings");

        gbarArr = garr;
        setSize(600,600);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    // Find the maximum width of the strings in pixels
    int getMaxTextWidth(ArrayList<GBar> garr, FontMetrics fm)
    {
        int maxValue=0;
        for (int i=0; i < garr.size(); i++)
        {
            int width = fm.stringWidth(garr.get(i).text);
            if (width > maxValue)
                maxValue = width;
        }
        return maxValue;
    }

    // Find the maximum value in the ArrayList
    int getMaxBarWidth(ArrayList<GBar> garr)
    {
        int maxValue=0;
        for (int i=0; i < garr.size(); i++)
        {
            int value = garr.get(i).value;
            if (value > maxValue)
                maxValue = value;
        }
        return maxValue;
    }
    public void paint(Graphics g)
    {
        super.paint(g);
        Dimension dimen = getSize();
        Insets insets = getInsets();
        int top = insets.top;
        int left = insets.left;
        int right = insets.right;

        Font font = g.getFont();
        FontMetrics fm = getFontMetrics(font);
        int fontHeight = fm.getHeight();
        int maxAscent = fm.getMaxAscent();

        int strMaxWidth = left + getMaxTextWidth( gbarArr, fm);
        int x_bar_start =  strMaxWidth +1/* a little white space pad*/;

        int barMaxValue = getMaxBarWidth(gbarArr);
        double scale = (dimen.width -x_bar_start - right) / (double) barMaxValue;

        int y_start = top;

        int bar_height = fontHeight;

        for (int i=0; i < gbarArr.size(); i++)
        {
            String text = gbarArr.get(i).text;
            int strWidth = fm.stringWidth(text);
            int value =gbarArr.get(i).value;
            int scaledValue = (int)(value * scale);
            g.drawString(text, strMaxWidth - strWidth, y_start + maxAscent);
            g.fillRect(x_bar_start, y_start, scaledValue, bar_height);

            y_start += fontHeight + 10/*  a little space between rows */;
        }
        g.drawLine(strMaxWidth, top, strMaxWidth, dimen.height);
    }

    public static void main(String[] args) {
        ArrayList<GBar> garr = new ArrayList<GBar>();
        garr.add(new GBar("Bubba", 320));
        garr.add(new GBar("Adrian Petersen", 235));
        garr.add(new GBar("Sproules",165));
        garr.add(new GBar("RG3",212));

        GraphBeginnings gb= new GraphBeginnings(garr);

    }

}



Last Updated: July 22, 2014 8:22 PM