1

I am working on a project and I have to display the graphic of a function and zoom in on the graphic. Zoom in entirely or simply have a rectangle and in that rectangle have only the selected part zoomed in. Thing is, I have no clue how to do that and I am requesting some guidance from your side, SO.

This is my code, how can I zoom in on the graphic?

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;

class SimpleJava2DExample extends Frame {
    private static final long serialVersionUID = 1L;
    double XRmin, XRmax, YRmin, YRmax;
    int XEmin, XEmax, YEmin, YEmax;
    double Sx, Sy;
    int Nsteps;
    String textMessage;
    double deltaY = 0.3;

    // Constructor
    SimpleJava2DExample() {
        textMessage = "";
        XEmin = YEmin = 10;
        Nsteps = 100;
        XRmin = -Math.PI / 2.;
        XRmax = 3 * Math.PI / 2.;// XRmax = 7*Math.PI;
        // Calculates YRmin, YRmax
        YRmin = F(XRmin);
        YRmax = F(XRmax);
        double xr, yr;
        for (int i = 0; i < Nsteps; i++) {
            xr = XRmin + (XRmax - XRmin) * i / Nsteps;
            yr = F(xr);
            if (yr < YRmin)
                YRmin = yr;
            if (yr > YRmax)
                YRmax = yr;
        }
        YRmax += deltaY;
        // Enables the closing of the window.
        WindowListener listener = new WindowAdapter() {
            // Override
            public void windowClosing(WindowEvent w) {
                System.exit(0);
            }
        };
        addWindowListener(listener);
        // Mouse click event
        MouseListener mouselistener = new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                int ex = (int) e.getPoint().getX();
                int ey = (int) e.getPoint().getY();
                textMessage = "(x, y) : (" + Xreal(ex) + ", " + Yreal(ey) + ")";
                repaint();
            }
        };
        addMouseListener(mouselistener);
        // Enables the resize of the window.
        addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent arg0) {
                repaint();
            }
        });
    }

    // The function to be plotted
    double F(double x) {
        return (double) ((Math.sin(x) + 0.5 * Math.sin(3 * x)) * Math.exp(-1.0
                * x));
    }

    // Conversions between user (real) space and device space
    // Conversion Xreal --> Xdevice
    int Xpix(double xr) {
        return XEmin + (int) ((xr - XRmin) * Sx);
    }

    // Conversion Yreal --> Ydevice
    int Ypix(double yr) {
        return YEmax - (int) ((yr - YRmin) * Sy);
    }

    // Conversion Xdevice --> Xreal
    double Xreal(double xe) {
        return XRmin + (xe - XEmin) / Sx;
    }

    // Conversion Ydevice --> Yreal
    double Yreal(double ye) {
        return YRmin + (YEmax - ye) / Sy;
    }

    // This function plots the axes of the graph
    void drawAxes(Graphics2D g2d) {
        g2d.setColor(Color.black);
        g2d.drawLine(Xpix(XRmin), Ypix(0.0), Xpix(XRmax), Ypix(0.0));
        g2d.drawLine(Xpix(0.0), Ypix(YRmin), Xpix(0.0), Ypix(YRmax));
        int fontsize = this.getFont().getSize();
        g2d.drawString("0", Xpix(0.0) - fontsize, Ypix(0.0) + fontsize);
        g2d.drawString("" + XRmax, Xpix(XRmax) - 8 * fontsize, Ypix(0.0)
                - fontsize);
        g2d.drawString("" + XRmin, Xpix(XRmin), Ypix(0.0) - fontsize);
        g2d.drawString("" + YRmax, Xpix(0.0) + fontsize, Ypix(YRmax) + 4
                * fontsize);
        g2d.drawString("" + YRmin, Xpix(0.0) + fontsize, Ypix(YRmin) - fontsize);
    }

    public void paint(Graphics g) {
        super.paint(g);
        // In order to use Java 2D, it is necessary to cast the Graphics object
        // into a Graphics2D object.

        Graphics2D g2d = (Graphics2D) g;
        // The current size of the window
        XEmax = this.getWidth() - 50;
        YEmax = this.getHeight() - 50;
        // Calculates the scale factors
        Sx = (XEmax - XEmin) / (XRmax - XRmin);
        Sy = (YEmax - YEmin) / (YRmax - YRmin);
        // Draw the axes
        drawAxes(g2d);
        // Draw the graph
        g2d.setColor(Color.red);
        double xr, yr;
        Point2D lastPoint = new Point2D.Double(Xpix(XRmin), Ypix(YRmin));
        for (int i = 1; i < Nsteps; i++) {
            xr = XRmin + (XRmax - XRmin) * i / Nsteps;
            yr = F(xr);
            Point2D currentPoint = new Point2D.Double(Xpix(xr), Ypix(yr));
            g2d.draw(new Line2D.Double(lastPoint, currentPoint));
            lastPoint = currentPoint;
        }
        g2d.setColor(Color.blue);
        int fontsize = this.getFont().getSize();
        g2d.drawString(textMessage, 2 * fontsize, this.getHeight() - 2
                * fontsize);
        textMessage = "";
    }
}

public class MainJava2D {

    public static void main(String[] args) {
        //Generate the window.
        SimpleJava2DExample f = new SimpleJava2DExample();
        //Define a title for the window.
        String s = new String("The first Java 2D graph of a univariate function");
        f.setTitle(s);
        //Definition of the window size in pixels
        f.setSize(500, 400);
        //Show the window on the screen.
        f.setVisible(true);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
MrSilent
  • 564
  • 10
  • 28
  • 1
    Why use AWT? See [this answer](http://stackoverflow.com/questions/6255106/java-gui-listeners-without-awt/6255978#6255978) for many good reasons to abandon AWT using components in favor of Swing. – Andrew Thompson Nov 09 '14 at 23:24
  • 1
    To be honest, I am not into AWT, I think Swing is more useful than AWT but my teacher requires me/us to use AWT, reasons are unknown. – MrSilent Nov 10 '14 at 06:26
  • 1
    1) Thanks for answering. 2) My commiserations on the teacher stuck in the last millennium & (glances down the page) 3) Glad you got a solution. :) – Andrew Thompson Nov 10 '14 at 07:58
  • 1
    My teacher is pretty old to be honest, about 60-70 years old, he does live in the last milennium. :) Thank you for your help and guidance. – MrSilent Nov 10 '14 at 08:00

1 Answers1

2

The easiest way to zoom everything is to scale the Graphics2D object at the beginning of the paint method, but before it save the old AffineTransform and reset it at the end.

// save the original transform so that it can be restored later
AffineTransform oldTransform = g2d.getTransform();
g2d.scale(zoom, zoom);
...
// use g2d normally
...
// restore the transform because the same Graphics2D object
// might be used to draw other components
g2d.setTransform(oldTransform );

As Andrew Thompson commented, you should probably use Swing instead of the very old AWT - if you do so, then you need to override paintComponent (instead of paint), but the scaling mechanism is the same.

lbalazscs
  • 17,474
  • 7
  • 42
  • 50