user7253631
user7253631

Reputation:

Java Won't draw paintComponent from another class

I have a main class and a subclass Circle that has a paintComponent method within it. I am trying to call that method to my main class to draw the Circle but nothing will appear and i'm not sure why?

My Circle class:

public class Circle extends Shape {
Integer rad;

public Circle(int posx,int posy, int rad) {
    this.posx = posx;
    this.posy = posy;
    this.rad = rad;
}

class drawCircle extends JPanel {
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.setColor(Color.green);
        g.fillOval(posx,posy,rad,rad);
    }
  }
}

My main method snippets

public class drawFrame extends JFrame {
JPanel panel1;
JPanel panel2;
Square square1;
Circle circle1;



public drawFrame() {

    panel2= new JPanel();
    panel1= new JPanel();

 int rad = 0;
    circle1 = new Circle(posx, posy,rad);
    Circle.drawCircle drawCi = circle1.new drawCircle();
    add(panel1, BorderLayout.CENTER);
    panel1.add(drawCi);

So essentially I've just given some snippets of the main part of the code. What I tried doing was creating a new object from the Circle drawCircle inner class,adding it to the mainPanel, so that my Jframe outputs my mainPanel contents which should be the new Circle object I've created? But It seems this doesn't work.

Upvotes: 1

Views: 731

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

Your code is confusing, and I recommend simplifying.

Problems:

  • You're using an inner class, drawCircle unnecessarily. Don't nest classes when not needed, but instead give the drawing component its own stand-alone class.
  • You're creating a drawing component, but never adding it to the GUI. Without adding it to a top-level window, here the JFrame, it will never display. Edit: You are in fact adding it, but its preferred size is 0,0
  • You're overriding paint not paintComponent. This carries both problems (jerky animations when you later try to do this) and risk (paint also affects a component's child component and border drawing).
  • Your drawing component has no preferred size set, so it will size to [0,0], and this is not conducive to showing its drawing.

Instead (again) create a stand-alone, non-nested class that extends JPanel, override its paintComponent where you draw the circle and be sure to add it to the displayed JFrame. Also either set the drawing component's preferred size or override its getPreferredSize() method. Of course be sure to pack() the JFrame after adding components and then calling setVisible(true) on it after packing it.

A minor issue: you will want to learn and use Java naming conventions. Variable names should all begin with a lower letter while class names with an upper case letter. Learning this and following this will allow us to better understand your code, and would allow you to better understand the code of others.

Minor quibble 2: You're rad field (presumably named for radius) should be called "diameter" since it's being used as a diameter, not a radius.

e.g.,

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.*;

@SuppressWarnings("serial")
public class DrawCircle extends JPanel {
    private static final int PANEL_WIDTH = 600;
    private static final Color CIRCLE_COLOR = Color.GREEN;
    private int posx;
    private int posy;
    private int diameter;

    public DrawCircle(int posx, int posy, int diamter) {
        setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_WIDTH));
        this.posx = posx;
        this.posy = posy;
        this.diameter = diamter;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        // for smooth graphics
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(CIRCLE_COLOR);
        g2.fillOval(posx, posy, diameter, diameter);
    }

    private static void createAndShowGui() {
        DrawCircle mainPanel = new DrawCircle(100, 100, 400);

        JFrame frame = new JFrame("DrawCircle");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

Upvotes: 4

Related Questions