com.greglturnquist.jlogo.TurtleGraphicsWindow.java Source code

Java tutorial

Introduction

Here is the source code for com.greglturnquist.jlogo.TurtleGraphicsWindow.java

Source

package com.greglturnquist.jlogo;

import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.Optional;

import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

/**
 * Wrapper class which provides the TurtleGraphics support from the TG Logo programmng
 * environment to the world of programming in Java.
 *
 * @author Guy Haas
 * @author Greg Turnquist
 */
public class TurtleGraphicsWindow extends Frame implements TGKeyHandler, TGMouseHandler, WindowListener {

    //
    // Symbolic Constants
    // -------- ---------

    /**
     * Default height of the graphics canvas.
     */
    public final static int DEFAULT_CANVAS_HEIGHT = 600;

    /**
     * Default width of the graphics canvas.
     */
    public final static int DEFAULT_CANVAS_WIDTH = 600;

    /*
     * The following colors numbers, font numbers, headings, and turtle shape numbers have
     * been copied from Sprite and TGCanvas so that classes extending TurtleGraphicsWindow
     * do not have to prefix them with their class names. Think of this as scaffolding for
     * beginners.
     */

    /**
     * The setpencolor method's input is a built-in color number or an RGB value. Built-in
     * colors numbers are in the range of 0-31.
     */
    public static final int BLACK = 0;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int BLUE = 1;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int GREEN = 2;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int CYAN = 3;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int RED = 4;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int MAGENTA = 5;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int YELLOW = 6;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int WHITE = 7;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int BROWN = 8;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int TAN = 9;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int FOREST = 10;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int AQUA = 11;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int SALMON = 12;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int VIOLET = 13;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int ORANGE = 14;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int GRAY = 15;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int NAVY = 16;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int SKYBLUE = 17;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int LIME = 18;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int STEELBLUE = 19;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int CHOCOLATE = 20;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int PURPLE = 21;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int GOLD = 22;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int LIGHTGRAY = 23;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int PERU = 24;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int WHEAT = 25;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int PALEGREEN = 26;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int LIGHTBLUE = 27;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int KHAKI = 28;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int PINK = 29;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int LAWNGREEN = 30;

    /**
     * Symbolic constant for input to setpencolor().
     */
    public static final int OLIVE = 31;

    /**
     * The maximum value for a built-in color which require conversion to RGB colors used
     * by Java.
     */
    public static final int MAX_LOGO_COLOR = 31;

    /*
     * The turtle can draw Strings of characters onto the graphics canvas in a few
     * different fonts and styles. The setlabelfont() method has an integer parameter that
     * represents a font and style combination. Following are symbolic constants for the
     * available fonts and styles.
     */

    /**
     * Symbolic constant for setlabelfont() to select a fixed-width Courier font.
     * @see #setlabelfont
     */
    public static final int COURIER = 0;

    /**
     * Symbolic constant for setlabelfont() to select an emboldened fixed-width Courier
     * font.
     * @see #setlabelfont
     */
    public static final int COURIER_BOLD = 1;

    /**
     * Symbolic constant for setlabelfont() to select an italicized fixed-width Courier
     * font.
     * @see #setlabelfont
     */
    public static final int COURIER_ITALIC = 2;

    /**
     * Symbolic constant for setlabelfont() to select an emboldened and italicized
     * fixed-width Courier font.
     * @see #setlabelfont
     */
    public static final int COURIER_BOLD_ITALIC = 3;

    /**
     * Symbolic constant for setlabelfont() to select the Sans Serif font.
     * @see #setlabelfont
     */
    public static final int SANS_SERIF = 4;

    /**
     * Symbolic constant for setlabelfont() to select an emboldened Sans Serif font.
     * @see #setlabelfont
     */
    public static final int SANS_SERIF_BOLD = 5;

    /**
     * Symbolic constant for setlabelfont() to select an italicized Sans Serif font.
     * @see #setlabelfont
     */
    public static final int SANS_SERIF_ITALIC = 6;

    /**
     * Symbolic constant for setlabelfont() to select an emboldened and italicized Sans
     * Serif font.
     * @see #setlabelfont
     */
    public static final int SANS_SERIF_BOLD_ITALIC = 7;

    /**
     * Symbolic constant for setlabelfont() to select the Serif font.
     * @see #setlabelfont
     */
    public static final int SERIF = 0;

    /**
     * Symbolic constant for setlabelfont() to select an emboldened Serif font.
     * @see #setlabelfont
     */
    public static final int SERIF_BOLD = 1;

    /**
     * Symbolic constant for setlabelfont() to select an italicized Serif font.
     * @see #setlabelfont
     */
    public static final int SERIF_ITALIC = 2;

    /**
     * Symbolic constant for setlabelfont() to select an emboldened and italicized Serif
     * font.
     * @see #setlabelfont
     */
    public static final int SERIF_BOLD_ITALIC = 3;

    /**
     * Turtle heading for the positive Y axis.
     *
     * The Logo turtle's heading in degrees does not match the standard mathematics notion
     * of having the positive X axis as zero, with degrees increasing counter-clockwise.
     * Logo has the positive Y axis as zero with degrees increasing clockwise. The use of
     * abstract symbolic constants for north, east, south, and west help.
     * @see #seth
     * @see #setheading
     */
    public static final int NORTH = 0;

    /**
     * Turtle heading for the positive X axis.
     *
     * The Logo turtle's heading in degrees does not match the standard mathematics notion
     * of having the positive X axis as zero, with degrees increasing counter-clockwise.
     * Logo has the positive Y axis as zero with degrees increasing clockwise. The use of
     * abstract symbolic constants for north, east, south, and west help.
     * @see #seth
     * @see #setheading
     */
    public static final int EAST = 90;

    /**
     * Turtle heading for the negative Y axis.
     *
     * The Logo turtle's heading in degrees does not match the standard mathematics notion
     * of having the positive X axis as zero, with degrees increasing counter-clockwise.
     * Logo has the positive Y axis as zero with degrees increasing clockwise. The use of
     * abstract symbolic constants for north, east, south, and west help.
     * @see #seth
     * @see #setheading
     */
    public static final int SOUTH = 180;

    /**
     * Turtle heading for the negative X axis.
     *
     * The Logo turtle's heading in degrees does not match the standard mathematics notion
     * of having the positive X axis as zero, with degrees increasing counter-clockwise.
     * Logo has the positive Y axis as zero with degrees increasing clockwise. The use of
     * abstract symbolic constants for north, east, south, and west help.
     * @see #seth
     * @see #setheading
     */
    public static final int WEST = 270;

    /*
     * The following turtle shape symbolic constants have been copied from Sprite so that
     * classes extending TurtleGraphicsWindow do not have to prefix them with class name.
     */

    /**
     * jLogo comes with a few basic shapes (images) that the turtle may take on. Each is
     * assigned a fixed shape number. The initial shape roughly looks like a turtle
     * (come-on... think artististic license). This default turtle image is shape number
     * 0.
     */
    public static final int TURTLE = 0;

    /**
     * jLogo comes with a few basic shapes (images) that the turtle may take on. Each is
     * assigned a fixed shape number. An image which resembles an arrow is shape number 1.
     */
    public static final int ARROW = 1;

    /**
     * jLogo comes with a few basic shapes (images) that the turtle may take on. Each is
     * assigned a fixed shape number. An image which is a filled circle, a ball, is shape
     * number 2.
     */
    public static final int BALL = 2;

    /**
     * jLogo comes with a few basic shapes (images) that the turtle may take on. Each is
     * assigned a fixed shape number. An image which is a filled rectangle, a box, is
     * shape number 3.
     */
    public static final int BOX = 3;

    /**
     * jLogo comes with a few basic shapes (images) that the turtle may take on. Each is
     * assigned a fixed shape number. An image which resembles a filled plus-sign, a
     * cross, is shape number 4.
     */
    public static final int CROSS = 4;

    /**
     * jLogo comes with a few basic shapes (images) that the turtle may take on. Each is
     * assigned a fixed shape number. An image which is a filled triangle is shape number
     * 5.
     */
    public static final int TRIANGLE = 5;

    /**
     * jLogo comes with a few basic shapes (images) that the turtle may take on. Each is
     * assigned a fixed shape number. An image which is a filled diamond is shape number
     * 6.
     */
    public static final int DIAMOND = 6;

    /*
     * Lines the turtle draws can have caps (decorations) on their ends. The following
     * symbolic constants are mapped to similarly named counterparts from
     * java.awt.BasicStroke.
     */

    /**
     * Symbolic constant for setLinecap() which selects a basic line with no endcap.
     */
    public static final int LINECAP_BUTT = 0;

    /**
     * Symbolic constant for setLinecap() to which selects a rounded endcap. This is the
     * default.
     */
    public static final int LINECAP_ROUND = 1;

    /**
     * Symbolic constant for setLinecap() to which selects a squared-off endcap.
     */
    public static final int LINECAP_SQUARE = 2;

    /*
     * Provide a range of indicies for the users to add their own images for the turtle.
     */

    /**
     * The minimum shape number that users can assign an image of their own to.
     */
    public static final int FIRST_USER_SUPPLIED_SHAPE = 32;

    /**
     * The number of shape numbers reserved for users to assign their own images to.
     */
    public static final int NUM_USER_SUPPLIED_SHAPES = 96;

    /**
     * The maximum shape number that users can assign an image of their own to.
     */
    public static final int LAST_USER_SUPPLIED_SHAPE = FIRST_USER_SUPPLIED_SHAPE + (NUM_USER_SUPPLIED_SHAPES - 1);

    //
    // Variables with class-wide visibility (scope)
    // --------- ---- ---------- ---------- -------

    /*
     * Position of the mouse when it was last clicked.
     */
    private int mouseX, mouseY;

    /*
     * Component where drawing takes place.
     */
    private TGCanvas canvas;

    /*
     * Object that does the drawing.
     */
    private Sprite turtle;

    /*
     * Array of SpritePixels objects, images/shapes that Sprites can take on supplied by a
     * Logo program, see loadshape().
     */
    private static SpritePixels[] userSuppliedImages;

    static {
        userSuppliedImages = new SpritePixels[NUM_USER_SUPPLIED_SHAPES];
    }

    DefaultResourceLoader loader;

    //
    // Constructors
    // ------------

    /**
     * Create and return an AWT Frame which contains a turtle graphics canvas. It comes
     * with a full set of methods (actually wrappers for Sprite methods) for performing
     * Logo-like turtle graphics stuff. It has a default size of symbolic constants
     * DEFAULT_CANVAS_HEIGHT and DEFAULT_CANVAS_WIDTH.
     */
    public TurtleGraphicsWindow() {
        this(DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT);
        this.loader = new DefaultResourceLoader();
    }

    /**
     * Create and return an AWT Frame which contains a turtle graphics Canvas. It comes
     * with a full set of methods (actually wrappers for Sprite methods) for performing
     * Logo-like turtle graphics stuff. Its size is provided as parameters.
     */
    public TurtleGraphicsWindow(int width, int height) {
        addWindowListener(this);
        setTitle("TurtleGraphicsWindow");
        canvas = new TGCanvas(width, height);
        canvas.setBackground(Color.white);
        canvas.addKeyHandler(this);
        canvas.addMouseHandler(this);
        this.add("Center", canvas);
        Insets insets = getInsets();
        width += insets.left + insets.right;
        height += insets.top + insets.bottom;
        setPreferredSize(new Dimension(width, height));
        pack();
        setVisible(true);
        canvas.requestFocusInWindow();
        turtle = new Sprite(canvas);
    }

    //
    // TGKeyHandler Interface Methods
    // ------------ --------- -------

    /**
     * TurtleGraphicsWindow implements the TGKeyHandler interface and registers with
     * TGCanvas to receive keyboard key events.
     * <p>
     * Override this method to do something when a key on the keyboard is pressed while
     * the graphics canvas is active, has focus.
     * @param keyNum key identifier - either a character or an action key code (e.g.,
     * arrow keys)
     * @see TGKeyHandler#ALT
     * @see TGKeyHandler#CONTROL
     * @see TGKeyHandler#DOWN_ARROW
     * @see TGKeyHandler#LEFT_ARROW
     * @see TGKeyHandler#RIGHT_ARROW
     * @see TGKeyHandler#SHIFT
     * @see TGKeyHandler#UP_ARROW
     */
    public void tgKeyPressed(int keyNum) {
        keypressed(keyNum);
    }

    /**
     * TurtleGraphicsWindow implements the TGKeyHandler interface and registers with
     * TGCanvas to receive keyboard key events.
     * <p>
     * Override this method to do something when a key which generates a character is
     * pressed and released while the graphics canvas is active, has focus.
     * @param keyNum key identifier - either a character or an action key code (e.g.,
     * arrow keys)
     * @see TGKeyHandler#ALT
     * @see TGKeyHandler#CONTROL
     * @see TGKeyHandler#DOWN_ARROW
     * @see TGKeyHandler#LEFT_ARROW
     * @see TGKeyHandler#RIGHT_ARROW
     * @see TGKeyHandler#SHIFT
     * @see TGKeyHandler#UP_ARROW
     */
    public void tgKeyReleased(int keyNum) {
    };

    /**
     * TurtleGraphicsWindow implements the TGKeyHandler interface and registers with
     * TGCanvas to receive keyboard key events.
     * <p>
     * Override this method to do something when a key on the keyboard is released while
     * the graphics canvas is active, has focus.
     * @param keyChar a character generated by a keyboard key
     */
    public void tgKeyTyped(char keyChar) {
    };

    //
    // TGMouseHandler Interface Methods
    // -------------- --------- -------

    /**
     * TurtleGraphicsWindow implements the TGMouseHandler interface and registers with
     * TGCanvas to receive mouse events.
     * <p>
     * Override this method to do something when the left mouse button is clicked in the
     * graphics canvas while it is active, has focus.
     *
     * @param x the X-coordinate where mouse was clicked
     * @param y the Y-coordinate where mouse was clicked
     *
     * @see #mousex
     * @see #mousey
     * @see #tgMouseMoved
     */
    public void tgMouseClicked(int x, int y) {
    };

    /**
     * TurtleGraphicsWindow implements the TGMouseHandler interface and registers with
     * TGCanvas to receive mouse events.
     * <p>
     * Override this method to do something when the mouse is moved within the graphics
     * canvas while it is active, has focus.
     *
     * @param x the X-coordinate where mouse was clicked.
     * @param y the Y-coordinate where mouse was clicked.
     *
     * @see #mousex
     * @see #mousey
     * @see #tgMouseClicked
     */
    public void tgMouseMoved(int x, int y) {
    };

    //
    // WindowListener Interface Methods
    // -------------- --------- -------

    public void windowActivated(WindowEvent we) {
    }

    public void windowClosed(WindowEvent we) {
    }

    public void windowClosing(WindowEvent we) {
        System.exit(0);
    }

    public void windowDeactivated(WindowEvent we) {
    }

    public void windowDeiconified(WindowEvent we) {
    }

    public void windowIconified(WindowEvent we) {
    }

    public void windowOpened(WindowEvent we) {
    }

    /*
     * TurtleGraphics Methods
     *
     * Provided to allow the class extending TurtleGraphicsWindow to invoke them without
     * being forced to obtain and use the Sprite object to reference/invoke them.
     */

    /**
     * Draws an arc of a circle, with the turtle at the center, with the specified radius,
     * starting at the turtle's heading and extending clockwise through the specified
     * angle. The turtle is not moved.
     *
     * @param angle clockwise rotation from current heading (in degrees)
     * @param radius distance from center of the turtle to the drawn arc, to the center of
     * the arc line if the pen width is greater than 1.
     */
    public void arc(double angle, double radius) throws IllegalArgumentException {
        if (angle == 0 || radius == 0)
            return;
        if (radius <= 0)
            throw new IllegalArgumentException("Illegal radius: " + radius);
        turtle.arc(angle, radius);
    }

    /**
     * Draws an arc of a circle, with the turtle at the center, with the specified radius,
     * starting at the turtle's heading and extending clockwise through the specified
     * angle. The turtle is not moved.
     *
     * @param angle clockwise rotation from current heading (in degrees)
     * @param radius distance from center of the turtle to the drawn arc, to the center of
     * the arc line if the pen width is greater than 1.
     */
    public void arc(int angle, int radius) throws IllegalArgumentException {
        arc((double) angle, (double) radius);
    }

    /**
     * Move the turtle backwards along its current heading. If the pen is currently in the
     * DOWN position, a line is drawn.
     *
     * Long name for bk(). Both spellings need to provided for compatibility.
     *
     * @param steps number of turtle steps to move
     * @see #bk
     */
    public void back(double steps) {
        try {
            turtle.bk(steps);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Move the turtle backwards along its current heading. If the pen is currently in the
     * DOWN position, a line is drawn.
     *
     * Long name for bk(). Both spellings need to provided for compatibility.
     *
     * @param steps number of turtle steps to move
     * @see #bk
     */
    public void back(int steps) {
        try {
            turtle.bk(steps);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Move the turtle backwards along its current heading. If the pen is currently in the
     * DOWN position, a line is drawn.
     *
     * Long name for bk(). Both spellings need to provided for compatibility.
     *
     * @param steps number of turtle steps to move
     * @see #bk
     */
    public void bk(double steps) {
        try {
            turtle.bk(steps);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Move the turtle backwards along its current heading. If the pen is currently in the
     * DOWN position, a line is drawn.
     *
     * Abbreviation for back(). Both spellings need to provided for compatibility.
     *
     * @param steps Number of turtle steps to move
     * @see #back
     */
    public void bk(int steps) {
        try {
            turtle.bk(steps);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Clear the graphics canvas area of the TurtleGraphicsWindow.
     *
     * Note: Clean does not change the current position of the turtle, its heading, the
     * size of the pen it is drawing with and/or the color of the pen it is drawing with.
     */
    public void clean() {
        canvas.clean();
    }

    /**
     * Return an array of the unique colors this turtle's image is positioned over.
     * <p>
     * @see #pencolor
     * @see #setbg
     * @see #setpc
     * @see #setpencolor
     */
    public int[] colorsunder() {
        return turtle.colorsunder();
    }

    /**
     * Return the color under the center of the turtle's image.
     *
     * @see #pencolor
     * @see #setpc
     * @see #setpencolor
     */
    public int colorunder() {
        return turtle.colorunder();
    }

    /**
     * Fill a bounded area in the graphics canvas.
     *
     * The current pixel, and any of its neighbors that are the same color as it (and any
     * of their neighbors that are the same color as it, etc...) are changed to the
     * current color.
     */
    public void fill() {
        turtle.fill();
    }

    /**
     * Move the turtle forward along its current heading. If the pen is currently in the
     * DOWN position, a line is drawn.
     *
     * Abbreviation for forward(). Both spellings need to be provided for compatibility.
     *
     * @param steps Number of turtle steps to take.
     * @see #forward
     */
    public void fd(double steps) {
        try {
            turtle.fd(steps);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Move the turtle forward along its current heading. If the pen is currently in the
     * DOWN position, a line is drawn.
     *
     * Abbreviation for forward(). Both spellings need to be provided for compatibility.
     *
     * @param steps Number of turtle steps to take.
     * @see #forward
     */
    public void fd(int steps) {
        try {
            turtle.fd(steps);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Move the turtle forward along its current heading. If the pen is currently in the
     * DOWN position, a line is drawn.
     *
     * Long name for fd(). Both spellings need to provided for compatibility.
     *
     * @param steps number of turtle steps to move in current direction
     * @see #fd
     */
    public void forward(double steps) {
        try {
            turtle.fd(steps);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Move the turtle forward along its current heading. If the pen is currently in the
     * DOWN position, a line is drawn.
     *
     * Long name for fd(). Both spellings need to provided for compatibility.
     *
     * @param steps number of turtle steps to move in current direction
     * @see #fd
     */
    public void forward(int steps) {
        try {
            turtle.fd(steps);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Return the width of the provided String, when rendered in the current font, in
     * turtle steps (pixels).
     *
     * @param label text to be measured
     * @see #label
     * @see #setlabelfont
     * @see #setlabelheight
     */
    public int labelwidth(String label) {
        return turtle.getLabelWidth(label);
    }

    /**
     * Return the turtle's heading in Logo (turtle space) degrees.
     *
     * @see #seth
     * @see #setheading
     */
    public double heading() {
        return (turtle.heading());
    }

    /**
     * Hide the turtle; make it invisible.
     *
     * Long name for ht(). Both spellings need to provided for compatibility.
     *
     * @see #ht
     * @see #showturtle
     * @see #st
     */
    public void hideturtle() {
        turtle.ht();
    }

    /**
     * Move the turtle to the center of the display. If the pen is in the DOWN position, a
     * line is drawn.
     *
     * Home is equivilent to setxy( 0, 0 )
     *
     * @see #setxy
     */
    public void home() {
        try {
            turtle.home();
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Hide the turtle; make it invisible.
     *
     * Abbreviation for hideturtle(). Both spellings need to provided for compatibility.
     *
     * @see #hideturtle
     * @see #showturtle
     * @see #st
     */
    public void ht() {
        turtle.ht();
    }

    /**
     * Return the current status of the pen.
     *
     * Return true if the turtle's pen is down or false if it in the up position.
     *
     * @see #pendown
     * @see #penup
     * @see #pd
     * @see #pu
     */
    public boolean ispendown() {
        return (turtle.ispendown());
    }

    /**
     * Empty method declaration which child programs override to process keyboard key
     * events.
     *
     * @param keyNum Character on the keyboard that was pressed while the graphics canvas
     * has its focus.
     *
     * @deprecated
     * @see #tgKeyPressed
     * @see #tgKeyReleased
     * @see #tgKeyTyped
     */
    public void keypressed(int keyNum) {
    }

    /**
     * Draws a String of characters on the graphics canvas. The text is drawn in the
     * current pen's color, starting at the current position of the turtle.
     *
     * The text is always drawn in the standard horizontal manner, i.e., the heading of
     * the turtle is ignored.
     *
     * @param text characters to be drawn on the graphics canvas
     *
     * @see #labelwidth
     * @see #setlabelfont
     * @see #setlabelheight
     */
    public void label(String text) {
        turtle.label(text);
    }

    /**
     * Rotate the turtle counterclockwise by the specified angle, measured in degrees.
     *
     * @param degrees angle to rotate the turtle's heading
     * @see #lt
     */
    public void left(double degrees) {
        try {
            turtle.lt(degrees);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Rotate the turtle counterclockwise by the specified angle, measured in degrees.
     *
     * @param degrees angle to rotate the turtle's heading
     * @see #lt
     */
    public void left(int degrees) {
        try {
            turtle.lt(degrees);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Draw a picture from a file onto the background of the graphics canvas. Returns true
     * if successful, otherwise false.
     *
     * @param fileName String that identifies the source image file
     * @see #clean
     */
    public boolean loadpicture(String fileName) {
        Resource pictureResource = filenameToResource(loader, fileName);

        return Optional.ofNullable(TGFileIO.getImage(pictureResource)).map(pictureImage -> {
            canvas.loadPicture(pictureImage);
            return true;
        }).orElse(false);
    }

    public static Resource filenameToResource(ResourceLoader loader, String filename) {

        return Optional.of(filename.startsWith("classpath:")).map(o -> loader.getResource(filename))
                .orElse(loader.getResource("classpath:" + filename));
    }

    /**
     * Load an image file; it can then be used for a turtle's shape, its image. Returns
     * true if successful, otherwise false.
     *
     * @param fileName String that identifies the source image file
     * @param shapeNum an integer that is between FIRST_USER_SUPPLIED_SHAPE and
     * LAST_USER_SUPPLIED_SHAPE, inclusive This number can then be used with setshape() to
     * change the turtle's appearance
     * @see #setshape
     */
    public boolean loadshape(String fileName, int shapeNum) {
        PixelRectangle pixRect = TGFileIO.getPixRect(filenameToResource(loader, fileName));
        if (pixRect == null)
            return false;
        int shapeIdx = shapeNum - FIRST_USER_SUPPLIED_SHAPE;
        if (shapeNum < 0 || shapeNum > NUM_USER_SUPPLIED_SHAPES)
            return false;
        userSuppliedImages[shapeIdx] = new UserTurtle(pixRect);
        return true;
    }

    /**
     * Rotate the turtle counterclockwise by the specified angle, measured in degrees.
     *
     * Abbreviation for left(). Both spellings need to provided for compatibility.
     *
     * @param degrees Angle to change turtle's heading by.
     * @see #left
     */
    public void lt(double degrees) {
        try {
            turtle.lt(degrees);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Rotate the turtle counterclockwise by the specified angle, measured in degrees.
     *
     * Abbreviation for left(). Both spellings need to provided for compatibility.
     *
     * @param degrees Angle to change turtle's heading by.
     * @see #left
     */
    public void lt(int degrees) {
        try {
            turtle.lt(degrees);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Return the x-coordinate where the mouse was last moved or clicked within the
     * graphics canvas.
     *
     * @see #mousey
     * @see #tgMouseClicked
     * @see #tgMouseMoved
     */
    public int mousex() {
        return (canvas.mousex());
    }

    /**
     * Return the Y-coordinate where the mouse was last moved or clicked within the
     * graphics canvas.
     *
     * @see #mousex
     * @see #tgMouseClicked
     * @see #tgMouseMoved
     */
    public int mousey() {
        return (canvas.mousey());
    }

    /**
     * Lower the turtle's pen into the down position.
     *
     * When the turtle moves, it will leave a trace from its current position to its
     * destination (its new position).
     * @see #ispendown
     * @see #pendown
     * @see #pu
     * @see #penup
     */
    public void pd() {
        turtle.pd();
    }

    /**
     * Return the color the pen is currently drawing in.
     * <P>
     * @see #setpc
     * @see #setpencolor
     */
    public int pencolor() {
        return turtle.pencolor();
    }

    /**
     * Lower the turtle's pen into the down position.
     *
     * When the turtle moves, it will leave a trace from its current position to its
     * destination (its new position).
     * @see #ispendown
     * @see #pd
     * @see #penup
     * @see #pu
     */
    public void pendown() {
        turtle.pd();
    }

    /**
     * Lift the turtle's pen into the up position.
     *
     * When the turtle moves, it will leave no trace.
     * @see #ispendown
     * @see #pd
     * @see #pendown
     * @see #pu
     */
    public void penup() {
        turtle.pu();
    }

    /**
     * Return the current position of this turtle.
     *
     * @return TGPoint a virtual point, a point in TurtleSpace. In TurtleSpace, 0.0,0.0 is
     * at the center of the graphics canvas.
     */
    public TGPoint pos() {
        return turtle.pos();
    }

    /**
     * Lift the turtle's pen into the up position.
     *
     * When the turtle moves, it will leave no trace.
     * @see #ispendown
     * @see #pd
     * @see #pendown
     * @see #penup
     */
    public void pu() {
        turtle.pu();
    }

    /**
     * Rotate the turtle clockwise by the specified angle, measured in degrees.
     *
     * @param degrees angle to rotate the turtle's heading
     * @see #rt
     */
    public void right(double degrees) {
        try {
            turtle.rt(degrees);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Rotate the turtle clockwise by the specified angle, measured in degrees.
     *
     * @param degrees angle to rotate the turtle's heading
     * @see #rt
     */
    public void right(int degrees) {
        try {
            turtle.rt(degrees);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Rotate the turtle clockwise by the specified angle, measured in degrees.
     *
     * Abbreviation for right(). Both spellings need to provided for compatibility.
     *
     * @param degrees angle to rotate the turtle's heading
     * @see #right
     */
    public void rt(double degrees) {
        try {
            turtle.rt(degrees);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Rotate the turtle clockwise by the specified angle, measured in degrees.
     *
     * Abbreviation for right(). Both spellings need to provided for compatibility.
     *
     * @param degrees angle to rotate the turtle's heading
     * @see #right
     */
    public void rt(int degrees) {
        try {
            turtle.rt(degrees);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Set the background color of the graphics canvas.
     * <p>
     * *NOTE* a side-effect of changing the background color is that all current graphics
     * is cleared.
     * <p>
     * 
     * <pre>
     * Number Color        Number Color        Number Color
     * ------ ----------   ------ ----------   ------ ---------
     *    0   black          11   aqua           22   gold
     *    1   blue           12   salmon         23   lightgray
     *    2   green          13   purple         24   peru
     *    3   cyan           14   orange         25   wheat
     *    4   red            15   grey           26   palegreen
     *    5   magenta        16   navy           27   lightblue
     *    6   yellow         17   skyblue        28   khaki
     *    7   white          18   lime           29   pink
     *    8   brown          19   steelblue      30   lawngreen
     *    9   light brown    20   chocolate      31   olive
     *   10   forest         21   purple
     * </pre>
     * <p>
     * Color numbers greater than 31 will be treated as RGB values. Assuming bits are
     * numbered 0-31, left to right, the red component is in bits 8-15, the green
     * component in bits 16-23, and the blue component in bits 24-31. The actual color
     * used in rendering will depend on finding the best match given the color space
     * available for a given display.
     * @see #clean
     * @see #loadpicture
     * @see #setpencolor
     * @see #BLACK
     * @see #BLUE
     * @see #AQUA
     * @see #BROWN
     * @see #CHOCOLATE
     * @see #CYAN
     * @see #GOLD
     * @see #FOREST
     * @see #GRAY
     * @see #GREEN
     * @see #KHAKI
     * @see #LAWNGREEN
     * @see #LIGHTBLUE
     * @see #LIGHTGRAY
     * @see #LIME
     * @see #MAGENTA
     * @see #NAVY
     * @see #OLIVE
     * @see #ORANGE
     * @see #PALEGREEN
     * @see #PERU
     * @see #PINK
     * @see #PURPLE
     * @see #RED
     * @see #SALMON
     * @see #SKYBLUE
     * @see #STEELBLUE
     * @see #TAN
     * @see #VIOLET
     * @see #WHEAT
     * @see #WHITE
     * @see #YELLOW
     */
    public void setbg(int logoColor) {
        canvas.setbg(logoColor);
    }

    /**
     * Turns the turtle to the specified absolute heading. The heading is specified in
     * degrees (units of 1/360th of a circle) with 0 being North (+Y axis), increasing
     * clockwise. So, East is 90 degrees, South is 180 degrees, and West is 270 degrees.
     *
     * Abbreviation for setheading(). Both spellings need to provided for compatibility.
     *
     * @param degrees number of 1/360ths increments clockwise from the positive Y axis
     * @see #setheading
     */
    public void seth(double degrees) {
        try {
            turtle.seth(degrees);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Turns the turtle to the specified absolute heading. The heading is specified in
     * degrees (units of 1/360th of a circle) with 0 being North (+Y axis), increasing
     * clockwise. So, East is 90 degrees, South is 180 degrees, and West is 270 degrees.
     *
     * Abbreviation for setheading(). Both spellings need to provided for compatibility.
     *
     * @param degrees number of 1/360ths increments clockwise from the positive Y axis
     * @see #setheading
     */
    public void seth(int degrees) {
        try {
            turtle.seth(degrees);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Turns the turtle to the specified absolute heading. The heading is specified in
     * degrees (units of 1/360th of a circle) with 0 being North (+Y axis), increasing
     * clockwise. So, East is 90 degrees, South is 180 degrees, and West is 270 degrees.
     *
     * @param degrees number of 1/360ths increments clockwise from the positive Y axis
     * @see #seth
     */
    public void setheading(double degrees) {
        try {
            turtle.seth(degrees);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Turns the turtle to the specified absolute heading. The heading is specified in
     * degrees (units of 1/360th of a circle) with 0 being North (+Y axis), increasing
     * clockwise. So, East is 90 degrees, South is 180 degrees, and West is 270 degrees.
     *
     * @param degrees number of 1/360ths increments clockwise from the positive Y axis
     * @see #seth
     */
    public void setheading(int degrees) {
        try {
            turtle.seth(degrees);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Set the font for LABELs, text drawn on the graphics canvas by the turtle.
     *
     * @param fontNumber an integer representing a font face and font style
     * <p>
     * 
     * <pre>
     * Number   Font         Style
     * ------   ----------   -----------
     *    0     Courier      Plain
     *    1     Courier      Bold
     *    2     Courier      Italic
     *    3     Courier      Bold Italic
     *    4     Sans Serif   Plain
     *    5     Sans Serif   Bold
     *    6     Sans Serif   Italic
     *    7     Sans Serif   Bold Italic
     *    8     Serif        Plain
     *    9     Serif        Bold
     *   10     Serif        Italic
     *   11     Serif        Bold Italic
     * </pre>
     * 
     * @see #label
     * @see #labelwidth
     * @see #setlabelheight
     * @see #COURIER
     * @see #COURIER_BOLD
     * @see #COURIER_ITALIC
     * @see #COURIER_BOLD_ITALIC
     * @see #SANS_SERIF
     * @see #SANS_SERIF_BOLD
     * @see #SANS_SERIF_ITALIC
     * @see #SANS_SERIF_BOLD_ITALIC
     * @see #SERIF
     * @see #SERIF_BOLD
     * @see #SERIF_ITALIC
     * @see #SERIF_BOLD_ITALIC
     */
    public void setlabelfont(int fontNumber) throws IllegalArgumentException {
        if (fontNumber < 0 || fontNumber >= Sprite.NUM_FONTS)
            throw new IllegalArgumentException("Illegal font number: " + fontNumber);
        turtle.setlabelfont(fontNumber);
    }

    /**
     * Set the height of the text drawn on the graphics canvas with the label() method.
     *
     * @param size approximate number of pixels tall the uppercase characters should be
     * (in the current font/style)
     * @see #label
     * @see #setlabelfont
     * @see #labelwidth
     */
    public void setlabelheight(int size) throws IllegalArgumentException {
        if (size < 1 || size > Sprite.MAX_LABEL_ASCENT)
            throw new IllegalArgumentException("Illegal label height: " + size);
        turtle.setlabelheight(size);
    }

    /**
     * Set the type of linecaps applied to the ends of lines drawn.
     *
     * Linecap Description --------------
     * ---------------------------------------------------- LINECAP_BUTT - lines start/end
     * where turtle starts and stops. This is the default linecap. LINECAP_ROUND - line
     * ends are rounded with a semicircle extending a half pensize before/after turtle
     * starts and stops. LINECAP_SQUARE - line ends are extended a half pensize
     * before/after turtle starts and stops.
     *
     * @param typeLinecap an integer representing the desired linecap.
     *
     */
    public void setlinecap(int typeLinecap) throws IllegalArgumentException {
        switch (typeLinecap) {
        case LINECAP_BUTT:
        case LINECAP_ROUND:
        case LINECAP_SQUARE:
            turtle.setLinecap(typeLinecap);
            break;
        default:
            throw new IllegalArgumentException("Illegal linecap type: " + typeLinecap);
        }
    }

    /**
     * Sets the color of the turtle's pen to the supplied number.
     * @param colorNum either a built-in Logo color number in the range 0-31, else a
     * 24-bit RGB color value
     * <p>
     * 
     * <pre>
     * Number Color        Number Color        Number Color
     * ------ ----------   ------ ----------   ------ ---------
     *    0   black          11   aqua           22   gold
     *    1   blue           12   salmon         23   lightgray
     *    2   green          13   purple         24   peru
     *    3   cyan           14   orange         25   wheat
     *    4   red            15   grey           26   palegreen
     *    5   magenta        16   navy           27   lightblue
     *    6   yellow         17   skyblue        28   khaki
     *    7   white          18   lime           29   pink
     *    8   brown          19   steelblue      30   lawngreen
     *    9   light brown    20   chocolate      31   olive
     *   10   forest         21   purple
     * </pre>
     * <p>
     * Color numbers greater than 31 will be treated as RGB values. Assuming bits are
     * numbered 0-31, left to right, the red component is in bits 8-15, the green
     * component in bits 16-23, and the blue component in bits 24-31. The actual color
     * used in rendering will depend on finding the best match given the color space
     * available for a given display.
     * @see #setbg
     * @see #setpencolor
     * @see #BLACK
     * @see #BLUE
     * @see #AQUA
     * @see #BROWN
     * @see #CHOCOLATE
     * @see #CYAN
     * @see #GOLD
     * @see #FOREST
     * @see #GRAY
     * @see #GREEN
     * @see #KHAKI
     * @see #LAWNGREEN
     * @see #LIGHTBLUE
     * @see #LIGHTGRAY
     * @see #LIME
     * @see #MAGENTA
     * @see #NAVY
     * @see #OLIVE
     * @see #ORANGE
     * @see #PALEGREEN
     * @see #PERU
     * @see #PINK
     * @see #PURPLE
     * @see #RED
     * @see #SALMON
     * @see #SKYBLUE
     * @see #STEELBLUE
     * @see #TAN
     * @see #VIOLET
     * @see #WHEAT
     * @see #WHITE
     * @see #YELLOW
     */
    public void setpc(int colorNum) {
        turtle.setpc(colorNum);
    }

    /**
     * Sets the color of the turtle's pen to the supplied number.
     *
     * @param colorNum either a built-in Logo color number in the range 0-31, else a
     * 24-bit RGB color value
     * <p>
     * 
     * <pre>
     * Number Color        Number Color        Number Color
     * ------ ----------   ------ ----------   ------ ---------
     *    0   black          11   aqua           22   gold
     *    1   blue           12   salmon         23   lightgray
     *    2   green          13   purple         24   peru
     *    3   cyan           14   orange         25   wheat
     *    4   red            15   grey           26   palegreen
     *    5   magenta        16   navy           27   lightblue
     *    6   yellow         17   skyblue        28   khaki
     *    7   white          18   lime           29   pink
     *    8   brown          19   steelblue      30   lawngreen
     *    9   light brown    20   chocolate      31   olive
     *   10   forest         21   purple
     * </pre>
     * <p>
     * Color numbers greater than 31 will be treated as RGB values. Assuming bits are
     * numbered 0-31, left to right, the red component is in bits 8-15, the green
     * component in bits 16-23, and the blue component in bits 24-31. The actual color
     * used in rendering will depend on finding the best match given the color space
     * available for a given display.
     * @see #setbg
     * @see #setpc
     * @see #BLACK
     * @see #BLUE
     * @see #AQUA
     * @see #BROWN
     * @see #CHOCOLATE
     * @see #CYAN
     * @see #GOLD
     * @see #FOREST
     * @see #GRAY
     * @see #GREEN
     * @see #KHAKI
     * @see #LAWNGREEN
     * @see #LIGHTBLUE
     * @see #LIGHTGRAY
     * @see #LIME
     * @see #MAGENTA
     * @see #NAVY
     * @see #OLIVE
     * @see #ORANGE
     * @see #PALEGREEN
     * @see #PERU
     * @see #PINK
     * @see #PURPLE
     * @see #RED
     * @see #SALMON
     * @see #SKYBLUE
     * @see #STEELBLUE
     * @see #TAN
     * @see #VIOLET
     * @see #WHEAT
     * @see #WHITE
     * @see #YELLOW
     */
    public void setpencolor(int colorNum) {
        turtle.setpc(colorNum);
    }

    /**
     * Set the pattern used to draw lines. A pattern consists of lengths of down and up
     * pen states when drawing lines. If segmentSize is zero, solid lines are drawn.
     * Otherwise, it is used as the distance draw followed by the distance to skip over.
     *
     * @param segmentSize draw/skip amount.
     *
     * @see #back
     * @see #bk
     * @see #fd
     * @see #forward
     * @see #home
     * @see #setx
     * @see #setxy
     * @see #sety
     */
    public void setpenpattern(int segmentSize) throws IllegalArgumentException {
        if (segmentSize < 0)
            throw new IllegalArgumentException("Illegal segment size: " + segmentSize);
        else if (segmentSize == 0)
            turtle.setpenpattern(null);
        else
            turtle.setpenpattern(new int[] { segmentSize, segmentSize });
    }

    /**
     * Set the pattern used to draw lines. A pattern consists of lengths of down and up
     * pen states when drawing lines. If the pattern is null or empty, solid lines are
     * drawn. Otherwise, the array's even elements are distances to draw and the odd
     * elements are distances to skip over.
     *
     * @param pattern array of draw/skip amounts. If pattern has an odd number of
     * elements, the last draw amount is duplicated for the skip amount, producing a
     * pattern one element longer.
     */
    public void setpenpattern(int[] pattern) throws IllegalArgumentException {
        if (pattern == null || pattern.length == 0) {
            turtle.setpenpattern(null);
            return;
        }
        for (int idx = 0; idx < pattern.length; idx++)
            if (pattern[idx] < 1)
                throw new IllegalArgumentException("Illegal segment size: " + pattern[idx]);
        turtle.setpenpattern(pattern);
    }

    /**
     * Sets the width of the turtle's pen to the supplied number.
     *
     * @param width small positive number; 1 (or less) results in a single pixel line.
     * greater numbers result in line widths equal to width pixels.
     */
    public void setpensize(int width) {
        turtle.setpensize(width);
    }

    /**
     * Move the turtle to an absolute display position, to the x and y coordinates in the
     * TGPoint parameter.
     *
     * @param pos a TGPoint object containing the X-coordinate and Y-coordinate of
     * destination
     * @see #home
     * @see #setx
     * @see #setxy
     * @see #sety
     */
    public void setpos(TGPoint pos) {
        setxy(pos);
    }

    /**
     * Sets the shape of the turtle - its pixel image. Returns true if shape successfully
     * set, else false failure.
     *
     * @param shapeNum small positive number for either a built-in shape (see constants
     * (e.g., BALL, BOX, etc...) or a user-supplied image via loadShape() method
     *
     * <pre>
     * Number  Shape
     * ------  --------
     *    0    Turtle
     *    1    Arrow
     *    2    Ball
     *    3    Box
     *    4    Cross
     *    5    Triangle
     *    6    Diamond
     * </pre>
     *
     * @see #loadshape
     * @see #stamp
     * @see #ARROW
     * @see #BALL
     * @see #BOX
     * @see #CROSS
     * @see #DIAMOND
     * @see #TRIANGLE
     * @see #TURTLE
     * </pre>
     */
    public boolean setshape(int shapeNum) {
        return setshape(shapeNum, null);
    }

    /**
     * Sets the shape of the turtle - its pixel image. Returns true if shape successfully
     * set, else false for failure.
     * <p>
     * @param shapeNum small positive number; 0 for default turtle image; see constants
     * (e.g., BALL, BOX, etc...) for other turtle shapes
     * @param params an optional int array containing sizing information hints, e.g.
     * radius of a ball, width and height of a box, etc...
     * <p>
     * 
     * <pre>
     * Number  Shape      Optional Size Parameters
     * ------  --------   ------------------------
     *    0    Turtle
     *    1    Arrow      width, height
     *    2    Ball       diameter
     *    3    Box        width, height
     *    4    Cross      width, height
     *    5    Triangle   width, height
     *    6    Diamond    width, height
     * </pre>
     * 
     * @see #loadshape
     * @see #stamp
     * @see #ARROW
     * @see #BALL
     * @see #BOX
     * @see #CROSS
     * @see #DIAMOND
     * @see #TRIANGLE
     * @see #TURTLE
     */
    public boolean setshape(int shapeNum, int[] params) {
        if (shapeNum >= FIRST_USER_SUPPLIED_SHAPE && shapeNum <= LAST_USER_SUPPLIED_SHAPE) {
            if (userSuppliedImages[shapeNum - FIRST_USER_SUPPLIED_SHAPE] == null)
                return false;
            turtle.setshape(userSuppliedImages[shapeNum - FIRST_USER_SUPPLIED_SHAPE]);
            return true;
        } else
            return turtle.setshape(shapeNum, params);
    }

    /**
     * Sets the shape of the turtle - its pixel image.
     * <p>
     * @param newSpritePixels
     * <p>
     * @see #loadshape
     */
    public void setshape(SpritePixels newSpritePixels) {
        turtle.setshape(newSpritePixels);
    }

    /**
     * Move the turtle to an absolute display position.
     *
     * Move the turtle horizontally to a new location specified as an X coordinate
     * argument.
     * @param newX the X-coordinate of destination
     * @see #home
     * @see #setxy
     * @see #sety
     */
    public void setx(double newX) {
        try {
            turtle.setx(newX);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Move the turtle to an absolute display position.
     *
     * Move the turtle horizontally to a new location specified as an X coordinate
     * argument.
     * @param newX the X-coordinate of destination
     * @see #home
     * @see #setxy
     * @see #sety
     */
    public void setx(int newX) {
        try {
            turtle.setx(newX);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Move the turtle to an absolute display position.
     *
     * Move the turtle to the x and y coordinates provided as arguments.
     * @param newX the X-coordinate of destination
     * @param newY the Y-coordinate of destination
     * @see #home
     * @see #setx
     * @see #sety
     */
    public void setxy(double newX, double newY) {
        try {
            turtle.setxy(newX, newY);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Move the turtle to an absolute display position.
     *
     * Move the turtle to the x and y coordinates provided as arguments.
     * @param newX the X-coordinate of destination
     * @param newY the Y-coordinate of destination
     * @see #home
     * @see #setx
     * @see #sety
     */
    public void setxy(int newX, int newY) {
        try {
            turtle.setxy(newX, newY);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Move the turtle to an absolute display position.
     *
     * Move the turtle to the x and y coordinates provided in the TGPoint parameter.
     * @param newPt a TGPoint objext containing the X-coordinate and Y-coordinate of
     * destination
     * @see #home
     * @see #setx
     * @see #sety
     */
    public void setxy(TGPoint newPt) {
        try {
            turtle.setxy(newPt);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Move the turtle to an absolute display position.
     *
     * Move the turtle vertically to a new location specified as an Y coordinate argument.
     * @param newY the Y-coordinate of destination
     * @see #home
     * @see #setx
     * @see #setxy
     */
    public void sety(double newY) {
        try {
            turtle.sety(newY);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Move the turtle to an absolute display position.
     *
     * Move the turtle vertically to a new location specified as an Y coordinate argument.
     * @param newY the Y-coordinate of destination
     * @see #home
     * @see #setx
     * @see #setxy
     */
    public void sety(int newY) {
        try {
            turtle.sety(newY);
        } catch (AbortException ae) {
            /* ignore */ }
    }

    /**
     * Return the height of the image of the turtle, as it appears for its current
     * heading.
     *
     * @see #setshape(int)
     * @see #setshape(int, int[])
     */
    public int shapeheight() {
        return turtle.getSpritePixels().getHeight();
    }

    /**
     * Return the width of the image of the turtle, as it appears for its current heading.
     *
     * @see #setshape(int)
     * @see #setshape(int, int[])
     */
    public int shapewidth() {
        return turtle.getSpritePixels().getWidth();
    }

    /**
     * Return true if this turtle's image is being displayed on the graphics canvas, else
     * return false.
     * <p>
     * @see #hideturtle
     * @see #ht
     * @see #showturtle
     * @see #st
     */
    public boolean shownp() {
        return turtle.shownp();
    }

    /**
     * Show the turtle; make it visible.
     *
     * Long name for st(). Both spellings need to provided for compatibility.
     *
     * @see #hideturtle
     * @see #ht
     * @see #st
     */
    public void showturtle() {
        turtle.st();
    }

    /**
     * Show the turtle; make it visible.
     *
     * Abbreviation for showturtle(). Both spellings need to provided for compatibility.
     *
     * @see #hideturtle
     * @see #ht
     * @see #showturtle
     */
    public void st() {
        turtle.st();
    }

    /**
     * Draw the turtle's image onto the graphics canvas.
     *
     * @see #setshape(int)
     * @see #setshape(int, int[])
     */
    public void stamp() {
        turtle.stamp();
    }

    /**
     * Set the amount of time (milliseconds) that drawing is suspended each time a method
     * which visibly changes the turtle's state is performed. To aid debugging and/or
     * optimizing a grapical program it can be helpful to artificially slow down the
     * drawing. When throttleSleepAmt is greater than zero, concerned methods suspend the
     * current Thread for it's amount.
     *
     * @param amt - milliseconds to pause after the visible state of the turtle changes.
     * When less than or equal to zero, pausing is turned off.
     */
    public void throttle(int amt) {
        turtle.setThrottleSleepAmt(amt);
    }

    /**
     * Return the turtle's X-coordinate
     * @see #setxy
     * @see #setx
     * @see #sety
     * @see #ycor
     */
    public int xcor() {
        return ((int) turtle.xcor());
    }

    /**
     * Return the turtle's Y-coordinate
     * @see #setxy
     * @see #setx
     * @see #sety
     * @see #xcor
     */
    public int ycor() {
        return ((int) turtle.ycor());
    }

} // end class TurtleGraphicsWindow