Search code examples
javaswingpaintcomponentgraphics2d

Graphics2D does not pull in values from class variables


I'm trying to create a Graphical Circle Calculator program that allows the user to input the diameter of a circle, with the resulting output showing a representation of the circle in a frame along with the radius, circumference, and diameter. I used System.out.println() commands to ensure that the values were being accepted, calculated, and stored. However, I was not able to have the frame/component pull in the values from those same variables, resulting in an ellipse size 0x0, and all data being represented as 0.0.

Any assistance you can provide would be greatly appreciated. The program code is included below.

package javaconcepts;
import java.awt.*;
import java.awt.geom.*;
import java.util.Scanner;

import javax.swing.*;

public class CircleComponent extends JComponent
{
    private String input;
    private float value;
    private float radius;
    private float circ;
    private float area;

    private static final long serialVersionUID = 1L;

    public CircleComponent()
    {

    }

    public void circleCalcValues()
    {
        System.out.println("Welcome to the Circle Graphical Calculator.");
        System.out.println();

        while(true)
        {
            System.out.print("Please enter the diameter's value (in pixels): ");
            Scanner in = new Scanner(System.in);
            input = in.next();

            if(input.equals("done"))
            {
                System.out.println();
                break;
            }

            value = (Float.valueOf(input));
            System.out.println(value);
            calculate();
            System.out.println(radius + ", " + circ + ", " + area);

            draw();

            System.out.println();
            System.out.println("Results are available in window.");
            System.out.println();
        }
        System.out.println("OK.");
        System.exit(0);
    }

    private void calculate()
    {
        radius = (value / 2);
        circ = (float)(value * Math.PI);
        area = (float)(Math.PI * Math.pow(value, 2));
    }

    private void draw()
    {
        JFrame frame = new JFrame();
        frame.setSize(640, 480);
        frame.setTitle("Circle Graphical Calculator: Result");
        frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        CircleComponent component = new CircleComponent();
        frame.add(component);
        frame.setVisible(true);

    }

    public void paintComponent(Graphics g)
    {
        Graphics2D g2 = (Graphics2D) g;

        Ellipse2D.Float output = new Ellipse2D.Float(100, 100, value, value);
        g2.setColor(Color.BLACK);
        g2.draw(output);
        g2.setPaint(Color.WHITE);
        g2.fill(output);
        g2.setColor(Color.BLACK);
        g2.drawString("Diameter: " + value + ", Radius: " + radius + ", Circumference: " + circ + ", Area: " + area, 50, 50);
    }
}

Solution

  • You mixing user input paradigms (console and GUI) and blocking the Event Dispathing Thread, which will prevent Swing from painting anything.

    Basically, a GUI is an event driven environment. Something happens (key press, mouse click) and your code responds to it. This is often achieved through the use of "listeners" which notify you when something changes.

    User input within a GUI environment is done using GUI controls. Take a look at Creating a GUI with Swing.

    Basically, you want to set a field, such as JTextField or JSpinner or JFormattedField that the user can enter values into and possibly a JButton or other listener so that they can "apply" that value so you can paint it...

    While a little bit advanced, Painting in AWT and Swing may give you some cluse of why your current approaching isn't working