0

I am solving a Java problem about AWT. When you click the right button of Mouse. It will create an oval. If you click the left button, it will remove the oval you clicked. I have implemented the creation of ovals, but I cannot find any built-in functions about removing shapes in AWT. My code is below:

package chapter16;

import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Points extends JFrame{
    public Points(){
        add(new NewPanel4());
    }
    public static void main(String[] args){
        Points frame = new Points();
    frame.setSize(200, 200);
    frame.setTitle("Add and Remove Points");
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}
class NewPanel4 extends JPanel{
    private boolean Add = false;//add points
    private int x,y;//the x,y coordinate
    public NewPanel4(){
        addMouseListener(new MouseAdapter(){
            public void mouseClicked(MouseEvent e){
                if(e.getButton()== MouseEvent.BUTTON3){
                    Add = true;
                    x = e.getX();
                    y = e.getY();
                    repaint();
                }
                else if(e.getButton() == MouseEvent.BUTTON1){
                    Add = false;
                }
            }
        });


    }

    protected void paintComponent(Graphics g){
        //super.paintComponent(g);
        //Add oval if Add is true
        if (Add == true){
            g.fillOval(x, y, 10, 10);
        }
        //remove oval if Add is false
        else if(Add == false){
            //code to remove ovals
        }
    }
}
}
Wang Jirao
  • 51
  • 5
  • Retain a list of the shapes and add to or subtract from the list. Aech add/remove call for a repaint and in the overriden paint method, (call the super method to erase the earlier drawings, then) iterate the list and draw each shape in it. [This example](http://stackoverflow.com/a/26579730/418556) (which goes somewhat further than the specification here - in that it will serialize the shapes on program exit) offers a list on the left of the GUI to allow the user to remove shape elements. – Andrew Thompson Jun 13 '16 at 04:16
  • `//super.paintComponent(g);` Why is that code statement commented out? It **should** be included. – Andrew Thompson Jun 13 '16 at 04:27
  • I make it as a comment because I want to keep other ovals in the frame or they will be removed in the repaint()? – Wang Jirao Jun 13 '16 at 06:36
  • They will certainly **be removed.** That's why I added *".. **iterate the list** and **draw each shape**.."*. If you don't call the super method to paint the background, the old shapes will still be visible, even if removed from the list of shapes. When doing custom painting, the GUI has to draw every pixel that needs drawing, whenever requested (which might be due to any number of things not related to your buttons or your program at all - e.g. when another app. covers then uncovers part of your app.). – Andrew Thompson Jun 13 '16 at 06:44

1 Answers1

0

I have refactored your code to use a collection to store the oval. Hope it helps you. It is same as what Andrew suggested.

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Points extends JFrame {

    public Points() {
        add(new NewPanel4());
    }

    public static void main(String[] args) {
        Points frame = new Points();
        frame.setSize(200, 200);
        frame.setTitle("Add and Remove Points");
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    class NewPanel4 extends JPanel {

        private List<Point> points = new ArrayList<>();

        public NewPanel4() {
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (e.getButton() == MouseEvent.BUTTON3) {
                        Point center = new Point(e.getX(), e.getY());
                        points.add(center);
                        repaint();
                    } else if (e.getButton() == MouseEvent.BUTTON1) {
                        removeOval(new Point(e.getX(), e.getY()));
                        repaint();
                    }
                }
            });
        }

        private void removeOval(Point selectedPoint) {
            for (Iterator<Point> iterator = points.iterator(); iterator.hasNext();) {
                Point center = iterator.next();
                if (isInsideOval(selectedPoint, center)) {
                    iterator.remove();
                    break;
                }
            }
        }

        private boolean isInsideOval(Point point, Point center) {
            int r = 5;
            int dx = point.x - center.x;
            int dy = point.y - center.y;
            return (dx * dx + dy * dy <= r * r);
        }

        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g2D = (Graphics2D) g;
            g2D.setRenderingHint(
                    RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            super.paintComponent(g);
            g2D.setColor(Color.BLUE);
            for (Point point : points) {
                g2D.fillOval(point.x- (10 / 2) , point.y- (10 / 2), 10, 10);
            }
        }
    }
}
Beniton Fernando
  • 1,533
  • 1
  • 14
  • 21