Scientific Programming II

ModSim

Graphics using AWT and Swing


So far, we've been extending from JApplet to use AWT and Swing. Doing that sets up most of the GUI for us, like the window to display and basic layout settings. However, if we instead build our AWT/Swing applications slightly differently, we can take more control over the design of the application.

This example, and the next few, will start moving away from applets and back into traditional desktop GUI development. Our classes will generally inherit instead from JPanel, and we will include a main method to run our programs.

This first example will draw rectangles that the user drags out with the mouse. Instead of inheriting from JApplet, we inherit from JPanel and develop a custom GUI component.

package edu.govschool;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * This program will allow the user to drag out a rectangle and draw it to the
 * screen.
 * @author Mr. Davis
 */
public class RectMaker extends JPanel
{
    // We need to store the coordinates of where we clicked and where we
    // released the mouse
    private static int xDown, yDown, xUp, yUp;
    // Constant for window size
    private static final int SIZE = 700;
    
    // We'll be using instances of the class itself in-place of a JPanel, since
    // it extends from JPanel!
    public RectMaker()
    {
        // We need to only listen for mousePressed and mouseReleased, so we can
        // use an anonymous instance of MouseAdapter() to pick and choose the
        // methods to implement
        addMouseListener(
            new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) 
                {
                    // Coordinates for where we clicked
                    xDown = e.getX();
                    yDown = e.getY();
                }
                
                @Override
                public void mouseReleased(MouseEvent e)
                {
                    // Coordinates for where we released
                    xUp = e.getX();
                    yUp = e.getY();
                    // Calls paintComponent(Graphics) instead of paint(Graphics)
                    repaint();
                }
            }
        );
        
        // As you might expect, there is a MouseMotionAdapter to do the same
        // thing for MouseMotionEvents
        addMouseMotionListener(
            new MouseMotionAdapter() {
                @Override
                public void mouseDragged(MouseEvent e)
                {
                    // By copying the same code from the mouseReleased method,
                    // the rectangle will be continuously drawn as we drag it
                    // out
                    xUp = e.getX();
                    yUp = e.getY();
                    repaint();
                }
            }
        );
    }
    
    // Since we inherit from JPanel (a component) and not JApplet, we use the
    // method paintComponent(Graphics) instead of just paint(Graphics)
    @Override
    public void paintComponent(Graphics g)
    {
        int width = Math.abs(xUp - xDown);
        int height = Math.abs(yUp - yDown);
        int xTop = Math.min(xUp, xDown);
        int yTop = Math.min(yUp, yDown);
        g.setColor(Color.RED);
        g.fillRect(xTop, yTop, width, height);
    }
    
    public static void main(String[] args)
    {
        // The JFrame is analogous to the JavaFX Stage, it is the window
        // displayed
        JFrame frame = new JFrame("RectMaker");
        RectMaker rm = new RectMaker();
        // Add our custom JPanel to the window
        frame.add(rm);
        // Sets the size of the window
        frame.setSize(SIZE, SIZE);
        // Show the window
        frame.setVisible(true);
        // Prevent the user from resizing the window
        frame.setResizable(false);
        // Exit the JVM on close (necessary on OS X)
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
}