使用鼠标移动侦听器绘制线条

时间:2012-02-18 23:44:33

标签: java swing graphics line mouseevent

我是使用actionListenermouselistner的新手。我想跟踪鼠标移动并在我走的时候连接点。所以这将是一条连续的路线。每次我在屏幕上移动鼠标并获得一组新的点时,我都在使用MouseMotionListener。我没有使用mousePressedmouseReleased

每当我移动鼠标时,我都可以看到我的鼠标位置在JPanel上的每个点都显示在我的结果窗口上,但是为了画出两点之间的线,我不是确定如何在每个不同的点集之间进行解密,以便我可以使用一组开始和结束点来绘制线条?我查看了这里和API,我被卡住了。

我被要求添加更多代码,所以我给了你我的代码。

我基本上创建了一个Jpane,可以在按下跟踪鼠标按钮或绘制轨迹单选按钮时跟踪鼠标移动 这些结果将在输出屏幕上打印为(x,y)

仅供参考:一旦绘制圆圈选中RadioButton,您也可以绘制圆圈

Jpanel Output

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;
}
}

2 个答案:

答案 0 :(得分:3)

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();
         }
      });
   }
}

编辑:示例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();
         }
      });
   }
}

答案 1 :(得分:3)

您只需要在类的某个属性中保存x和y(如lastX和lastY。)当您第二次获得该事件时,您的第一个点坐标将保存在您的属性中,然后您可以绘制您的线。这个新点也必须保存,作为你的新lastX和lastY。

更好:因为您可能需要每帧重绘一行(如果您想要一组线而不是每帧都绘制一条线),请使用Point来保存您的坐标和某种类似ArrayList的列表。将全部跟踪点保存在ArrayList<Point>中,然后绘制每个帧迭代此列表。