user203837
user203837

Reputation: 21

Trouble with graphics in Java

I'm working on a school project and I have to create a person's face in java that the user of my app can edit. Each facial characteristic is supposed to have a couple of options, so the first one I tried doing is the eye. However, I'm having trouble when I try to interact with the user in the eyeComponent class.

It prints the users color options (1-4) in the JVM, and opens a blank JFrame window, but in the JVM, it doesn't allow for a user's response. After it prints out the color options, the program just ends, and I'm not sure why it's not allowing the user to respond. I posted the code for both the EyeComponent and PersonViewer classes below.

EyeComponent

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import javax.swing.JComponent;
import java.util.Scanner;  

public class EyeComponent extends JComponent
  { 
    public void paintComponent(Graphics g)
  {
    Scanner in = new Scanner(System.in);
    Graphics2D g2 = (Graphics2D) g;
    Ellipse2D.Double head = new Ellipse2D.Double(5,20,100,150);
    System.out.println("What color would you like the eyes to be?"); 
    System.out.println("Select \n1:blue \n2:red \n3:yellow \n4:green"); 
    int response = in.nextInt(); 
    if (response == 1)
        { g2.setColor(Color.BLUE);}
        else if (response == 2)
        { g2.setColor(Color.RED);}
    else if (response == 3)
        { g2.setColor(Color.YELLOW);}
    else if (response == 4)
        { g2.setColor(Color.GREEN);}
    g2.draw(head); 
 }   
}

PersonViewer

import javax.swing.*;
import java.util.Scanner;
public class personViewer //creates class called engine of scope public
  {
     public static void main (String [] args) //main method for engine class
     {
        JFrame frame = new JFrame();
        frame.setSize(150, 250);
        frame.setTitle("Face");
        EyeComponent component = new EyeComponent();
        frame.add(component);
        frame.setVisible(true);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

Upvotes: 1

Views: 365

Answers (3)

MiSu
MiSu

Reputation: 29

Do not have your scanner in a method which you do not have control about. I refactored you code a bit to more OOP approach.

    import javax.swing.*;

import java.awt.Color;
import java.util.Scanner;

public class PersonViewer // creates class called engine of scope public
{

    public static void main(String[] args) // main method for engine class
    {

        Configurator conf = Configurator.getInstance();
        Scanner in = new Scanner(System.in);
        System.out.println("What color would you like the eyes to be?");
        System.out.println("Select \n1:blue \n2:red \n3:yellow \n4:green");
        int response = in.nextInt();
        switch (response) {
        case 1:
            conf.setEyeColor(Color.BLUE);
            break;
        case 2:
            conf.setEyeColor(Color.RED);
            break;
        case 3:
            conf.setEyeColor(Color.YELLOW);
            break;
        case 4:
            conf.setEyeColor(Color.GREEN);
            break;

        }
        JFrame frame = new JFrame();
        frame.setSize(150, 250);
        frame.setTitle("Face");
        EyeComponent component = new EyeComponent();
        frame.add(component);
        frame.setVisible(true);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

    import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;

import javax.swing.JComponent;

public class EyeComponent extends JComponent {

    Configurator conf = Configurator.getInstance();

    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        Ellipse2D.Double head = new Ellipse2D.Double(5, 20, 100, 150);
        g2.setColor(conf.getEyeColor());
        System.out.println(conf.getEyeColor());
        g2.draw(head);
    }
}

    import java.awt.Color;


public class Configurator {

    private static Configurator instance = null;
    public static Configurator getInstance() {
        if (instance==null) {
            instance = new Configurator();
            System.out.println("first called");
        }
        else {
            System.out.println("next calls");
        }
        return instance;
    }
    private Color eyeColor;

    public Color getEyeColor() {
        return eyeColor;
    }

    public void setEyeColor(Color eyeColor) {
        this.eyeColor = eyeColor;
    }

}

Hope this help to get a point. And it works.

Upvotes: 0

MadProgrammer
MadProgrammer

Reputation: 347234

This is (another) Event Dispatching Thread issue.

You should NEVER request input from the user via the console from within a GUI program, apart from breaking the whole point of GUI, you have know experienced what happens when you block the main event/repaint thread.

Swing (like all GUI's) are event driven environments. The user clicks or types something and the program responds to it. In this form, they are unlike console programs, which tend to be more linear in nature.

Swing uses a single thread to perform all it's painting and event notification from. Doing anything that stops this thread from running will cause you application to appear as if it has hung and become non-responsive.

Start by having a read of Creating GUIs with Swing and then have a read of Performing Custom Painting and finally I would highly recommend you take a look at Painting in AWT and Swing

Simple Example

enter image description here

Upvotes: 2

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

Never use a Scanner or any blocking code inside of paintComponent. Ever. In fact this blocking code should never be called on the Swing event thread, but especially so in paintComponent as it will grind your program's graphics to a halt. Just don't do it.

Upvotes: 2

Related Questions