从鼠标侦听器方法调用时 repaint() 不起作用

repaint() not working when called from mouse listener method

我正在制作一个纸牌程序作为一个副项目,我在制作的油漆 window 上遇到了问题。

在程序中,我有一条直线从一点开始,到鼠标单击的位置结束。当我点击 window 时,它成功读取我的点击并将 xcorycor 变量更改为我的鼠标点击位置,但无法使用新坐标重新绘制线条。

public class Game_Play extends JFrame {

public int xcor = 0;
public int ycor = 0;
public void setup() { //sets up JFrame
    JFrame frame = new JFrame();
    frame.setSize(500, 500);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocation(0, 0);
    frame.setTitle("Circles");
    frame.add(new MouseHandler());
    frame.addMouseListener(new MouseHandler());
    frame.addMouseMotionListener(new MouseHandler());
    frame.setVisible(true);
}

          //listener and painting subclass
class MouseHandler extends JPanel implements MouseListener, MouseMotionListener {
              //when mouse pressed, the Xcor and Ycor
              //will be changed to the current mouse 
              //x and y cords, then it will call 
              //repaint() to repaint the line using the
              //new Xcor and Ycor locations
    public void mousePressed(MouseEvent me) {
        System.out.println("mouse pressed");
        xcor = me.getX();
        ycor = me.getY();
                  //prints out new cords
        System.out.println(xcor + " xcor");
        System.out.println(ycor + " ycor");
        repaint();
    }

    public void mouseReleased(MouseEvent me) { //tests to make sure listener is working
        System.out.println("mouse released");
    }

    public void mouseClicked(MouseEvent me) {}
    public void mouseEntered(MouseEvent me) {}
    public void mouseMoved(MouseEvent me) {}
    public void mouseExited(MouseEvent me) {}
    public void mouseDragged(MouseEvent me) {}

              //paints the line with the Xcor and Ycor values
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        System.out.println("repaint check"); //test to see if repaint has been called
        g.drawLine(100, 100, xcor, ycor);
    }
}
}

注意:repaint() 是从 MouseListener 方法 mousePressed 调用的,我也试过从不同的 MouseListenerMouseMotionListener 方法调用它来没用。

注意:paintComponent方法调用成功会通知我,点击时paintComponent方法不执行

注意:我确实注意到,如果我在屏幕上单击以设置新线,然后点击 window 上的最大化按钮,它将使用新线成功调用重绘线的重绘方法.

注意:setup()方法是从另一个文件中的另一个class调用的,代码如下:

public static void main(String[] args) throws IOException {
  deck_Create();
  deck_Shuffle();
  game_setup();
  BufferedImage_array_Setup();
  //being called here
  Game_Play a = new Game_Play();
  a.setup();
  //
}

最后说明:我四处寻找解决这个问题的办法,结果发现类似的问题对我没有帮助。非常感谢您提供的任何反馈。

如果有任何问题,请告诉我,我会尽快为您解答。

谢谢!

对您的代码的一些评论:

public void setup() {
    JFrame frame = new JFrame();
    frame.setSize(500, 500);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocation(0, 0);
    frame.setTitle("Circles");
    frame.add(new MouseHandler());// your panel
    frame.addMouseListener(new MouseHandler()); // your listener, also a panel, but not the one you added to your frame
    frame.addMouseMotionListener(new MouseHandler()); // yet another listener, also not the panel you added to your frame
    frame.setVisible(true);
}

您可能打算写:

public void setup() {
    JFrame frame = new JFrame();
    frame.setSize(500, 500);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocation(0, 0);
    frame.setTitle("Circles");
    JPanel p = new MouseHandler();
    frame.add(p);
    frame.addMouseListener(p);
    frame.addMouseMotionListener(p);
    frame.setVisible(true);
}

请注意,让您的 UI 组件实现侦听器接口并不是一个好主意。如果您想为面板中的不同组件设置两个鼠标侦听器怎么办?面板上不能有两个听众。

更好的方法是让监听器接口由匿名 类 实现,遵循 关注点分离 准则。

另一件事是将侦听器添加到应该处理它们的组件中。您应该在面板上注册这些侦听器,而不是包含面板的框架。

最后,您应该将面板设置为内容窗格,使用 setContentPane. Usually it's best to have the panel dictate what its size should be by overriding setPreferredSize. In that case you don't need to set the size of the containing frame, rather you call pack 将框架的大小设置为其子组件的首选大小。