使用 Java Swing,mouseEntered 被 mouseMoved 所掩盖.有没有一个简单的解决方法



基本上,我必须简单地绘制文本"鼠标输入位置",然后是其坐标。 我的代码在未实现鼠标移动时成功地完成了此操作。 如果是,它永远不会显示鼠标进入并直接进入"鼠标移动"。 我可以理解mouseMoved如何做到这一点,因为进入面板也是在该位置移动鼠标。 我尝试将移动存储在矢量中并显示它们(对于这个项目来说还不是必需的),但它仍然没有描绘出鼠标进入的样子。 这让我怀疑有更深层次的原因导致了这种情况。 有没有简单的解决方法?

对于原始的、未完成的代码,我深表歉意(未完成,因为它还没有完成我需要它的所有事情,但它确实编译并使用它的 GUI 对应项运行)。

import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import javax.swing.*;
public class DrawingArea extends JPanel {
int x1, x2, y1, y2;
int shapeType;
char mouseAction;
Vector<String> eventList = new Vector<String>();
public DrawingArea() {
    initialize();
}
public void initialize() {

    addMouseListener(new MouseAdapter() {
      public void mouseEntered(MouseEvent m) {
          x1 = m.getX();
          y1 = m.getY();
          mouseAction = 'a';
          shapeType = 0;
          repaint();
      }
     public void mouseExited (MouseEvent m) {
         x1 = m.getX();
         y1 = m.getY();
         mouseAction = 'b';
         shapeType = 0;
         repaint();
     }
      public void mousePressed(MouseEvent m) {
          x1 = m.getX();
          y1 = m.getY();
          mouseAction = 'd';
          shapeType = 0;
          repaint();
      }
      public void mouseReleased(MouseEvent m) {
          x2 = m.getX();
          y2 = m.getY();
          repaint();
      }
    });
  addMouseMotionListener(new MouseMotionAdapter() {
      public void mouseMoved (MouseEvent m) {
          x2 = m.getX();
          y2 = m.getY();
          mouseAction = 'c';
          shapeType = 0;
          repaint();
      }
       public void mouseDragged(MouseEvent m) {
             x2 = m.getX();
             y2 = m.getY();
             repaint();
          }
      });
}
public void output(String event, MouseEvent m) {
}
public void setShapeType(int num) {
    if (num == 1) {
        shapeType = 1;
        mouseAction = 'z';
        repaint();
    }
    else if (num == 2) {
        shapeType = 2;
        mouseAction = 'z';
        repaint();
    }
    else if (num == 3) {
        shapeType = 0;
        mouseAction = 'z';
        repaint();
    }
}
public void paint(Graphics g) {
    super.paint(g);
    if (shapeType == 1) {
        g.drawString("Rectangle", 25,25);
    }
    else if (shapeType == 2)
        g.drawString("Circle", 25, 25);
    if (mouseAction == 'a') {
        g.drawString("Mouse entered at (" + x1+ ", " + y1 + ")", 25, 25);
    }
    else if (mouseAction == 'b') {
        g.drawString("Mouse exited at (" + x1 + ", " + y1 + ")", 25, 25);
    }
    else if (mouseAction == 'c') {
        g.drawString("Mouse moved at (" + x2 + ", " + y2 + ")", 25, 25);
    }
    else if (mouseAction == 'd') 
        g.drawString("Mouse clicked at (" + x1 + ", " + y1 + ")", 25, 25);
}
}

作为参考,以下是 GUI 代码:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SimpleGUI extends JFrame {
DrawingArea drawArea = new DrawingArea();

public SimpleGUI() {
    createGUI();
}

public void createGUI() {
    JFrame main = new JFrame();
    main.setVisible(true);
    main.setSize(500, 600);
    main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel right = new JPanel(new GridLayout(20,1));
    JPanel bottom = new JPanel();
    JButton rect = new JButton("Rectangle");
    JButton circ = new JButton("Circle");
    JButton erase = new JButton("Erase");
    JButton send = new JButton("Send");
    JTextField text = new JTextField(30);
    right.add(rect);
    right.add(circ);
    right.add(erase);
    bottom.add(text);
    bottom.add(send);
    drawArea.setBackground(Color.WHITE);
    main.add(drawArea, BorderLayout.CENTER);
    main.add(right, BorderLayout.EAST);
    main.add(bottom, BorderLayout.SOUTH);
    rect.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            drawArea.setShapeType(1);
        }
    });
    circ.addActionListener (new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            drawArea.setShapeType(2);
        }
    });
    erase.addActionListener (new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            drawArea.setShapeType(3);
        }
    });
}


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

问题不在于侦听器,而在于您的渲染逻辑......

if (mouseAction == 'a') {
    g.drawString("Mouse entered at (" + x1 + ", " + y1 + ")", 25, 25);
} else if (mouseAction == 'b') {
    g.drawString("Mouse exited at (" + x1 + ", " + y1 + ")", 25, 25);
} else if (mouseAction == 'c') {
    g.drawString("Mouse moved at (" + x2 + ", " + y2 + ")", 25, 25);
} else if (mouseAction == 'd') {
    g.drawString("Mouse clicked at (" + x1 + ", " + y1 + ")", 25, 25);
}

基本上,当鼠标进入时,它会触发a mouseAction,紧随其后的是c mouseAction

我推测重绘管理器从来没有时间渲染a因为c覆盖了它。

如果您更新了绘制代码以分离运动和动作之间的逻辑,您应该能够看到差异。

g.drawString("Mouse " + (mouseEntered ? "entered" : "exited") + " at (" + x1 + ", " + y1 + ")", 25, 50);
if (mouseAction == 'c') {
    g.drawString("Mouse moved at (" + x2 + ", " + y2 + ")", 25, 25);
} else if (mouseAction == 'd') {
    g.drawString("Mouse clicked at (" + x1 + ", " + y1 + ")", 25, 25);
}

我添加了一个mouseEntered字段,这是一个简单的boolean值,设置为从mouseEntered true,从mouseExited false

此外,约定更喜欢覆盖paintComponent方法而不是paintpaintComponent是双缓冲的,paint不是。

相关内容

最新更新