为什么我的mouseClicked()计数器递增2?

时间:2014-11-08 15:55:14

标签: java swing graphics mouseclick-event click-counting

我正在尝试计算mouseClicks,但我不明白为什么我的计数器每次点击都会增加2。试过getClickCount(),但它也不是我需要的。

我计算后的目标:我会使用计数器在不同的clickcount上绘制不同的东西。让我们说1st和2nd总是得到drawLine()的坐标,第三次点击就会得到drawRect()。

package graphics_training_painting;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JFrame;

public class U4 extends Canvas implements MouseListener{
    private int x1;
    private int y1;
    private int x2;
    private int y2;
    private int counter = 0;

    public U4() {
        setBackground(Color.white);
    }

    public static void main(String[] args) {
        U4 u = new U4();
        JFrame f = new JFrame();
        f.add(u);
        f.setSize(800, 600);
        f.setVisible(true);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        counter++;
        System.out.println(counter);
    }

    @Override
    public void mouseEntered(MouseEvent e) {


    }

    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mousePressed(MouseEvent e) {
/*      x1 = e.getX();
        y1 = e.getY();*/
    }

    @Override
    public void mouseReleased(MouseEvent e) {
/*      x2 = e.getX();
        y2 = e.getY();
        repaint();*/        
    }

    public void paint(Graphics g) {
        addMouseListener(this);
        g.setColor(Color.blue);
        g.drawLine(x1, y1, x2, y2);

    }   
}

非常感谢您的帮助或建议, 提米!

1 个答案:

答案 0 :(得分:4)

不要在paint方法中添加MouseListener!这将添加许多监听器,每个监听器在激活时递增计数器。

您需要知道您无法控制何时或是否将调用paint,并且在典型的程序运行期间可能会多次调用它。出于这个原因和其他原因,您不应该在此方法中放置程序逻辑,状态更改代码或组件创建。将MouseListener添加到一些初始化代码中,例如构造函数,称为一次

顺便说一句,你不会想要像你一样混合AWT和Swing组件。相反,你应该让你的U4类扩展JPanel,并用paintComponent方法进行绘图。

所以,改变一下:

public U4() {
    setBackground(Color.white);
}


// ...

public void paint(Graphics g) {
    addMouseListener(this);
    g.setColor(Color.blue);
    g.drawLine(x1, y1, x2, y2);
} 

到此:

public U4() {
    setBackground(Color.white);
    addMouseListener(this);
}


// ...

public void paint(Graphics g) {
    //  addMouseListener(this);
    super.paint(g); 
    g.setColor(Color.blue);
    g.drawLine(x1, y1, x2, y2);
} 

然后接下来,进行我推荐的更改

类似的东西:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.*;

public class U4b extends JPanel {
   private static final Color BG = Color.white;
   private static final Color DRAW_COLOR = Color.red;
   private static final int PREF_W = 800;
   private static final int PREF_H = 600;
   private static final Stroke BASIC_STROKE = new BasicStroke(3f);
   private int counter = 0;
   private int x1 = 0;
   private int y1 = 0;
   private int x2 = 0;
   private int y2 = 0;

   public U4b() {
      setBackground(BG);
      MyMouseListener myMouseListener = new MyMouseListener();
      addMouseListener(myMouseListener);
      addMouseMotionListener(myMouseListener);
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setColor(DRAW_COLOR);
      g2.setStroke(BASIC_STROKE);
      g2.drawLine(x1, y1, x2, y2);
   }

   private class MyMouseListener extends MouseAdapter {
      @Override
      public void mousePressed(MouseEvent e) {
         counter++;
         System.out.println("Counter: " + counter);
         x1 = e.getX();
         y1 = e.getY();
         x2 = x1;
         y2 = y1;
      }

      @Override
      public void mouseDragged(MouseEvent e) {
         x2 = e.getX();
         y2 = e.getY();
         repaint();
      }

      @Override
      public void mouseReleased(MouseEvent e) {
         x2 = e.getX();
         y2 = e.getY();
         repaint();
      }

   }

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

      JFrame frame = new JFrame("U4b");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_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();
         }
      });
   }
}