1

Okay so I am trying to build a program using swing in which I have to to be able to draw an oval and rectangle in the bottom right corner of the screen. I am currently trying to use a prior program in which the program starts and stops a square using JToggleSwitch. My Question is How can i get a shape to toggle on and off the screen since it needs a parameter "Graphics g". Here is my PaintPanel code so far.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class PaintPanel extends JPanel
{
    private static Color[] colors =
        { Color.RED, Color.BLACK, Color.PINK, Color.ORANGE };
    private int colorNumber = 0;

    private int shape = 0;

    private int x = 0;
    private int y = 0;

    private int width = 100;
    private int height = 100;

    private int dx = 2;
    private int dy = 2;

    private String displayString = "hello";

    private boolean isStarted = true;

    public void update()
    {
        if (isStarted) 
        {
            x += dx;
            y += dy;
        }
        //dx ++;
        //dy ++;

        if (y + height > getHeight())
        {
            dy = -Math.abs(dy);
            shape++;
            colorNumber = (colorNumber+1)%colors.length;
        }
        else if (y < 0)
        {
            dy = Math.abs(dy);
            shape++;
            colorNumber = (colorNumber+1)%colors.length;
        }

        if (x + width > getWidth())
        {
            dx = -Math.abs(dx);
            shape++;
            colorNumber = (colorNumber+1)%colors.length;
        }
        else if (x < 0)
        {
            dx = Math.abs(dx);
            shape++;
            colorNumber = (colorNumber+1)%colors.length;
        }

    }

    public void changeColor()
    {
        colorNumber = (colorNumber+1) % colors.length;
    }

    public void startStop()
    {
        //if (isStarted == true) isStarted = false;
        //else isStarted = true;

        isStarted = !isStarted;
    }

    public void setDisplayText(String dt)
    {
        displayString = dt;
    }
    public void paintRectangle(Graphics g)
    {

        int w = getWidth();
        int h = getHeight();
        g.setColor(Color.PINK);
        g.fillRect(w/2, h/2, w/2, h/2);
        //g.setColor(Color.CYAN);
        //g.fillOval((5*w)/8, (5*h)/8, w/4, h/4);


    }


    public void paintComponent(Graphics g)
    {



        int w = getWidth();
        int h = getHeight();
        g.setColor(colors[colorNumber]);
        if (shape % 2 == 0) //g.fillOval(x, y, width, height);
        /*else*/ g.fillRect(x,y, width, height);


        int textx = x+width/2;
        int texty = y+height/2;

        FontMetrics fm = g.getFontMetrics();
        int texth = fm.getHeight();
        int textw = fm.stringWidth(displayString);

        textx -= textw/2;
        texty += texth/2;
        texty -= 5;     

        g.setColor(colors[(colorNumber+1)%colors.length]);
        g.drawString(displayString, textx, texty);
    }

}

And here is the actual code that creates the window and panel. This is my main class.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GuiTest extends JFrame 
    implements ActionListener
{
    private Timer frameTimer;
    private JToggleButton name;
    private JToggleButton ovalButton;
    private JToggleButton rectangle;
    //private JTextField theText;
    private PaintPanel paintPanel;

    public GuiTest()
    {
        setTitle("Servando Hernandez");
        setSize(500,500);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel topPanel = new JPanel();
        topPanel.setLayout(new GridLayout(1,3));

        name = new JToggleButton("Name");
        name.addActionListener(this);

        ovalButton = new JToggleButton("Oval");
        ovalButton.addActionListener(this);

        rectangle = new JToggleButton("Rectangle");
        rectangle.addActionListener(this);

        //theText = new JTextField("HI");
        //theText.addActionListener(this);


        topPanel.add(name);
        topPanel.add(ovalButton);
        topPanel.add(rectangle);
        //topPanel.add(theText);

        Container contentPane = getContentPane();
        contentPane.setLayout(new BorderLayout());
        contentPane.add(topPanel, BorderLayout.SOUTH);

        paintPanel = new PaintPanel();
        contentPane.add(paintPanel, BorderLayout.CENTER);

        frameTimer = new Timer(50, this);
        frameTimer.start();
    }

    public void actionPerformed(ActionEvent e)
    {
        //System.out.println("Action performed");
        if (e.getSource() == name)      
        {
            paintPanel.changeColor();
        }
        else if (e.getSource() == frameTimer)
        {
            paintPanel.update();
        }
        else if (e.getSource() == ovalButton)
        {
            //System.out.println("start/stop");
            paintPanel.startStop();
        }
        else if (e.getSource() == rectangle)
        {

        }
        /*else if (e.getSource() == theText)
        {
            String text = e.getActionCommand();
            paintPanel.setDisplayText(text);
            //System.out.println(text);
        }
        */
        repaint();
    }

    public static void main(String[] args)
    {
        GuiTest gui = new GuiTest();
        gui.setVisible(true);

    }
}
Servanh
  • 45
  • 8
  • You could maintain a `List` of `Shape`s to be drawn and add/remove them as you need. You could maintain a series of flags which dictates which shapes are to be painted – MadProgrammer Apr 29 '15 at 23:25
  • You should also be calling `super.paintComponent` before you do any custom painting – MadProgrammer Apr 29 '15 at 23:25

1 Answers1

1

You could...

Maintain a List of Shapes which are to be painted, adding or removing them as needed. You would then loop through the list in the paintComponent method, painting what ever was in the List and simply calling repaint when you want the component updated

You could...

Have a series of boolean (or other types of) flags which dictates which shapes are to be painted. This kind of fixes what shapes are available to be painted and doesn't really allow you to control the z-order of the shapes

You should...

Be calling super.paintComponent before you do any custom painting, otherwise you are likely to produce unwanted paint artifacts each time the component is painted. Remember, painting is destructive and when paintComponent is called, you should completely repaint the current state of the component

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366