I'm trying to write a program that can create lines in a JPanel by clicking and dragging the mouse. That part I have down. The next thing I'm trying to do is create a perpendicular line to the line that I just drew by clicking randomly somewhere on the JPanel. So basically like this:
Untitled.jpg
If I were to click where that black dot was. It would draw the red line connecting to the black line and they would meet at a 90 degree angle (perpendicular).
I'm having trouble figuring out how to implement this into my program.
Here is my GUI class
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.util.ArrayList; import java.util.Random; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.border.BevelBorder; public class BasicLinePix extends JFrame { private JPanel drawingPanel; private JLabel statusLabel; private EventHandler eh; private Line myLine; private ArrayList<Line> storedLines = new ArrayList<Line>(); public static void main(String[] args) { // TODO Auto-generated method stub BasicLinePix lp = new BasicLinePix(); lp.setVisible(true); } public BasicLinePix() { setTitle("Basic Line Pix 1.0"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container cp = getContentPane(); cp.setLayout(new BorderLayout()); eh = new EventHandler(); drawingPanel = makeDrawingPanel(); drawingPanel.addMouseListener(eh); drawingPanel.addMouseMotionListener(eh); JPanel statusBar = createStatusBar(); cp.add(drawingPanel, BorderLayout.CENTER); cp.add(statusBar, BorderLayout.SOUTH); buildMenu(); pack(); } public void paint(Graphics g) { super.paint(g); Graphics gl = drawingPanel.getGraphics(); if(myLine != null) for(Line l : storedLines) l.draw(gl); } private void buildMenu() { JMenuBar menuBar = new JMenuBar(); JMenu fileMenu = buildFileMenu(); JMenu editMenu = buildEditMenu(); menuBar.add(fileMenu); menuBar.add(editMenu); setJMenuBar(menuBar); } private JMenu buildEditMenu() { JMenu editMenu = new JMenu("Edit"); JMenuItem menuItem = new JMenuItem("Cut"); editMenu.add(menuItem); return editMenu; } private JMenu buildFileMenu() { JMenu fileMenu = new JMenu("File"); JMenuItem menuItem = new JMenuItem("New"); menuItem.addActionListener(eh); fileMenu.add(menuItem); menuItem = new JMenuItem("Open"); fileMenu.add(menuItem); menuItem = new JMenuItem("Save"); fileMenu.add(menuItem); menuItem = new JMenuItem("Exit"); menuItem.addActionListener(eh); fileMenu.add(menuItem); return fileMenu; } private JPanel makeDrawingPanel() { // TODO Auto-generated method stub JPanel p = new JPanel(); p.setPreferredSize(new Dimension(500, 400)); p.setBackground(Color.YELLOW); return p; } private JPanel createStatusBar() { JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); statusLabel = new JLabel("No message"); panel.add(statusLabel, BorderLayout.CENTER); panel.setBorder(new BevelBorder(BevelBorder.LOWERED)); return panel; } private class EventHandler implements ActionListener, MouseListener, MouseMotionListener { private Point startPoint = null; // line's start point private Point endPoint = null; // line's most recent end point public void actionPerformed(ActionEvent arg0) { if (arg0.getActionCommand().equals("Exit")) { statusLabel.setText("Exiting program..."); System.exit(0); } else if (arg0.getActionCommand().equals("New")) { //clears the board of all lines storedLines.clear(); drawingPanel.removeAll(); drawingPanel.updateUI(); } } @Override public void mouseClicked(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent e) { if (e.isShiftDown()) { // record starting point for line startPoint = new Point(e.getX(), e.getY()); // initialize endPoint endPoint = startPoint; } if (e.isControlDown()) { Graphics g = drawingPanel.getGraphics(); //draw the perpendicular line } } @Override public void mouseReleased(MouseEvent e) { if (e.isShiftDown()) { //stores the line in an arrayList storedLines.add(myLine); startPoint = null; endPoint = null; } } @Override public void mouseDragged(MouseEvent e) { if (e.isShiftDown()) { // Implement rubber-band cursor Graphics g = drawingPanel.getGraphics(); g.setColor(Color.black); g.setXORMode(drawingPanel.getBackground()); // REDRAW the line that was drawn // most recently during this drag // XOR mode means that yellow pixels turn black // essentially erasing the existing line drawLine(g, startPoint, endPoint); // Update the end point of the line to current mouse position endPoint = new Point(e.getX(), e.getY()); // Draw line to current mouse position // XOR mode: yellow pixels become black // black pixels, like those from existing lines, temporarily // become // yellow drawLine(g, startPoint, endPoint); } } @Override public void mouseMoved(MouseEvent arg0) { // TODO Auto-generated method stub } private void drawLine(Graphics g, Point start, Point end) { if (startPoint != null && endPoint != null) { int startX = ((Double) start.getX()).intValue(); int startY = ((Double) start.getY()).intValue(); int endX = ((Double) end.getX()).intValue(); int endY = ((Double) end.getY()).intValue(); g.drawLine(startX, startY, endX, endY); } } } }
and here is my line classe
import java.awt.Graphics; import java.awt.Point; import java.util.ArrayList; public class Line { private Point startPoint, endPoint; double slope; double length; public Line(Point start, Point end) { startPoint = start; endPoint = end; } public double getSlope() { return slope; } public double getLength() { return length; } public void draw(Graphics g) { drawLine(g, startPoint, endPoint); } private void drawLine(Graphics g, Point start, Point end) { if (startPoint != null && endPoint != null) { int startX = ((Double) start.getX()).intValue(); int startY = ((Double) start.getY()).intValue(); int endX = ((Double) end.getX()).intValue(); int endY = ((Double) end.getY()).intValue(); g.drawLine(startX, startY, endX, endY); } } }
If anyone could lead me into the right direction that would be great. Thanks!