0

I would like to know how i can make java detect whether an ellipse is linked to a line or a rectangle and the program should also detect the shape that it is linked to.

The ellipse is drawn, a line is also drawn and a rectangle. Java must detect whether there is something linked to the ellipse, if yes, then find out through the line what is linked to it.

enter image description here

Here is my code to draw the shapes.

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;

import javax.imageio.ImageIO;
import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileNameExtensionFilter;

public class Lesson49_1 extends JFrame {

    private static final long serialVersionUID = -140274271716086522L;

    JMenuBar menubar;
    JMenu File, Exit;
    JMenuItem New, Open;
    JComponent DrawingBoard;

    JButton  lineBut, ellipseBut, rectBut, strokeBut;

    DecimalFormat dec = new DecimalFormat("#.##");

    // Contains all of the rules for drawing

    Graphics2D graphSettings;

   
    // Going to be used to monitor what shape to draw next

    int currentAction = 1;

    // Transparency of the shape

    // Default stroke and fill colors

    Color strokeColor = Color.BLACK;

    public static void main(String[] args) {
        new Lesson49_1();
    }

    public Lesson49_1() {
        // Define the defaults for the JFrame

        this.setSize(800, 600);
        this.setTitle("ERD BUILDER");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setJMenuBar(menubar);

        JMenuBar menuBar = new JMenuBar();

        // Add the menubar to the frame
        setJMenuBar(menuBar);

        // Define and add two drop down menu to the menubar
        JMenu fileMenu = new JMenu("File");
        JMenu editMenu = new JMenu("Edit");
        JMenu dbMenu = new JMenu("Database");
        JMenu ToolsMenu = new JMenu("Tools");
        JMenu HelpMenu = new JMenu("Help");
        menuBar.add(fileMenu);
        menuBar.add(editMenu);
        menuBar.add(dbMenu);
        menuBar.add(ToolsMenu);
        menuBar.add(HelpMenu);
        // Create and add simple menu item to one of the drop down menu
        JMenuItem newAction = new JMenuItem("New Project");
        JMenuItem openAction = new JMenuItem("Open File");
        JMenuItem exitAction = new JMenuItem("Quit");
        JMenuItem cutAction = new JMenuItem("Cut");
        JMenuItem copyAction = new JMenuItem("Copy");
        JMenuItem pasteAction = new JMenuItem("Paste");
        JMenuItem UndoAction = new JMenuItem("Undo");
        JMenuItem RedoAction = new JMenuItem("Redo");
        JMenuItem clearAction = new JMenuItem("Clear");
        JMenuItem saveAction = new JMenuItem("Save");
        JMenuItem exportAction = new JMenuItem("Export");
        JMenuItem printAction = new JMenuItem("Print");
        JMenuItem ConvertAction = new JMenuItem("Convert To Tables");
        JMenuItem ColorAction = new JMenuItem("Color Picker");
        JMenuItem ZoomAction = new JMenuItem("Zoom");
        JMenuItem EntityAction = new JMenuItem("Entity & Attributes");
        JMenuItem RelationshipAction = new JMenuItem("Relationship Attributes");
        JMenuItem HelpAction = new JMenuItem("Help");
        JMenuItem AboutAction = new JMenuItem("About");

        fileMenu.add(newAction);
        fileMenu.addSeparator();
        fileMenu.add(openAction);
        fileMenu.addSeparator();
        fileMenu.add(saveAction);
        fileMenu.addSeparator();
        fileMenu.add(exportAction);
        fileMenu.addSeparator();
        fileMenu.add(printAction);
        fileMenu.addSeparator();
        fileMenu.add(exitAction);

        editMenu.add(UndoAction);
        editMenu.addSeparator();
        editMenu.add(RedoAction);
        editMenu.addSeparator();
        editMenu.add(cutAction);
        editMenu.addSeparator();
        editMenu.add(copyAction);
        editMenu.addSeparator();
        editMenu.add(pasteAction);
        editMenu.addSeparator();
        editMenu.add(clearAction);

        dbMenu.add(ConvertAction);

        ToolsMenu.add(ColorAction);
        ToolsMenu.addSeparator();
        ToolsMenu.add(ZoomAction);
        ToolsMenu.addSeparator();
        ToolsMenu.add(EntityAction);
        ToolsMenu.addSeparator();
        ToolsMenu.add(RelationshipAction);

        HelpMenu.add(HelpAction);
        HelpMenu.addSeparator();
        HelpMenu.add(AboutAction);
        
        
        exitAction.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
               
        }}
        );
        
        
        
        
        
        
        ConvertAction.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                
               new ConvertForm().setVisible(true);
                
                
               
        }}
        );
        
        
        

        newAction.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                new Lesson49_1().setVisible(true);
            }
        });
        
        

        JPanel buttonPanel = new JPanel();
       
        JPanel FieldPanel = new JPanel();

        // Swing box that will hold all the buttons

        Box theBox = Box.createVerticalBox();
        Box theBoxs = Box.createVerticalBox();

        // Make all the buttons in makeMeButtons by passing the
        // button icon.

        
        lineBut = makeMeButtons("./src/line.png", 2);
        ellipseBut = makeMeButtons("./src/ellipse.png", 3);
        rectBut = makeMeButtons("./src/rectangle.png", 4);

        // Make all the buttons in makeMeColorButton by passing the
        // button icon and true for stroke color or false for fill

        strokeBut = makeMeColorButton("./src/stroke.png", 5, true);


        // Add the fields to the boxs

        

        //theBox.add(brushBut);
        theBox.add(lineBut);
        theBox.add(ellipseBut);
        theBox.add(rectBut);
        theBox.add(strokeBut);
       
        buttonPanel.add(theBox);
        FieldPanel.add(theBoxs);
        

        this.add(buttonPanel, BorderLayout.WEST);
        this.add(FieldPanel, BorderLayout.EAST);
        buttonPanel.setPreferredSize(new Dimension(200,480));        
        FieldPanel.setPreferredSize(new Dimension(200,480));
        // Make the drawing area take up the rest of the frame

        // this.add(new DrawingBoard(), BorderLayout.CENTER);
        final DrawingBoard drawPanel = new DrawingBoard();
        this.add(drawPanel, BorderLayout.CENTER);
        this.getContentPane().setBackground(Color.WHITE);

        
        
        
        
        
        exportAction.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent arg0) {
                BufferedImage image = new BufferedImage(drawPanel.getWidth(),
                        drawPanel.getHeight(), BufferedImage.TYPE_INT_ARGB);
                Graphics2D g = image.createGraphics();
                drawPanel.paint(g);
                g.dispose();

                JFileChooser fileChooser = new JFileChooser();
                File theDirectory = new File("C:/Users/Wenda/Desktop");
                fileChooser.setCurrentDirectory(theDirectory);
                FileNameExtensionFilter pngFilter = new FileNameExtensionFilter(
                        "PNG file (*.png)", "png");
                fileChooser.addChoosableFileFilter(pngFilter);
                fileChooser.setFileFilter(pngFilter);

                int status = fileChooser.showSaveDialog(Lesson49_1.this);

                if (status == JFileChooser.APPROVE_OPTION) {
                    try {
                        ImageIO.write(image, "png",
                                fileChooser.getSelectedFile());
                        JOptionPane.showMessageDialog(null, "Image saved to "
                                + fileChooser.getSelectedFile().getName());
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
        });
        // Show the frame
        this.setVisible(true);
    }

    public JButton makeMeButtons(String iconFile, final int actionNum) {
        JButton theBut = new JButton();
        Icon butIcon = new ImageIcon(iconFile);
        theBut.setIcon(butIcon);

         theBut.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                currentAction = actionNum;
            }
        });
        return theBut;
    }

    // Spits out buttons based on the image supplied and
    // whether a stroke or fill is to be defined

    public JButton makeMeColorButton(String iconFile, final int actionNum,
            final boolean stroke) {
        JButton theBut = new JButton();
        Icon butIcon = new ImageIcon(iconFile);
        theBut.setIcon(butIcon);

        theBut.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                if (stroke) {

                    // JColorChooser is a popup that lets you pick a color

                    strokeColor = JColorChooser.showDialog(null,
                            "Pick a Stroke", Color.BLACK);
                } else {
                                    }
            }
        });

        return theBut;
    }
    public class DrawingBoard extends JComponent {

        private static final long serialVersionUID = -4431176095451940075L;

        // ArrayLists that contain each shape drawn along with
        // that shapes stroke and fill
        ArrayList<Shape> shapes = new ArrayList<Shape>();
        ArrayList<Color> shapeStroke = new ArrayList<Color>();
        
        Point drawStart, drawEnd;
        // Monitors events on the drawing area of the frame

        public DrawingBoard() {

            this.addMouseListener(new MouseAdapter() {

                public void mousePressed(MouseEvent e) {

                    if (currentAction != 1) {

                        // When the mouse is pressed get x & y position

                        drawStart = new Point(e.getX(), e.getY());
                        drawEnd = drawStart;
                        repaint();
                    }
                }
            
                public void mouseReleased(MouseEvent e) {

                    if (currentAction != 1) {
                        Shape aShape = null;
                        
                        if (currentAction == 2) {
                            aShape = drawLine(drawStart.x, drawStart.y,
                            e.getX(), e.getY());
                            shapes.add(aShape);
                            shapeStroke.add(strokeColor);
                            drawStart = null;
                            drawEnd = null;
                            repaint();
                        } else

                        if (currentAction == 3) {
                            aShape = drawEllipse(drawStart.x, drawStart.y,
                             e.getX(), e.getY());
                            shapes.add(aShape);
                            shapeStroke.add(strokeColor);
                            drawStart = null;
                            drawEnd = null;
                            repaint();
                            new AttributeForm().setVisible(true);
                        } else

                        if (currentAction == 4) {

                            // Create a new rectangle using x & y coordinates

                            aShape = drawRectangle(drawStart.x, drawStart.y,
                            e.getX(), e.getY());
                            shapes.add(aShape);
                            shapeStroke.add(strokeColor);
                            drawStart = null;
                            drawEnd = null;
                            repaint();
                            new EntityForm().setVisible(true);
                        }

                        // Add shapes, fills and colors to there ArrayLists

                                              

                    }

                }
            });
            
              this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent me) {
                JTextField name = new JTextField(15);
                super.mouseClicked(me);
                for (Shape s : shapes) {

                    if (s.contains(me.getPoint())) {//check if mouse is clicked within shape

                        //we can either just print out the object class name
                        System.out.println("Clicked a "+s.getClass().getName());

                        //or check the shape class we are dealing with using instance of with nested if
                        if (s instanceof Rectangle2D) {
                            
                            //create table  
                            
                        } 
                         else if (s instanceof Ellipse2D) {
                            
                           
                             
                            
                            
                            
                        }

                    }
                }
            }
        });

            this.addMouseMotionListener(new MouseMotionAdapter() {

                public void mouseDragged(MouseEvent e) {

                    // If this is a brush have shapes go on the screen quickly

                    if (currentAction == 1) {

                        int x = e.getX();
                        int y = e.getY();

                        Shape aShape = null;
                        shapes.add(aShape);

                        shapeStroke.add(strokeColor);

                        // Add the transparency value
                    }

                    // Get the final x & y position after the mouse is dragged

                    drawEnd = new Point(e.getX(), e.getY());
                    repaint();
                }
            });
        }

        public void paint(Graphics g) {
            // Class used to define the shapes to be drawn

            graphSettings = (Graphics2D) g;

            // Antialiasing cleans up the jagged lines and defines rendering
            // rules

            graphSettings.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);

            // Defines the line width of the stroke

            graphSettings.setStroke(new BasicStroke(4));

            // Iterators created to cycle through strokes and fills
            Iterator<Color> strokeCounter = shapeStroke.iterator();
            for (Shape s : shapes) {
 
                // Grabs the next stroke from the color arraylist
                graphSettings.setPaint(strokeCounter.next());

                graphSettings.draw(s);

            }

            // Guide shape used for drawing
            if (drawStart != null && drawEnd != null) {
                // Makes the guide shape transparent

                graphSettings.setComposite(AlphaComposite.getInstance(
                        AlphaComposite.SRC_OVER, 0.40f));

                // Make guide shape gray for professional look

                graphSettings.setPaint(Color.LIGHT_GRAY);

                Shape aShape = null;

                if (currentAction == 2) {
                    aShape = drawLine(drawStart.x, drawStart.y, drawEnd.x,
                            drawEnd.y);
                } else

                if (currentAction == 3) {
                    aShape = drawEllipse(drawStart.x, drawStart.y, drawEnd.x,
                            drawEnd.y);
                } else

                if (currentAction == 4) {

                    // Create a new rectangle using x & y coordinates

                    aShape = drawRectangle(drawStart.x, drawStart.y, drawEnd.x,
                            drawEnd.y);
                }

                graphSettings.draw(aShape);
            }
        }

    
        private Rectangle2D.Float drawRectangle(int x1, int y1, int x2, int y2) {
            // Get the top left hand corner for the shape
            // Math.min returns the points closest to 0

            int x = Math.min(x1, x2);
            int y = Math.min(y1, y2);

            // Gets the difference between the coordinates and

            int width = Math.abs(x1 - x2);
            int height = Math.abs(y1 - y2);

            return new Rectangle2D.Float(x, y, width, height);
        }

           private Ellipse2D.Float drawEllipse(int x1, int y1, int x2, int y2) {
            int x = Math.min(x1, x2);
            int y = Math.min(y1, y2);
            int width = Math.abs(x1 - x2);
            int height = Math.abs(y1 - y2);

            return new Ellipse2D.Float(x, y, width, height);
        }

        private Line2D.Float drawLine(int x1, int y1, int x2, int y2) {

            return new Line2D.Float(x1, y1, x2, y2);
        }
           }
    
    }
    

Can someone please help me out?

Lana
  • 171
  • 1
  • 7
  • 18
  • Is it possible that an object will be linked to many objects? – Anil Feb 17 '15 at 19:06
  • All you need to do is check for the bounds of the objects. Say we have two shapes s1 and s2. If s1.maxRight > s2.minLeft AND (s1.maxbottom > s2.maxbottom OR s1.minTop < s2.minTop)... you two objects will be intersected. – gran_profaci Feb 17 '15 at 19:09
  • You could try something like [this](http://stackoverflow.com/questions/20927189/detecting-collision-of-two-sprites-that-can-rotate/20928531#20928531) – MadProgrammer Feb 17 '15 at 20:53
  • Why not just simply maintain a virtual linkage between the objects? – MadProgrammer Feb 18 '15 at 03:39
  • @Anil Yes an object can be linked to many objects – Lana Feb 24 '15 at 05:55
  • @MadProgrammer What do you mean by "maintain a virtual linkage between the objects"? – Lana Feb 27 '15 at 08:01
  • I was thinking more along the lines that you maintain some kind map or relationship between the objects, rather then trying to determine if some line intersects the objects... – MadProgrammer Feb 27 '15 at 08:11
  • Thank you for your reply. How can i do this? Do you have any idea.. suggestions? @MadProgrammer – Lana Feb 27 '15 at 09:25

1 Answers1

0

There are two cases.

  1. Based on what you've shown it seems that if a line is linked to your ellipse, it is only linked in the center of the top or it might be on the center of a side, and we can see that if your line intersects your ellipse on the center of a side, then you can consider the ellipse as a rectangle. And then in java you could use
    Rectangle yourLine = new Rectangle(line.x, line.y, line.width, line.height); Rectangle ellipse = new Rectangle(ellipse.upperLeft.x, ellipse.upperLeft.y, ellipse.width, ellipse.height); boolean isThereAnIntersection = yourLine.intersects(ellipse);

  2. For a generic method, while working on complex shapes, you might use a BufferedImage as a buffer of your drawings then display the BufferedImagein your paint(Graphics g)method. By using this BufferedImageto draw your ellipse and lines you might be able to directly check if the bounds of a line will be drawn over colored pixels or background pixels, which means if drawn over colored pixels that there is already an object drawn at the location, so you would finally have to get the object depending on its location.

µTheory
  • 178
  • 10
  • From memory, interests use the shapes bounding box, which might give false positives for non-rectangular shapes, but that depends on your definition of intersection – MadProgrammer Feb 17 '15 at 20:54
  • How can i make java detect whether it's a colored pixels or a background pixels? – Lana Mar 02 '15 at 06:29
  • @LanaM Your problem is different you might be looking for "per pixel perfect collision detection" there a lot of answered questions answered you just need to do a quick search ;) – µTheory Mar 03 '15 at 14:57
  • @µTheory Thank you so much for your response, in fact, i was able to do the collision after many more search. But now i'm stuck on this: http://stackoverflow.com/questions/28834766/how-can-i-split-an-arraylist-of-shapes-into-partitions-lists-in-java-just-advic Can you please just take a small time and advice me? – Lana Mar 03 '15 at 15:22