Linda
Linda

Reputation: 2405

Drawing two circles with different positions and colors in java

I'm new to Java and I want to try some graphic things with it. I want to generate two circles with two different colors and different positions. My code:

Paint Class:

package de.test.pkg;
import javax.swing.*;

public class paint {

    public static void main(String[] args) throws Exception{

        JFrame frame = new JFrame("Titel");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Circle d = new Circle();
        Circle r = new CircleRed();
        frame.add(d);
        frame.add(r);
        frame.setSize(600,200);
        frame.setVisible(true);

    }

}

Circle class

package de.test.pkg;
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;


public class Circle extends JPanel {

    private double iconRadius = 100;
    private Color defaultColor = new Color(89,104,99); 
    private int positionX = 0;
    private int positionY = 0;

    private Ellipse2D iconBody = new Ellipse2D.Double(getPositionX(),getPositionY(),iconRadius,iconRadius);

    public Icon(){

    }

    public Color getDefaultColor() {
        return defaultColor;
    }

    public void setDefaultColor(Color defaultColor) {
        this.defaultColor = defaultColor;
    }

    public int getPositionX() {
        return positionX;
    }

    public void setPositionX(int positionX) {
        this.positionX = positionX;
    }

    public int getPositionY() {
        return positionY;
    }

    public void setPositionY(int positionY) {
        this.positionY = positionY;
    }

    public void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D)g;
        super.paintComponent(g2d);
        this.setBackground(new Color(255,255,255));

        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setPaint(getDefaultColor());
        g2d.draw(iconBody);
        g2d.fill(iconBody);
    }

}

CircleRed class

package de.design.pkg;
import java.awt.Color;

public class CircleRed extends Circle {

private Color defaultColor = Color.RED;
private int positionX = 120;
private int positionY = 0;

public CircleRed() {
}

public Color getDefaultColor() {
    return defaultColor;
}

public void setDefaultColor(Color defaultColor) {
    this.defaultColor = defaultColor;
} 

public int getPositionX() {
    return positionX;
}

public void setPositionX(int positionX) {
    this.positionX = positionX;
}

public int getPositionY() {
    return positionY;
}

public void setPositionY(int positionY) {
    this.positionY = positionY;
    }

}

The Result is that the Circles have the same positions.

My questions are:

  1. Why do they have the same positions?
  2. Is this a good way to do that or are there better solutions? I want to use a class so please don't gave me answers with do all that paint thing in the Main.
  3. Is there a better way to hold the position. Maybe in an array? But how should the setter and getter look like if I want to return array[position]?
  4. If I want to set the Position from the Main function. How can I do this?

Upvotes: 0

Views: 4660

Answers (4)

user1803551
user1803551

Reputation: 13407

The Result is that the Circles have the same positions.

(1) Why do they have the same positions?

Not really. The result is that only CircleRed is displayed. Your problem here is not with painting, it's with adding components to a container with a suitable layout manager. The lines

Circle d = new Circle();
Circle r = new CircleRed();
frame.add(d);
frame.add(r);

add r instead of d. This is because JFrame uses BorderLayout by default and you are replacing the center component d with r the line after. Just to show the point, add the line

frame.setLayout(new GridLayout(1, 2));

enter image description here

(2) Is this a good way to do that or are there better solutions? I want to use a class so please don't gave me answers with do all that paint thing in the Main.

It depends on what you are aiming to do. I would venture a guess that if you want to practice inheritance, it would be better for you to create an abstract class for a general circle with shared code and then subclass it with concrete implementation and specific code for the various types. Otherwise, you can just create a single customizable circle class and instantiate that one with different parameters.

It's not a good practical approach in any case because the placement of the circles (which are JPanels) will be determined by the layout manager. The painting only determines the location of the painted shape in the panel. It would be better to just paint the shapes on a single big panel and not with using multiple panels.

There are a few very good answers on the site about moving components around.

(3) Is there a better way to hold the position. Maybe in an array? But how should the setter and getter look like if i want to return array[position]?

There are effectively 2 positions in your design. One is for the panels in the frame, the other is for the shapes in the panels.

For the latter, I would use a Point or just an int x, y fields in the class itself. Getters and setters are the standard ones, the setters will control the position (you will need to call repaint() though).

For the first, it is determined by the layout manager and you don't (shouldn't) control it in a pixel-prefect way. You just instruct the layout manager with "guidelines" and it does the calculations for you.

(4) If I want to set the Position from the Main function. How can i do this?

Again, depends on which position you are talking about. See above.

Upvotes: 4

Pankaj Prakash
Pankaj Prakash

Reputation: 2428

You are going wrong way. You can simply draw two circles by overriding paint method of JFrame class.

Here is a sample demo program.

import java.awt.*;

/**
 *
 * @author Pankaj
 */
public class TestFrame extends javax.swing.JFrame {

    /**
     * Creates new form NewJFrame
     */
    public TestFrame() {
        initComponents();
        setTitle("Graphics Demo");
        setSize(200,200);
    }

    /**
     * You need to override this method.
     */
    @Override
    public void paint(Graphics g) {
        int X1 = 10; //X coordinate of first circle
        int X2 = 60; //X coordinate of second circle
        int Y1 = 100; //Y coordinate of first circle
        int Y2 = 100; //Y coordinate of second circle
        int width = 50; //Width of the circle
        int height = 50; //Height of the circle 

        Color color1 = Color.RED; //Color of first circle
        Color color2 = Color.BLUE; //Color of second circle

        g.setColor(color1);
        g.fillOval(X1, Y1, width, height);

        g.setColor(color2);
        g.fillOval(X2, Y2, width, height);
    }

    private void initComponents() {
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setResizable(false);
        pack();
    }                       

    public static void main(String args[]) {
        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new TestFrame().setVisible(true);
            }
        });
    }                 
}

And here's the output

enter image description here

Upvotes: -1

ThatOneCloud
ThatOneCloud

Reputation: 83

  1. They're in the same position because the paintComponent() method in Circle is being used for both - and it's using the position variables defined in Circle. When you have CircleRed extend Circle, you don't need to define the position variables again - you inherit them from Circle. Instead, call the setPosition() methods on CircleRed. (You don't need to define these either, they're also inherited.)

  2. There are a variety better solutions, I think the biggest improvement would be to improve your use of inheritance.

  3. That's a fine way to hold the position. If anything else, you could also use a Point object. (Already in Java)

  4. To set the position from the main function, you just call for example

    Circle c = new Circle(); c.setPositionX(120); c.setPositionY(40);

Upvotes: 0

Ryan
Ryan

Reputation: 1974

What your doing is very overkill for just creating two colored circles. You can just use the paint method in java.awt

public void paint(Graphics g){ 

       g.setColor(Color.YELLOW);
       g.fillOval(20,20,160,160);

       g.setColor(Color.RED);
       g.fillOval(60,60,80,80);
    } 

fillOval takes the following parameters (int x, int y, int width, int height) You can use g.setColor(Color.NAME) to change the color of your circle. Just call this method before your draw calls.

Upvotes: 1

Related Questions