简体   繁体   中英

Drawing a line using a Mouse Motion Listener

I'm new at using actionListener and mouselistner . I want to track the Mouse movements and connect the dots as I go. So it will be one continuous line. I am using the MouseMotionListener every time I move the mouse across the screen and get a new set of points. I am not using mousePressed or mouseReleased .

Everytime I move the mouse, I can get every point of where my mouse's position is on my JPanel to show up on my results window, but in order to draw the line between two points, I'm not sure how to decipher between each different set of points so I can have a beginning and ending set of points to use for drawing a line? I checked through here and the API and I'm stuck.

I was asked to put more code and so I gave you my code.

I am basically creating a Jpane that tracks mouse movement when the Track Mouse button or Draw Track Radio button is pressed These results will print out as (x,y) on the output screen

FYI: You can also draw circles once the Draw circles RadioButton is checked

的JPanel产量

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

public class MouseTest {

private JFrame frame;
private boolean tracking;
private boolean drawing;
private boolean connectdots;
private int xstart;             
private int ystart;             
private int xend;   
private int y;              
private int x;  
private int yend;               
private int borderWidth = 5;    
String drawCircles = "Draw Circles";
String drawTrack = "Draw Track";

public static void main (String [] arg) {
    MouseTest first = new MouseTest(); 
}//main

$

public MouseTest() {
    tracking = false; 
    frame = new JFrame(); 
    frame.setBounds(250,98,600,480);
    frame.setTitle("Window number three");
    Container cp = frame.getContentPane();
    JButton track = new JButton("Track Mouse");
    track.addActionListener(new ActionListener() {    

        public void actionPerformed(ActionEvent ae) {
            trackMouse();
        }
    });

    JPanel top = new JPanel();
    top.add(track);
    cp.add(top,BorderLayout.NORTH);

    MyPanel pane = new MyPanel();

    cp.add(pane,BorderLayout.CENTER);
    pane.addMouseListener(new MouseAdapter() {
        public void mousePressed(MouseEvent e) {
            xstart = e.getX();
            ystart = e.getY();
        }
        public void mouseReleased(MouseEvent e) {
            xend = e.getX();
            yend = e.getY();
            if (xend < xstart) { int tmp = xstart; xstart = xend; xend = tmp; } 
            if (yend < ystart) { int tmp = ystart; ystart = yend; yend = tmp; } 
            frame.repaint();
        }
    });
    pane.addMouseMotionListener(new MouseMotionAdapter() { 
        public void mouseMoved(MouseEvent e) { 
            if (tracking) { 
                x = e.getX();  
                y = e.getY();
                msg("(" + x + ", " + y + ")");
            }
        }
    });

    JRadioButton circleButton = new JRadioButton(drawCircles);
    circleButton.setMnemonic(KeyEvent.VK_B);
    circleButton.setActionCommand(drawCircles);
    circleButton.setSelected(false);

    JRadioButton trackButton = new JRadioButton(drawTrack);
    trackButton.setMnemonic(KeyEvent.VK_C);

    ButtonGroup group = new ButtonGroup();
    group.add(circleButton);
    group.add(trackButton);

    JPanel radioPanel = new JPanel(new GridLayout(2,0)); 
    radioPanel.add(circleButton);
    radioPanel.add(trackButton);    
    cp.add(radioPanel,BorderLayout.EAST);
    drawing = false;
    connectdots = false;

    circleButton.addActionListener(new ActionListener() { //Set drawing to true when the button is clicked
        public void actionPerformed(ActionEvent ae) {
            tracking = !tracking;
            drawCircles();
        }
    });

    trackButton.addActionListener(new ActionListener() { //Set drawing to true when the button is clicked
        public void actionPerformed(ActionEvent ae) {
            drawing = false;
            tracking = true;
            connectDots();
        }   
    });

    frame.setVisible(true);
}//constructor

$

public void trackMouse() {  
        tracking = !tracking;
}//trackMouse

public void msg(String s) { //new method to simplify the system.out.print method
    System.out.println(s);
}

public void drawCircles() { 
    drawing = true;

}//Allow Drawing of Circles

public void connectDots() { 
    connectdots = !connectdots;

}//Trying to use for connecting the mouse motion listener points when tracking

$

public class MyPanel extends JPanel {        

    ArrayList<Circle> circles = new ArrayList<Circle>();


public void paintComponent(Graphics g) {

    int width  = this.getWidth();
    int height = this.getHeight();

    msg("H = " + height + ",  w = " + width);
    g.setColor(Color.BLACK);
    Circle c = new Circle(xstart, ystart);   

    circles.add(c);
    if (drawing){  
        for(int k=0; k<circles.size(); k++){
            circles.get(k).draw(g);
        }
    }           // draw the circle

    if (connectdots && tracking) { //trying to use for drawing the lines
        g.drawLine(x,y,x,y);
    }

    for (int delta = 0; delta < borderWidth; delta++) {

        g.drawRect(delta,delta,width-(2*delta),height-(2*delta));

    }
    if (xstart != xend || ystart != yend) {    
        int red     = (int)(256*Math.random());
        int green   = (int)(256*Math.random());
        int blue    = (int)(256*Math.random());
        g.setColor(new Color(red, green, blue));
        msg("Colors are:  " + red + " - " + green + " - " + blue );
        msg("Drawing from: (" + xstart + ", " + ystart + ") to (" + xend + ", " + yend + ")");
        msg("Width is " + (xend-xstart) + " -  Height is " + (yend-ystart));
        g.fillRect(xstart,ystart,xend-xstart,yend-ystart);
    }

}
}
}

$

public class Circle {

// instance variables:
int radius;  //random radius
int x, y;  // coords of the center point
private Graphics g;


public Circle(int xIn, int yIn) {
    radius = (int)(127*Math.random());
    x = xIn;
    y = yIn;

}    

public void draw(Graphics g){
    g.drawOval(x-radius, y-radius, radius, radius);
    g.fillOval(x-radius, y-radius, radius, radius);
    int red     = (int)(256*Math.random());
    int green   = (int)(256*Math.random());
    int blue    = (int)(256*Math.random());
    g.setColor(new Color(red, green, blue));
}

public int getX(int xstart) {
    // TODO Auto-generated method stub
    return x;
}

public int getY(int ystart) {
    // TODO Auto-generated method stub
    return y;
}
}

An example of an sscce :

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

@SuppressWarnings("serial")
public class Foo3 extends JPanel {
   private static final int PREF_W = 400;
   private static final int PREF_H = PREF_W;
   private boolean tracking = false;
   private int x, y;

   public Foo3() {
      add(new JToggleButton(new AbstractAction("TrackMouse") {
         public void actionPerformed(ActionEvent ae) {
            trackMouse(ae);
         }
      }));

      MyMouseAdapter myMA = new MyMouseAdapter();
      addMouseMotionListener(myMA);
   }

   private void trackMouse(ActionEvent ae) {
      JToggleButton toggleBtn = (JToggleButton) ae.getSource();
      tracking = toggleBtn.isSelected();
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   public void msg(String message) {
      System.out.println(message);
   }

   private class MyMouseAdapter extends MouseAdapter {
      @Override
      public void mouseMoved(MouseEvent e) {
         if (tracking) { 
            x = e.getX();
            y = e.getY();
            msg("(" + x + ", " + y + ")");
         }
      }
   }

   private static void createAndShowGui() {
      Foo3 mainPanel = new Foo3();

      JFrame frame = new JFrame("MouseMotion Eg");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

Edit: Example 2

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.*;

@SuppressWarnings("serial")
public class MouseTestHovercraft extends JPanel {
   private static final int PREF_W = 600;
   private static final int PREF_H = PREF_W;
   private static final int MAX_CLR = 5;
   private static final Color CURRENT_LIST_COLOR = new Color(190, 190, 255);
   private List<Color> colors = new ArrayList<Color>();
   private boolean tracking = false;
   private List<Point> currentList = null;
   private BufferedImage bufferedImage = new BufferedImage(PREF_W, PREF_H,
         BufferedImage.TYPE_INT_ARGB);
   private Random random = new Random();

   public MouseTestHovercraft() {
      for (int redIndex = 0; redIndex < MAX_CLR; redIndex++) {
         int r = (redIndex * 256) / (MAX_CLR - 1);
         r = (r == 256) ? 255 : r;
         for (int greenIndex = 0; greenIndex < MAX_CLR; greenIndex++) {
            int g = (greenIndex * 256) / (MAX_CLR - 1);
            g = (g == 256) ? 255 : g;
            for (int blueIndex = 0; blueIndex < MAX_CLR; blueIndex++) {
               int b = (blueIndex * 256) / (MAX_CLR - 1);
               b = (b == 256) ? 255 : b;
               Color c = new Color(r, g, b);
               colors.add(c);
            }
         }
      }

      add(new JToggleButton(new AbstractAction("TrackMouse") {
         public void actionPerformed(ActionEvent ae) {
            trackMouse(ae);
         }
      }));
      add(new JButton(new AbstractAction("Clear Image") {
         public void actionPerformed(ActionEvent e) {
            bufferedImage = new BufferedImage(getWidth(), getHeight(),
                  BufferedImage.TYPE_INT_ARGB);
            repaint();
         }
      }));

      MyMouseAdapter myMA = new MyMouseAdapter();
      addMouseListener(myMA);
      addMouseMotionListener(myMA);
   }

   private void trackMouse(ActionEvent ae) {
      JToggleButton toggleBtn = (JToggleButton) ae.getSource();
      tracking = toggleBtn.isSelected();
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   public void msg(String message) {
      System.out.println(message);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawImage(bufferedImage, 0, 0, null);
      if (currentList != null) {
         drawList(g, currentList, CURRENT_LIST_COLOR, 1f);
      }
   }

   private void drawList(Graphics g, List<Point> ptList, Color color,
         float strokeWidth) {
      if (ptList.size() > 1) {
         Graphics2D g2 = (Graphics2D) g.create();
         g2.setColor(color);
         g2.setStroke(new BasicStroke(strokeWidth));
         for (int j = 0; j < ptList.size() - 1; j++) {
            int x1 = ptList.get(j).x;
            int y1 = ptList.get(j).y;
            int x2 = ptList.get(j + 1).x;
            int y2 = ptList.get(j + 1).y;
            g2.drawLine(x1, y1, x2, y2);
         }
         g2.dispose();
      }
   }

   private class MyMouseAdapter extends MouseAdapter {

      @Override
      public void mousePressed(MouseEvent e) {
         if (tracking && e.getButton() == MouseEvent.BUTTON1) {
            currentList = new ArrayList<Point>();
            currentList.add(e.getPoint());
         }
      }

      @Override
      public void mouseReleased(MouseEvent e) {
         if (tracking && e.getButton() == MouseEvent.BUTTON1) {
            currentList.add(e.getPoint());
            Graphics2D g2 = bufferedImage.createGraphics();
            Color color = colors.get(random.nextInt(colors.size()));
            drawList(g2, currentList, color, 3f);
            currentList = null;
            repaint();
         }
      }

      @Override
      public void mouseDragged(MouseEvent e) {
         if (tracking && currentList != null) {
            currentList.add(e.getPoint());
            repaint();
         }
      }
   }

   private static void createAndShowGui() {
      MouseTestHovercraft mainPanel = new MouseTestHovercraft();

      JFrame frame = new JFrame("MouseMotion Eg");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.setResizable(false);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

You just have to save x and y in some attribute for your class (like lastX and lastY.) When you get the event the second time, your first point coordinates are saved in your attributes and you can then draw your line. This new point has to be saved too to serve as your new lastX and lastY.

Even better: since you'll probably need to redraw your lines each frame (if you want a set of lines and not just a single line to be drawn each frame), use Point to save your coordinates and some kind of list like ArrayList . Save the full set of tracked points in an ArrayList<Point> and then draw each frame iterating over this list.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM