|
Prev: Timer Schedule TimerTask for same hour every day
Next: Sun's jdk, hibernate, jboss and log4j code quality
From: RichT on 29 Jun 2008 12:02 Hi all once again :) This question is really of two parts. part one I am constructing an arrow using a line as the tail of the arrow and a filled polygon for the arrow head which is an array of three pairs of x, y points used to construct the arrow. an example of this arrow may look something like this |\ -----------------| \ |/ So my first question is how can I create some sort of bounding shape around this shape so that when I click on any part of the arrow it becomes selected, or if this will prove too hard just clicking the arrow head to select the shape. What I ideally would like is once the mouse pointer is clicked on the arrow little selection handles would be drawn at the x0 of the line segment and at each point of the points of the arrow head perhaps using a 3x3 filled rectangle as each handle. I think I know how to create and position these handles as I have a reference to the necessary x0,y0,x1,y1 points of the arrow tail and each of the vertices of the arrowhead. Part two is related I believe to part one as once I have figured out how to bound the arrow shape, I want to be able to detect if I click on this shape with the left or right mouse button. I believe I can do this by using the if rectangle.contains(Point) Method???? but not too sure?, a better way if it exists would be to check if the object under the mouse pointer when clicked is a type of a class. I will include the code for constructing the arrow below, in case my explanation is not too clear. Hope someone can help or point me in the right direction Rich Code below. import java.awt.Graphics; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.util.ArrayList; import javax.swing.JFrame; import javax.swing.JPanel; public class ArrowPanel extends JPanel { FixedHeadArrow arrow; ArrayList<FixedHeadArrow> arrowList = new ArrayList<FixedHeadArrow>(); public ArrowPanel() { addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { arrow = new FixedHeadArrow(); arrow.x0 = e.getX(); arrow.y0 = e.getY(); arrow.x1 = arrow.x0; arrow.y1 = arrow.y0; arrowList.add(arrow); } @Override public void mouseReleased(MouseEvent e) { arrow.x1 = e.getX(); arrow.y1 = e.getY(); } }); addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseDragged(MouseEvent e) { arrow.x1 = e.getX(); arrow.y1 = e.getY(); repaint(); } }); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); for (FixedHeadArrow fha : arrowList) { fha.draw(g); } } public static void main(String[] args) { ArrowPanel arrowPanel = new ArrowPanel(); JFrame f = new JFrame(); f.add(arrowPanel); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(400, 400); f.setLocationRelativeTo(null); // centre f.setVisible(true); } public class FixedHeadArrow { private static final double HEAD_LENGTH = 10; private static final double HEAD_WIDTH = 5; // actually half the width private static final double TAN = HEAD_WIDTH / HEAD_LENGTH; int x0; int y0; int x1; int y1; private int xHeadPoints[] = new int[3]; private int yHeadPoints[] = new int[3]; public void draw(Graphics g) { int dx = x1 - x0; int dy = y1 - y0; double lineLength = Math.sqrt(dx * dx + dy * dy); double ratio = HEAD_LENGTH / lineLength; xHeadPoints[0] = x0 + (int) Math.round((1 - ratio) * dx + (ratio * dy) * TAN); yHeadPoints[0] = y0 + (int) Math.round((1 - ratio) * dy - (ratio * dx) * TAN); xHeadPoints[1] = x0 + (int) Math.round((1 - ratio) * dx - (ratio * dy) * TAN); yHeadPoints[1] = y0 + (int) Math.round((1 - ratio) * dy + (ratio * dx) * TAN); // 3rd point of arrow head is line end xHeadPoints[2] = x1; yHeadPoints[2] = y1; g.drawLine(x0, y0, x1, y1); g.fillPolygon(xHeadPoints, yHeadPoints, 3); for (int x = 0; x < xHeadPoints.length; ++x) { System.out.println("x Point: " + xHeadPoints[x] + " y Points: " + yHeadPoints[x]); } } } }
From: Knute Johnson on 29 Jun 2008 20:00 RichT wrote: > Hi all once again :) > > This question is really of two parts. > > part one > I am constructing an arrow using a line as the tail of the arrow and a > filled polygon for the arrow head which is an array of three pairs of > x, y points used to construct the arrow. > > an example of this arrow may look something like this > |\ > -----------------| \ > |/ > > So my first question is how can I create some sort of bounding shape > around this shape so that when I click on any part of the arrow it > becomes selected, or if this will prove too hard just clicking the arrow > head to select the shape. > > What I ideally would like is once the mouse pointer is clicked on the > arrow little selection handles would be drawn at the x0 of the line > segment and at each point of the points of the arrow head perhaps using > a 3x3 filled rectangle as each handle. > > I think I know how to create and position these handles as I have a > reference to the necessary x0,y0,x1,y1 points of the arrow tail and each > of the vertices of the arrowhead. > > Part two is related I believe to part one as once I have figured out how > to bound the arrow shape, I want to be able to detect if I click on this > shape with the left or right mouse button. > > I believe I can do this by using the if rectangle.contains(Point) > Method???? but not too sure?, a better way if it exists would be to > check if the object under the mouse pointer when clicked is a type of a > class. > > I will include the code for constructing the arrow below, in case my > explanation is not too clear. > > Hope someone can help or point me in the right direction > > Rich > > Code below. > > import java.awt.Graphics; > import java.awt.event.MouseAdapter; > import java.awt.event.MouseEvent; > import java.awt.event.MouseMotionAdapter; > import java.util.ArrayList; > > import javax.swing.JFrame; > import javax.swing.JPanel; > > public class ArrowPanel extends JPanel { > > FixedHeadArrow arrow; > ArrayList<FixedHeadArrow> arrowList = new ArrayList<FixedHeadArrow>(); > > public ArrowPanel() { > addMouseListener(new MouseAdapter() { > > @Override > public void mousePressed(MouseEvent e) { > arrow = new FixedHeadArrow(); > arrow.x0 = e.getX(); > arrow.y0 = e.getY(); > arrow.x1 = arrow.x0; > arrow.y1 = arrow.y0; > arrowList.add(arrow); > } > > @Override > public void mouseReleased(MouseEvent e) { > arrow.x1 = e.getX(); > arrow.y1 = e.getY(); > > } > }); > addMouseMotionListener(new MouseMotionAdapter() { > @Override > public void mouseDragged(MouseEvent e) { > arrow.x1 = e.getX(); > arrow.y1 = e.getY(); > repaint(); > } > }); > } > > @Override > public void paintComponent(Graphics g) { > super.paintComponent(g); > for (FixedHeadArrow fha : arrowList) { > fha.draw(g); > } > } > > public static void main(String[] args) { > ArrowPanel arrowPanel = new ArrowPanel(); > JFrame f = new JFrame(); > f.add(arrowPanel); > f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); > f.setSize(400, 400); > f.setLocationRelativeTo(null); // centre > f.setVisible(true); > } > > public class FixedHeadArrow { > private static final double HEAD_LENGTH = 10; > private static final double HEAD_WIDTH = 5; // actually half the > width > private static final double TAN = HEAD_WIDTH / HEAD_LENGTH; > int x0; > int y0; > int x1; > int y1; > private int xHeadPoints[] = new int[3]; > private int yHeadPoints[] = new int[3]; > > public void draw(Graphics g) { > int dx = x1 - x0; > int dy = y1 - y0; > double lineLength = Math.sqrt(dx * dx + dy * dy); > double ratio = HEAD_LENGTH / lineLength; > xHeadPoints[0] = x0 + (int) Math.round((1 - ratio) * dx + > (ratio * dy) * TAN); > yHeadPoints[0] = y0 + (int) Math.round((1 - ratio) * dy - > (ratio * dx) * TAN); > xHeadPoints[1] = x0 + (int) Math.round((1 - ratio) * dx - > (ratio * dy) * TAN); > yHeadPoints[1] = y0 + (int) Math.round((1 - ratio) * dy + > (ratio * dx) * TAN); > // 3rd point of arrow head is line end > xHeadPoints[2] = x1; > yHeadPoints[2] = y1; > g.drawLine(x0, y0, x1, y1); > g.fillPolygon(xHeadPoints, yHeadPoints, 3); > for (int x = 0; x < xHeadPoints.length; ++x) { > System.out.println("x Point: " + xHeadPoints[x] + " y > Points: " + yHeadPoints[x]); > } > } > } > } Here is a simple example, when you put the mouse over the shape it changes color. If you press the mouse when you are on the shape it changes to a unfilled polygon. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class test7 extends JPanel { int x[] = { 80,100,81,81,80,80,60,80 }; int y[] = { 40,60,60,120,120,60,60,40 }; Polygon poly = new Polygon(x,y,x.length); boolean fillFlag = true; boolean overFlag; public test7() { setPreferredSize(new Dimension(400,300)); // if mouse is clicked on poly, toggle fill flag addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent me) { if (poly.contains(me.getX(),me.getY())) { fillFlag = !fillFlag; repaint(); } } }); // if mouse is over poly change its color addMouseMotionListener(new MouseAdapter() { public void mouseMoved(MouseEvent me) { if (poly.contains(me.getX(),me.getY())) { overFlag = true; } else overFlag = false; repaint(); } }); } public void paintComponent(Graphics g2D) { Graphics2D g = (Graphics2D)g2D; g.setColor(Color.WHITE); g.fillRect(0,0,getWidth(),getHeight()); if (overFlag) g.setColor(Color.GREEN); else g.setColor(Color.RED); if (fillFlag) g.fillPolygon(poly); else g.drawPolygon(poly); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); test7 t7 = new test7(); f.add(t7,BorderLayout.CENTER); f.pack(); f.setVisible(true); } }); } } -- Knute Johnson email s/nospam/knute2008/ -- Posted via NewsDemon.com - Premium Uncensored Newsgroup Service ------->>>>>>http://www.NewsDemon.com<<<<<<------ Unlimited Access, Anonymous Accounts, Uncensored Broadband Access
From: RichT on 30 Jun 2008 17:56 > Here is a simple example, when you put the mouse over the shape it > changes color. If you press the mouse when you are on the shape it > changes to a unfilled polygon. Thanks Knute, I didn't know there was a poly.contains method in java, saves doing a bounding rect to detect mouse pointer. I am struggling to place handles at correct place on each of the three points on the arrow head, ideally having one of the handles edges central to an arrow head point something like the following []3 1[]/\[]2 The problem arises when calculating these points for the handles and the offsets when the arrow is drawn at an angle other than +-90 or +-180 degrees. at moment handle 1 is drawn at handle width + x as x offset handle 2 is drawn at handle 0,0 as offset handle 3 is drawn at handle x = point3 - handle width/2 and handle y + height. I am guessing that I need to offset the handle x,y relative to the angle of the line but seem to be guessing this incorrectly :( Thanks for your help so far Rich
From: Knute Johnson on 30 Jun 2008 20:19 RichT wrote: > >> Here is a simple example, when you put the mouse over the shape it >> changes color. If you press the mouse when you are on the shape it >> changes to a unfilled polygon. > > Thanks Knute, > > I didn't know there was a poly.contains method in java, saves doing a > bounding rect to detect mouse pointer. > > I am struggling to place handles at correct place on each of the three > points on the arrow head, ideally having one of the handles edges > central to an arrow head point something like the following > []3 > 1[]/\[]2 > > The problem arises when calculating these points for the handles and the > offsets when the arrow is drawn at an angle other than +-90 or +-180 > degrees. > > at moment > handle 1 is drawn at handle width + x as x offset > handle 2 is drawn at handle 0,0 as offset > handle 3 is drawn at handle x = point3 - handle width/2 and handle y + > height. > > I am guessing that I need to offset the handle x,y relative to the angle > of the line but seem to be guessing this incorrectly :( > > Thanks for your help so far > Rich Rich: Are these handles to rotate the arrow or just drag it around? -- Knute Johnson email s/nospam/knute2008/ -- Posted via NewsDemon.com - Premium Uncensored Newsgroup Service ------->>>>>>http://www.NewsDemon.com<<<<<<------ Unlimited Access, Anonymous Accounts, Uncensored Broadband Access
From: RichT on 1 Jul 2008 13:57
Knute Johnson wrote: > RichT wrote: >> >>> Here is a simple example, when you put the mouse over the shape it >>> changes color. If you press the mouse when you are on the shape it >>> changes to a unfilled polygon. >> >> Thanks Knute, >> >> I didn't know there was a poly.contains method in java, saves doing a >> bounding rect to detect mouse pointer. >> >> I am struggling to place handles at correct place on each of the three >> points on the arrow head, ideally having one of the handles edges >> central to an arrow head point something like the following >> []3 >> 1[]/\[]2 >> >> The problem arises when calculating these points for the handles and >> the offsets when the arrow is drawn at an angle other than +-90 or >> +-180 degrees. >> >> at moment >> handle 1 is drawn at handle width + x as x offset >> handle 2 is drawn at handle 0,0 as offset >> handle 3 is drawn at handle x = point3 - handle width/2 and handle y + >> height. >> >> I am guessing that I need to offset the handle x,y relative to the >> angle of the line but seem to be guessing this incorrectly :( >> >> Thanks for your help so far >> Rich > > Rich: > > Are these handles to rotate the arrow or just drag it around? > Hi Knute, The handles are to indicate the arrow is selected, while it is selected, dragging the arrow head rotates around the tail x0,y0 point (the line drawn from a point to the arrowhead), it is also possible to extend the length of the line by dragging the arrowhead and ideally I want to be able to move the arrow, line and all if the tail (line) is selected and dragged. Hope this info is useful? Rich |