Source code for DemoPanel.java

What follows is the highlighted source code with comments. You can also download this file directly: DemoPanel.java.

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package coordinatechanges;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import javax.swing.*;

/**
 *
 * @author pat
 */
public class DemoPanel<F, I> extends JPanel implements TransformChangedListener, MouseListener, MouseMotionListener {

    TransformManager transform_manager;
    Point2D point_plot_location = null;
    Point2D square_plot_location = null;

    public DemoPanel() {

        this.setBackground(Color.BLACK);
        this.addMouseListener(this);
        this.addMouseMotionListener(this);
        setFocusable(true);
        transform_manager = new TransformManager(this, new Rectangle2D.Double(-2, -2, 4, 4));
        transform_manager.setListener(this);

    }

    @Override
    public void transformChanged() {
        repaint();
    }
    //// FUNCTIONS RELATED TO THE STATUSBAR
    private JLabel status_bar = null;

    /**
     * Set the label to print status updates to.
     */
    public void setStatusBar(JLabel new_bar) {
        status_bar = new_bar;
        // This will update the status bar with the current mode of interaction:
        setInteractionMode(current_mode);
    }

    private void postStatus(String status) {
        if (status_bar != null) {
            status_bar.setText(status);
        }
    }

    /////////////////////////// Interaction
    //// INTERACTION MODES
    public enum InteractionMode {
        // Add more modes of interaction here...

        DO_NOTHING, ZOOM_BOX, PLOT_A_POINT, PLOT_A_UNIT_SQUARE;
    }
    private InteractionMode current_mode = InteractionMode.DO_NOTHING;

    public void setInteractionMode(InteractionMode new_mode) {
        current_mode = new_mode;
        switch (current_mode) {
            case DO_NOTHING:
                postStatus("Welcome to some program with some name!");
                break;
            case ZOOM_BOX:
                postStatus("Drag your mouse to draw a rectangle to zoom to.");
                break;
            case PLOT_A_POINT:
                postStatus("Click somewhere to plot a point.");
                break;
            case PLOT_A_UNIT_SQUARE:
                postStatus("Click somewhere to plot a unit square.");
                break;
            default:
                postStatus("The programmer forgot to update setInteractionMode with a directions for the user.");
                break;
        }
        repaint();
    }

    /**
     * Change coordinates so that we show 10% more in each dimension.
     */
    public final void zoomOut() {
        transform_manager.scale(1.1);
        this.postStatus("Zoomed out by a factor of 10%.");
    }

    /**
     * Guarantee that the unit square be displayed.
     */
    public void zoomSquare() {
        transform_manager.setDisplayBox(new Rectangle2D.Double(0, 0, 1, 1));
        this.postStatus("Zoomed to the unit square with lower left vertex (0,0).");
        
    }
    ////////////////// MOUSE
    // The current location of the mouse in math coordinates.
    Point2D mouse_position_in_math_coordinates;
    // The current location of the mouse in screen coordinates.
    Point2D mouse_position_in_screen_coordinates;
    // For ZOOM_BOX mode
    boolean dragging_box = false;
    Point2D dragging_box_start = new Point2D.Double(0, 0),
            dragging_box_end = new Point2D.Double(0, 0);

    /**
     * Get the rectangle being drawn by the user when in Zoom In mode...
     */
    private Rectangle2D.Double getZoomRectangle() {
        double minx = Math.min(dragging_box_start.getX(), dragging_box_end.getX()),
                maxx = Math.max(dragging_box_start.getX(), dragging_box_end.getX()),
                miny = Math.min(dragging_box_start.getY(), dragging_box_end.getY()),
                maxy = Math.max(dragging_box_start.getY(), dragging_box_end.getY());
        return new Rectangle2D.Double(minx, miny, maxx - minx, maxy - miny);
    }

    @Override
    public void mouseClicked(MouseEvent me) {
        mouse_position_in_screen_coordinates = me.getPoint();
        mouse_position_in_math_coordinates = transform_manager.toMathCoordinates(me.getPoint());
        switch (current_mode) {
            case PLOT_A_POINT:
                this.point_plot_location = mouse_position_in_math_coordinates;
                repaint();
                break;
            case PLOT_A_UNIT_SQUARE:
                this.square_plot_location = mouse_position_in_math_coordinates;
                repaint();
                break;
        }
    }

    @Override
    public void mouseEntered(MouseEvent me) {
        mouse_position_in_screen_coordinates = me.getPoint();
        mouse_position_in_math_coordinates = transform_manager.toMathCoordinates(me.getPoint());
    }

    @Override
    public void mouseExited(MouseEvent me) {
        mouse_position_in_screen_coordinates = me.getPoint();
        mouse_position_in_math_coordinates = transform_manager.toMathCoordinates(me.getPoint());
    }

    @Override
    public void mousePressed(MouseEvent me) {
        mouse_position_in_screen_coordinates = me.getPoint();
        mouse_position_in_math_coordinates = transform_manager.toMathCoordinates(me.getPoint());
        switch (current_mode) {
            case ZOOM_BOX:
                dragging_box = true;
                dragging_box_end = dragging_box_start = mouse_position_in_math_coordinates;
                break;
        }
    }

    @Override
    public void mouseReleased(MouseEvent me) {
        mouse_position_in_screen_coordinates = me.getPoint();
        mouse_position_in_math_coordinates = transform_manager.toMathCoordinates(me.getPoint());
        switch (current_mode) {
            case ZOOM_BOX:
                if (dragging_box) {
                    dragging_box_end = mouse_position_in_math_coordinates;
                    Rectangle2D r = getZoomRectangle();
                    if ((r.getWidth() > 0) && (r.getHeight() > 0)) {
                        transform_manager.setDisplayBox(r);
                    }
                    dragging_box = false;
                }
                break;
        }
    }

    @Override
    public void mouseDragged(MouseEvent me) {
        mouse_position_in_screen_coordinates = me.getPoint();
        mouse_position_in_math_coordinates = transform_manager.toMathCoordinates(me.getPoint());
        switch (current_mode) {
            case ZOOM_BOX:
                dragging_box_end = mouse_position_in_math_coordinates;
                repaint();
                break;
        }
    }

    @Override
    public void mouseMoved(MouseEvent me) {
        mouse_position_in_screen_coordinates = me.getPoint();
        mouse_position_in_math_coordinates = transform_manager.toMathCoordinates(me.getPoint());
    }

    // DRAWING ROUTINE:
    @Override
    public void paintComponent(Graphics gfx) {
        // This stuff is standard, and should be in any paintComponent method. 
        super.paintComponent(gfx);
        Graphics2D g = (Graphics2D) gfx;
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        // This transformation will convert from math to screen coordinates.
        AffineTransform t = transform_manager.getTransform();

        // Draw lines of thickness 3.
        g.setStroke(new BasicStroke(3));

        // Draw the circle which is inscribed in the unit square.
        Ellipse2D.Double e = new Ellipse2D.Double(0, 0, 1, 1);
        g.setColor(Color.WHITE);
        g.draw(t.createTransformedShape(e));

        if (square_plot_location != null) {
            // The square_plot_location is given in math coordinates.
            Rectangle2D.Double r = new Rectangle2D.Double(
                    square_plot_location.getX(), square_plot_location.getY(), 1, 1);
            
            g.setColor(new Color(0, 0, 255, 127)); // Set color to translucent blue.
            g.fill(t.createTransformedShape(r)); // fill in the square

            g.setColor(Color.BLUE);
            g.draw(t.createTransformedShape(r)); // draw the outline of the square
        }
        if (point_plot_location != null) {
            // point_plot_location is given in math coordinates.
            
            Point2D screen_loc=transform_manager.toScreenCoordinates(point_plot_location);
            g.setColor(Color.RED);
            // This gives the circle of radius 5 centered at screen_loc:
            Ellipse2D.Double p = new Ellipse2D.Double(screen_loc.getX()-5, screen_loc.getY()-5, 10, 10);
            g.fill(p); // Fill in the circle given in screen coordinates. (No transform required.)
        }

        switch (current_mode) {
            case ZOOM_BOX:
                if (dragging_box) {
                    g.setColor(Color.ORANGE);
                    g.setStroke(new BasicStroke(2));
                    g.draw(transform_manager.getTransform().createTransformedShape(getZoomRectangle()));
                }
                break;
        }
    }
}
HOOPER >>>>> JAVA TUTORIAL
Last modified on August 17, 2018.
[check html] [check css]