Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constructing Rectangle

Tags:

java

I am constructing a Rectangle class. I tried many times and watched numerous tutorials, but my program is not working. This is my code so far:

public class Rectangle {

    public static void main(String[] args) {

        Rectangle box = new Rectangle(5,10,20,30){
            System.out.println(new Rectangle());}
}
like image 812
S.Dovra Avatar asked Sep 14 '15 17:09

S.Dovra


1 Answers

Assumptions

I'm assuming you're unfamiliar with the syntax of the Java language, and trying to piece together your first Java class.

I'm also assuming you need the following things:

  1. A definition of a Rectangle.
  2. The properties x and y, indicating the Rectangle's origin.
  3. The properties width and height, indicating the Rectangle's dimensions.
  4. The ability to create a Rectangle by specifying these four key properties.
  5. The ability to display the properties of an existing Rectangle.

What You Have Already

Right now, you have a good start on this, but it's a little crossed.

Your first and last lines:

public class Rectangle {

}

define your Rectangle class. This serves as a unit of code, and a template for making objects. Classes have defined methods (behavior) and fields/properties (information), which serve to indicate how objects of that class can operate and describe what data is accessible on each object.

In short, this defines a general type of thing that can be created; in your case, you're defining what it means for an object to be a Rectangle in your code.

Your second line, and its follow-up:

public static void main(String[] args) {

}

defines a static method called main. There's a lot of stuff here to explain, but for now, just think of this as an entry point into a Java program. If you were to run this class as a Java program, this method would be (almost) the first code which is run.

The next line:

Rectangle box = new Rectangle(5,10,20,30);   // notice the correction here, no curly braces, but a semicolon to end the line of code.

is what you would do to declare a Rectangle named box, then create a new Rectangle object and assign the object to the variable named box. In other words, you're making a new Rectangle whose name is box.

The keyword new means that you're making a new object of type Rectangle. The numbers in the parentheses are arguments, which define some things about the object being created. These get passed into a constructor method of the Rectangle class, which puts those arguments into the newly-created object.

Right now, though, there is no constructor, so your code won't work right in that regard. I'll write one up further down, so keep reading.

The next line:

System.out.println(new Rectangle())  // NOTE: This is incorrect, see below

is also a little complicated. Basically, the System.out.println method writes text to the program's console, where it is seen by the user. It's used for writing out messages from your program, or showing the contents of variables in the program, to the screen.

Right now, you're passing it a new Rectangle object, which doesn't really make sense. A Rectangle isn't text, nor is it a basic variable (like an integer, a byte, a decimal number, a single character of text, or a true/false value), so if you try to print that new Rectangle object to the screen, you'll see some gobbledy-gook text provided by Java that looks like this:

Rectangle@1a2fc866

However, we have a nifty little feature that lets us tell Java how to convert objects of a specific class into a string of text; I'll show you that below.

What Needs To Be Done

First of all, we need to have our Rectangle class.

public class Rectangle {

}

There! We've defined a Rectangle class, for making Rectangle objects. Now, it needs some properties. We'll say these are integer numbers, called x, y, width, and height. Our class now looks like this:

public class Rectangle {
    public int x; // Defined with a scope (public), a type (int), and a name (x).
    public int y;
    public int width, height; // We can do multiple on the same line, if they share the same scope and type.
}

Okay, cool. Now, how do we make a Rectangle? Use a constructor method! If we didn't need information about the Rectangle when we make a new one, we can leave this out and use a default constructor which Java provides for us, but we do need the information about the rectangle's position, width, and height. Our code grows to this:

public class Rectangle {
    public int x;
    public int y;
    public int width, height;

    // This line defines a constructor with 4 parameters: x, y, w, and h.
    public Rectangle(int x, int y, int w, int h) {
        // This initializes our x, y, width, and height properties to what is passed in.
        this.x = x;    // We set our current object's x property to the x we're given.
        this.y = y;    // We have to specify which y is which, so we use this.y to indicate the current object, and y to specify the parameter we're given.
        width = w;     // We can leave off the "this" part if there's nothing else named "width" visible in the method.
        height = h;
    }
}

Now we have the ability to make a Rectangle object and specify its position, width, and height. But we have no program, since there is no entry point. Let's add one like you did originally, but fix some of the issues your original code had:

public class Rectangle {
    public int x;
    public int y;
    public int width, height;

    public Rectangle(int x, int y, int w, int h) {
        this.x = x;
        this.y = y;
        width = w;
        height = h;
    }

    // This is our program's entry point. It's static, and belongs to the Rectangle class, and NOT to the Rectangle objects.
    public static void main(String[] args) {
        // Inside our main method, let's make a new rectangle object.
        // Based on our constructor, the position is {5, 10}, the width is 20, and the height is 30.
        Rectangle box = new Rectangle(5, 10, 20, 30);

        // Now that it's created and named "box", let's print it out!
        // We pass the box variable as an argument to System.out.println,
        // and that method prints the box as if it were a string.
        System.out.println(box);
    }
}

We now have an entry point to our program, that does a little bit of stuff. We create a Rectangle, which we assign to the Rectangle variable called box. Then, we try to print box as a string to the console window. As mentioned earlier, if we run the program right now, we will end up with console output like this:

Rectangle@1a2fc866

This isn't what we want; we want to see what the Rectangle's position, height and width are! So, let's change how Java turns our Rectangle objects into strings of text, by adding a toString() method. Our Rectangle class now looks like this:

public class Rectangle {
    public int x;
    public int y;
    public int width, height;

    public Rectangle(int x, int y, int w, int h) {
        this.x = x;
        this.y = y;
        width = w;
        height = h;
    }

    public static void main(String[] args) {
        Rectangle box = new Rectangle(5, 10, 20, 30);
        System.out.println(box);
    }

    // Here is our toString method.
    // It's declared as an @Override, which means it overrides the toString method provided by the class that Rectangle is based on (in this case, java.lang.Object).
    // The method is in the public scope, returns a String-type value, and is called toString. It doesn't have parameters, so it gets empty parentheses.
    @Override
    public String toString() {
        // Now, we have to return a value from this method.

        // Start by declaring a local variable and filling it with some data.
        String stringValue = "Rectangle with location {";

        // We can "add" strings together to form a bigger string with the contents mashed next to each other (aka "concatenated").
        stringValue = stringValue + this.x + ",";

        // By "adding" this.y (the current object's y property) to a string, it also gets converted from an integer to a string without us needing to say anything special.
        stringValue = stringValue + this.y + "}";

        // We can take some shortcuts, too, by using the += operator so we don't have to rewrite stringValue twice every time!
        stringValue += ", width: " + this.width;

        // Remember, we don't need to use "this" when the name is not ambiguous, but it typically makes it clearer that some data is coming from the object instead of a local variable.
        stringValue += ", height: " + height;

        // Once we have a result value and no other code needs to be executed, we have to *return* it as the result of the method. Constructors and methods with "void" as their return type do not do this (though void methods can just say "return;")
        return stringValue;
    }
}

Now, when we run our program, it will print out the following:

Rectangle with location: {5,10}, width: 20, height: 30

We can clean up the toString method a lot here, so our class looks like this:

public class Rectangle {
    public int x;
    public int y;
    public int width, height;

    public Rectangle(int x, int y, int w, int h) {
        this.x = x;
        this.y = y;
        width = w;
        height = h;
    }

    public static void main(String[] args) {
        Rectangle box = new Rectangle(5, 10, 20, 30);
        System.out.println(box);
    }

    @Override
    public String toString() {
        return "Rectangle with location {" + x + "," + y + "}, width: " + width + ", height: " + height;
    }
}

Going Further

Now, what we need to do is to get our Rectangle to show up on the screen. In order to do this, we're going to need to bring in the AWT framework (Advanced Window Toolkit) and the Swing framework. This isn't the only way to get it to show up on screen, but it works for our purposes.

Thanks to @KanadJadhav for posting this example in his answer here.

We need to add some imports to the top of the file, and start modifying our main method so that it sets up AWT and Swing and uses them to draw our rectangle. Add this to the top of the file:

import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;

These bring in the classes you'll need to create a program window and draw your rectangle on it. I won't get into how AWT and Swing work in detail, but I'll show you what you need.

In order to get your Rectangle to appear on-screen, we need to create a window, set its size, and fill the window's content pane with a component which will draw the rectangle onto the screen. Afterwards, we just make our window visible, and Swing handles all the dirty work, keeping our program alive until the window is closed.

public static void main(String[] args) {
    Rectangle box = new Rectangle(5, 10, 20, 30);

    // New stuff - Create a program window and set it up.
    JFrame window = new JFrame();

    // Tell Swing to exit the program when the program window is closed.
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    // Set the window boundaries to be 300x300 on the screen, and position it 30 pixels from the top and left edges of the monitor.
    window.setBounds(30, 30, 300, 300);

    // Get the content pane of the window, and give it our own custom component.
    window.getContentPane().add(new JComponent() {  // Not a typo - this is some advanced magic called an "anonymous class".
        Rectangle myBox = box;    // Give the component a reference to our box object.
        public void paint(Graphics g) {
            g.drawRect(myBox.x, myBox.y, myBox.width, myBox.height);
        }
    });

    // Make our window appear.
    window.setVisible(true);
}

This is a little sloppy and hard to follow, so you'll have to excuse my hand-waving. I feel I've explained some of the tricky bits in the comments (like the anonymous class - that's a pretty advanced Java feature), but in general, this is the type of code that the Swing documentation shows, and much of it doesn't need to be understood completely to be used. If you want, you can do your own research on the Swing framework, the AWT Graphics class, or Java Anonymous classes through the examples at the links I've provided.

like image 123
Shotgun Ninja Avatar answered Sep 30 '22 08:09

Shotgun Ninja