Hello, I've looked all over the web and can't seem to find how to do this, so I'll try here.

I'm working in a program in which i need to draw shapes, specifically irregular polygons. I figured the easiest way to do this, and the one that makes the most sense, is to simply get the points from mouse clicks, and add those points to an array or arrayList, and put those into the polygon class. But, i can't seem to get more than 1 point at a time from a mouse listener inside a class. Is there a way to do this? Keep in mind i can't do it for a set number of points, but will know the number of points when it executes (i.e. The user specifies they want 5 sides through a input window.

Recommended Answers

All 13 Replies

You should get one mouse event for each click. What exactly is happening? Post the relevant code so we can have look - it may be something else (eg re-initialising the array each time the listener is called).

This is my latest attempt at the program. All methods that reference other classes work, or are not implemented yet.

package vectorGraphics;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Point2D;
import java.util.ArrayList;

import javax.swing.JFrame;

/**
 * TODO Put here a description of what this class does.
 *
 * @author kleinnj.
 *         Created Feb 8, 2011.
 */
public class IrregularPolygon extends AbstractPolygon{
	
	
	
	private int[] xPoints;
	private int[] yPoints;
	private int nSides;
	private VectorGraphicsComponent vgc;
	private Color borderColor;
	private Color fillColor;
	private  ArrayList<Point2D> points = new ArrayList<Point2D>();
	private static JFrame frame;
	private Polygon poly;

	static Point2D point;
	
	
	/**
	 * TODO Put here a description of what this constructor does.
	 *
	 * @param nSides
	 * @param vgc
	 * @param borderColor
	 * @param fillColor
	 * @param frame
	 */
	public IrregularPolygon(int nSides,VectorGraphicsComponent vgc, Color borderColor, Color fillColor, JFrame frame ){
		this.nSides = nSides;
		this.vgc = vgc;
		this.borderColor = borderColor;
		this.fillColor= fillColor;
		IrregularPolygon.frame = frame;
		int count =0;
		while(count < this.nSides){
			Point2D point = nextPoint();
			if (point != null){
				System.out.println("got it");
				this.points.add(nextPoint());
				count++;
			}
			
		}
			

	
			
		
	int j =0;
		for (Point2D p : this.points) {
				
				this.xPoints[j] = (int) p.getX();
				this.yPoints[j] = (int) p.getY();
				j++;
		}
		this.poly = new Polygon(this.xPoints, this.yPoints, this.nSides);
		vgc.shapes.add(this);
		vgc.repaint();
		}
		
		
		
		
	@Override
	public void resize(int newLineSize) {
		//may not be possible.
	}
	@Override
	public Point2D getCenter() {
		// TODO Auto-generated method stub.
		return null;
	}
	
	/**
	 * TODO Put here a description of what this method does.
	 *
	 * @return
	 */
	public Point2D nextPoint(){
		 IrregularPolygon.point = null;
		MouseListener getPoint = new MouseListener() {
			
			
			@Override
			public void mouseReleased(MouseEvent arg0) {
				// TODO Auto-generated method stub.
				
			}
			
			@Override
			public void mousePressed(MouseEvent arg0) {
				// TODO Auto-generated method stub.
				
			}
			
			@Override
			public void mouseExited(MouseEvent arg0) {
				// TODO Auto-generated method stub.
				
			}
			
			@Override
			public void mouseEntered(MouseEvent arg0) {
				// TODO Auto-generated method stub.
				
			}
			
			@Override
			public void mouseClicked(MouseEvent arg0) {
				IrregularPolygon.point = arg0.getPoint();
				System.out.println("got it");	
			}
		};
		IrregularPolygon.frame.addMouseListener(getPoint);
	
		
		return IrregularPolygon.point;
	}




	@Override
	public void duplicate() {
		// TODO Auto-generated method stub.
		
	}




	@Override
	public double getAngle() {
		// TODO Auto-generated method stub.
		return 0;
	}




	@Override
	public void moveTo(Point2D point) {
		// TODO Auto-generated method stub.
		
	}




	@Override
	public void setAngle(double angleInDegrees) {
		// TODO Auto-generated method stub.
		
	}

}

I don't understand why you are making a new MouseListener for each point. That's certainly not a normal way to proceed. I would just have one listener, initialised when the frame is ready to accept a polygon's worth of clicks. All it needs to do is add the points to an ArrayList of Points (ps why separate arrays for x and y???) until they have all been entered.

I don't understand why you are making a new MouseListener for each point. That's certainly not a normal way to proceed. I would just have one listener, initialised when the frame is ready to accept a polygon's worth of clicks. All it needs to do is add the points to an ArrayList of Points (ps why separate arrays for x and y???) until they have all been entered.

the separate arrays for x and y are for the polygon class. It takes an array of X points and and array of Y points. I could just add each point, but this way i have the set of right away. I can try to add the mouse listener in the class that calls the constructor for Irregular polygon, and pass an array of points instead, but how do i make the program wait until it has the right amount of points? wouldn't it just get 1 and call the constructor normally, or not wait at all?

how do i make the program wait until it has the right amount of points? wouldn't it just get 1 and call the constructor normally, or not wait at all

This is a very important question! We all start out thinking in purely procedural terms - joined-up thinking - "I'll start a method that gets 5 points, processes them, and finishes" but GUI apps just don't hang together that way. You have to structure them as a series of steps/methods that get called by the events in the GUI. In this case something like:
Method 1: get number of points, start the mouse listener
Method 2: called by mouse events: add point. If all points are entered remove listener, call method 3.
Method 3: Process the complete set of points collected by Method 2.

It can take a bit of brain battering to get the hang of this kind of split-up logic, where the waits are implicit rather than explicit, but once you get the hang of it it becomes natural. Either way, you need to master it because that's how asynchronous programs (of which GUIs are a subset) are written.

This is a very important question! We all start out thinking in purely procedural terms - joined-up thinking - "I'll start a method that gets 5 points, processes them, and finishes" but GUI apps just don't hang together that way. You have to structure them as a series of steps/methods that get called by the events in the GUI. In this case something like:
Method 1: get number of points, start the mouse listener
Method 2: called by mouse events: add point. If all points are entered remove listener, call method 3.
Method 3: Process the complete set of points collected by Method 2.

It can take a bit of brain battering to get the hang of this kind of split-up logic, where the waits are implicit rather than explicit, but once you get the hang of it it becomes natural. Either way, you need to master it because that's how asynchronous programs (of which GUIs are a subset) are written.

Alright. But what would the syntax be.

public void newIrregularPolygon() {
		intFrame.setTitle("New Irregular Polygon");

		SpinnerModel model = new SpinnerNumberModel(3, 0, 10000, 1);
		SpinnerModel model2 = new SpinnerNumberModel(50, 0, 10000, 1);

		numberChooser1 = new JSpinner(model);
		numberChooser2 = new JSpinner(model2);

		JLabel width1 = new JLabel("Number of Sides");
		JLabel height1 = new JLabel("Side length");

		JPanel panel = new JPanel();
		panel.add(width1, BorderLayout.NORTH);
		panel.add(numberChooser1);
		panel.add(height1, BorderLayout.NORTH);
		panel.add(numberChooser2);

		intFrame.add(panel, BorderLayout.NORTH);
		ActionListener listener = new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				String widthString = numberChooser1.getValue().toString();
				width = Integer.parseInt(widthString);

				String heightString = numberChooser2.getValue().toString();
				height = Integer.parseInt(heightString);

				intFrame.dispose();
				NewShapeDialog.color = NewShapeDialog.colorChooser.getColor();
				NewShapeDialog.colorChooser.setColor(Color.red);

				NewShapeDialog.borderColor = NewShapeDialog.colorChooser2
						.getColor();

				MouseListener getMouse = new MouseListener() {
					Point2D[] points = new Point2D[width];
					@Override
					public void mouseReleased(MouseEvent arg0) {
						// not needed

					}

					@Override
					public void mousePressed(MouseEvent arg0) {
						// not needed

					}

					@Override
					public void mouseExited(MouseEvent arg0) {
						// not needed

					}

					@Override
					public void mouseEntered(MouseEvent arg0) {
						// not needed

					}

					@Override
					public void mouseClicked(MouseEvent arg0) {
						while(arg0.getClickCount() <=width){
							points[arg0.getClickCount()-1] = arg0.getPoint();
						}
						
						arg0.getY() - 50);
						
						new IrregularPolygon(points,
								VectorGraphicsGUI.getComponent(), color,
								borderColor, frame);
						frame.removeMouseListener(this);

					}
				};
				frame.addMouseListener(getMouse);
			}
		};

		this.ok.addActionListener(listener);

I tried this in the GUI call to irregular polygon, but it didnt work.

I guess you didn't read my post. OK, that's your privilege. Anyway "what's the syntax" sounds like a request to write the code for you.

OK, I'm in a better mood now. Sorry if the previous post was a bit harsh. Anyway, as I said in before, structure it in 3 methods. You're not going to get any kind of sensible implementation in a single method, even if it has event handlers embedded.

OK, I'm in a better mood now. Sorry if the previous post was a bit harsh. Anyway, as I said in before, structure it in 3 methods. You're not going to get any kind of sensible implementation in a single method, even if it has event handlers embedded.

I understood the 3 methods, but in the second method that gets the points, how do I make the program wait until i have the points, and also make sure that it doesn't add the same point more than once? I suppose i could compare the last element of the array with the new mouse click, but I still don't know how to make it wait, while still accepting input.

I've been fooling around with this on my own since my alst post, but even when trying to do it in 3 methods it does not work. I call the second method with the mouse click, adding that point to the array. tje second method gets the array, and the mouse event.

Problem:
How do i get the method to wait until it has all the points while still accepting input? I am looking for methods or classes to use, and ideally an example so i can see how to implement them properly.

Like I said earlier... "the waits are implicit rather than explicit". Please just try doing what I suggested - it really does work.

Like I said earlier... "the waits are implicit rather than explicit". Please just try doing what I suggested - it really does work.

But what does that mean? does that mean i don't have to use something to make it wait, because i tried that and the program crashed.

Method 1: get number of points, start the mouse listener
Method 2: called by mouse events: add point. If all points are entered remove listener, call method 3.
Method 3: Process the complete set of points collected by Method 2.

None of these methods has a wait.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.