0

I'm required to make a program that allows a user to add shapes to a window by clicking where they want to add a shape. However, I have been having a problem were adjusting the window size results in the shapes being cleared.

To put it simply, how would I keep previously drawn objects after I have adjusted the window?

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.util.Locale;

import javax.swing.*;

public class GUIApp 
{
    public static void main(String[] args)
    {
        JFrame f = new AppFrame("GUI Frame Practice");
    }
}

class AppFrame extends JFrame
{
    JPanel pnlText, pnlGraphics;

    public AppFrame(String title)
    {
        super(title);
    }

    public void frameInit()
    {
        super.frameInit();
        this.setLayout(new GridLayout(1, 2));
        this.add(createContainer());
        this.setSize(1000, 800); // first width then height
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private Component createContainer()
    {
        JPanel container = new JPanel();
        JPanel buttons = new ButtonsPanel();

        container.setLayout(new BorderLayout());
        container.add(buttons, BorderLayout.CENTER);
        return container;
    }
}

class ShapeFactory
{
    static GeoShape createShape(String kind, int x, int y,int size)
    {   
        if(kind.equalsIgnoreCase("rect"))
            return new Rect(x, y, size);
        else if(kind.equalsIgnoreCase("circle"))
            return new Circle(x, y, size);
        else if(kind.equalsIgnoreCase("triangle"))
            return new Triangle(x, y, size);
        else 
            return null;
    }

}   



abstract class GeoShape
{
    int x, y, size;

    public GeoShape(int x, int y, int size)
    {
        this.x = x;
        this.y = y;
        this.size = size;
    }

    public abstract void draw(Graphics g);
}

class Rect extends GeoShape
{   
    public Rect(int x, int y, int size)
    {
        super(x, y, size);
    }

    @Override
    public void draw(Graphics g)
    {
        g.drawRect(x, y, size, size);
    }

}

class Circle extends GeoShape
{   
    public Circle(int x, int y, int size) 
    {
        super(x, y, size);
    }

    @Override
    public void draw(Graphics g)
    {
        g.drawOval(x, y, size, size);
    }   
}

class Triangle extends GeoShape
{

    public Triangle(int x, int y, int size)
    {
        super(x,y,size);
    }

    @Override
    public void draw(Graphics g)
    {
        g.drawLine(x, y, (x+size), y);
        g.drawLine(x, y, x+(size/2), (y-size));
        g.drawLine((x+size), y, x+(size/2), (y-size));
    }
}

class ButtonsPanel extends JPanel
{
    JPanel graphics;

    JButton btnTri, btnRect, btnCirc;
    JPanel pnlButtons;
    String Type;

    public ButtonsPanel()
    {
        super();
        this.addMouseListener(new MsListener());
        Type = "Circle";
        setup();    
    }

    private void setup()
    {
        graphics = new JPanel();

        btnTri = new JButton("Triangle");
        btnRect = new JButton("Rectangle");
        btnCirc = new JButton("Circle");
        pnlButtons = new JPanel();

        this.setLayout(new BorderLayout());
        pnlButtons.add(btnTri);
        pnlButtons.add(btnRect);
        pnlButtons.add(btnCirc);
        this.add(pnlButtons, BorderLayout.SOUTH);

        btnTri.addActionListener(new ActionListener()
        {

            @Override
            public void actionPerformed(ActionEvent e) 
            {
                Type = "triangle";
            }
        });

        btnRect.addActionListener(new ActionListener()
        {

            @Override
            public void actionPerformed(ActionEvent e) 
            {
                Type = "rect";
            }
        });


        btnCirc.addActionListener(new ActionListener()
        {

            @Override
            public void actionPerformed(ActionEvent e) 
            {
                Type = "circle";
            }
        });     
    }

class MsListener extends MouseAdapter
{ //instead of implements MouseListener

    @Override
    public void mousePressed(MouseEvent e) 
    {
        GeoShape s = ShapeFactory.createShape(Type, e.getX(), e.getY(), 50);
        s.draw(getGraphics());  
    }   
}


}

I am aware that their are a handful of ways that I could accomplish this task, however I have yet to find one that I could use in my code. I am also aware that I shouldn't use getGraphics(), and use paintComponent() instead. Yet, I'm not entirely sure how to implement this method.

  • Don't use `getGraphics()`, this is the worst thing you can do. See [Performing custom painting](https://docs.oracle.com/javase/tutorial/uiswing/painting/index.html) and [Painting in Swing](http://www.oracle.com/technetwork/java/painting-140037.html) for more details about how custom painting should be done – MadProgrammer Feb 15 '18 at 00:47
  • Yea I've looked on some other forms that discuss programming and it said that getGraphics() wasn't all that effective. I was recommended to use paintComponent(), but I have been having trouble doing such. – Jacob Mehnert Feb 15 '18 at 02:50
  • Then start with the linked tutorials in my previous comment. At least two the linked duplicates perform realtime operations by painting with the mouse which should give you starting point. Remember, painting is destructive, you are expected to repaint the entire state of your component scratch on each time `paintComponent` is called – MadProgrammer Feb 15 '18 at 03:01
  • Looked at both links, and I'm still having trouble grasping the concept. Is their any way you could please elaborate? – Jacob Mehnert Feb 15 '18 at 03:50
  • Not without writing yet another example which would basically be a copy of the examples that have already been linked – MadProgrammer Feb 15 '18 at 04:18
  • [There's another example](https://stackoverflow.com/questions/35051407/how-to-paint-an-arraylist-of-shapes-java/35052568#35052568) – MadProgrammer Feb 15 '18 at 04:24

0 Answers0