Search code examples
javaswinggraphics2d

Cartesian Plane in Java


After learning cycles, arrays, methods,...I started playing around with graphics but I encountered some problems. I was looking for some example when I saw this one: http://javaceda.blogspot.ch/2010/06/draw-cartesian-coordinate-system-in.html

It provides an example of a cartesian plane in Java. I can understand pretty much everything of that code ( except a few lines like invokelater, SwingUtilities and I will take a look at them later..).

Let's say that now I want to create a class "Point" with constructors, getters, a method that converts Cartesian Coordinates of a point into "Pixel Coordinates" and a method that print the point on the plane.

So, here is the code taken from the link:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Cartesian {
 public static void main(String[] args) {
  SwingUtilities.invokeLater(new Runnable() {

   @Override
   public void run() {
    CartesianFrame frame = new CartesianFrame();
    frame.showUI();
   }
  });
 }

}

class CartesianFrame extends JFrame {
 CartesianPanel panel;

 public CartesianFrame() {
  panel = new CartesianPanel();
  add(panel);
 }

 public void showUI() {
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  setTitle("Cartesian");
  setSize(700, 700);
  setVisible(true);
 }
}

class CartesianPanel extends JPanel {
 // x-axis coord constants
 public static final int X_AXIS_FIRST_X_COORD = 50;
 public static final int X_AXIS_SECOND_X_COORD = 600;
 public static final int X_AXIS_Y_COORD = 600;

 // y-axis coord constants
 public static final int Y_AXIS_FIRST_Y_COORD = 50;
 public static final int Y_AXIS_SECOND_Y_COORD = 600;
 public static final int Y_AXIS_X_COORD = 50;

 //arrows of axis are represented with "hipotenuse" of 
 //triangle
 // now we are define length of cathetas of that triangle
 public static final int FIRST_LENGHT = 10;
 public static final int SECOND_LENGHT = 5;

 // size of start coordinate lenght
 public static final int ORIGIN_COORDINATE_LENGHT = 6;

 // distance of coordinate strings from axis
 public static final int AXIS_STRING_DISTANCE = 20;


 public void paintComponent(Graphics g) {

  super.paintComponent(g);

  Graphics2D g2 = (Graphics2D) g;

  g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    RenderingHints.VALUE_ANTIALIAS_ON);

  // x-axis
  g2.drawLine(X_AXIS_FIRST_X_COORD, X_AXIS_Y_COORD,
     X_AXIS_SECOND_X_COORD, X_AXIS_Y_COORD);
  // y-axis
  g2.drawLine(Y_AXIS_X_COORD, Y_AXIS_FIRST_Y_COORD,
     Y_AXIS_X_COORD, Y_AXIS_SECOND_Y_COORD);

  // draw origin Point
  g2.fillOval(
    X_AXIS_FIRST_X_COORD - (ORIGIN_COORDINATE_LENGHT / 2), 
    Y_AXIS_SECOND_Y_COORD - (ORIGIN_COORDINATE_LENGHT / 2),
    ORIGIN_COORDINATE_LENGHT, ORIGIN_COORDINATE_LENGHT);

  // numerate axis
  int xCoordNumbers = 10;
  int yCoordNumbers = 10;
  int xLength = (X_AXIS_SECOND_X_COORD - X_AXIS_FIRST_X_COORD)
      / xCoordNumbers;
  int yLength = (Y_AXIS_SECOND_Y_COORD - Y_AXIS_FIRST_Y_COORD)
      / yCoordNumbers;

  // draw x-axis numbers
  for(int i = 1; i < xCoordNumbers; i++) {
   g2.drawLine(X_AXIS_FIRST_X_COORD + (i * xLength),
     X_AXIS_Y_COORD - SECOND_LENGHT,
     X_AXIS_FIRST_X_COORD + (i * xLength),
     X_AXIS_Y_COORD + SECOND_LENGHT);
   g2.drawString(Integer.toString(i), 
     X_AXIS_FIRST_X_COORD + (i * xLength) - 3,
     X_AXIS_Y_COORD + AXIS_STRING_DISTANCE);
  }

  //draw y-axis numbers
  for(int i = 1; i < yCoordNumbers; i++) {
   g2.drawLine(Y_AXIS_X_COORD - SECOND_LENGHT,
     Y_AXIS_SECOND_Y_COORD - (i * yLength), 
     Y_AXIS_X_COORD + SECOND_LENGHT,
     Y_AXIS_SECOND_Y_COORD - (i * yLength));
   g2.drawString(Integer.toString(i), 
     Y_AXIS_X_COORD - AXIS_STRING_DISTANCE, 
     Y_AXIS_SECOND_Y_COORD - (i * yLength));
  }
 }
}

Here is the class Point that I want to add:

class Point{
      public int x,y;

        public Point(int x,int y){
            this.x=x;
            this.y=y;
        }
        public Point FromCartToPix() {
            this.x=X_AXIS_FIRST_X_COORD+(x*xLength);
            this.y=Y_AXIS_SECOND_Y_COORD - (y * yLength);
            return this;

        }
        public int GetX(){
            return this.x;
        }
        public int GetY(){
            return this.y;
        }
        public void DrawPoint(){
            g2.fillOval(
                    this.FromCartToPix().Getx(), 
                    this.FromCartToPix().Gety(),
                    ORIGIN_COORDINATE_LENGHT, ORIGIN_COORDINATE_LENGHT);
        }
}

The Java Manual that I have, has just a small chapter about Java Graphics and Swing, for that reason I am not able to implement this class. I think that it should be inserted inside

PaintComponent(Graphics g)

otherwise I wouldn't be able to use

g2.filloval

but then I couldn't use

Point a = new Point (2,3);

inside the main

I know it's a bit a vague and general question but I am not able to get it to work. I searched a lot about the usage of Graphics2D g2 =(Graphics2D) g, but can't find a precise explanation, even on Javadocs.

If u know a link that explain it I would be grateful

Thanks in advance


Solution

  • Your Point class doesn't have access to the Graphics2D object of the CartesianPanel.

    You should move the functionality of your FromCartToPix and DrawPoint methods to the CartesionPanel. This way you can actually draw the points and you separate the data (Point) from the UI (the CartesionPanel).

    // add in CartesionPanel
    private List<Point> points = new ArrayList<>();
    
    public void drawPoint(Point point) {
        points.add(point);
        repaint();
    }
    
    private void drawPointOnPanel(Point point, Graphics g) {
        final int pointDiameter = 5;
        final int x = X_AXIS_FIRST_X_COORD + (point.x * xLength) - pointDiameter / 2;
        final int y = Y_AXIS_SECOND_Y_COORD - (point.y * yLength) - pointDiameter / 2;
        g.fillOval(x, y, pointDiameter, pointDiameter);
    }
    
    public void paintComponent(Graphics g) {
        // existing code ...
    
        // draw points
        points.forEach(p -> drawPointOnPanel(p, g))
    }
    

    In your main function you could draw Points by:

    CartesianFrame frame = new CartesianFrame();
    frame.showUI();
    
    frame.panel.drawPoint(new Point(3, 4));