Search code examples
javajpanelgraphics2d

Java- Calling a method to change the color of an Oval


1.This is part of a bigger game. I want to call the methods to create and display the Jpanel, then be able to call the displayColors method(based on events in other classes) with an integer to change the color of the circle rendered. I've come across a repaint() method that seems helpful, but am unsure how to use it.

import java.awt.*;
import javax.swing.*;
public class SimonView extends JPanel {

    public Graphics2D showSimonsColor;

    public void displayScreen() {

        //Setting up the container
        JFrame frame = new JFrame("Circle Color Game");
        JLabel mitaLabel = new JLabel("A Changing Circle");

        setLayout(new BorderLayout());
        frame.add(mitaLabel, BorderLayout.PAGE_START);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new SimonView());
        frame.setSize(700, 700);
        frame.setVisible(true);

        //just to test the display colors method. Pauses for 5 secs
        SimonView sv = new SimonView();

        for (int i = 0 ; i < 5 ; i ++) {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
            sv.displayColors(i);
        }

    }

    @Override
    public void paint(Graphics g)  {
        showSimonsColor = (Graphics2D) g;
        showSimonsColor.setColor(Color.BLACK);
        showSimonsColor.fillOval(75, 75, 500, 500);
    }

    public void displayColors(int color)  {

        switch (color)  {

            case 0: showSimonsColor.setColor(Color.WHITE);
                break;
            case 1: showSimonsColor.setColor(Color.RED);
                break;
            case 2: showSimonsColor.setColor(Color.BLUE);
                break;
            case 3: showSimonsColor.setColor(Color.GREEN);
                break;
            case 4: showSimonsColor.setColor(Color.YELLOW);
                break;
        }
    }

    public static void main(String[] arguments) {

        SimonView sv = new SimonView();
        sv.displayScreen();
    }
}

Solution

    1. You create three different instance of SimonView, none of which have any thing to with each other and only one which is actually displayed on the screen
    2. You should call repaint to request that you component be repainted (after you've made some change which requires a repaint)
    3. You should not be maintaining a reference to the Graphics2D object, but should instead be painting the current state of the component from within your paint when it's called. This would mean that you will need to maintain a reference to the current color your want to use
    4. You should avoid overriding paint where you can, lots of fun reasons, but it's just simpler to use paintComponent instead
    5. You should be calling super.paint (or super.paintComponent if you overrode it instead) to preserve the paint chain
    6. You should use a Swing Timer to perform time delayed actions within Swing, it's safer to update the UI and won't block the Event Dispatching Thread, preventing it from performing updates
    7. You should be starting your UI from within the context of the Event Dispatching Thread, this just reduces potential issues with thread deadlocks on some systems

    Have a look at

    for more details