从鼠标侦听器方法调用时 repaint() 不起作用
repaint() not working when called from mouse listener method
我正在制作一个纸牌程序作为一个副项目,我在制作的油漆 window 上遇到了问题。
在程序中,我有一条直线从一点开始,到鼠标单击的位置结束。当我点击 window 时,它成功读取我的点击并将 xcor
和 ycor
变量更改为我的鼠标点击位置,但无法使用新坐标重新绘制线条。
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
调用的,我也试过从不同的 MouseListener
和 MouseMotionListener
方法调用它来没用。
注意: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
将框架的大小设置为其子组件的首选大小。
我正在制作一个纸牌程序作为一个副项目,我在制作的油漆 window 上遇到了问题。
在程序中,我有一条直线从一点开始,到鼠标单击的位置结束。当我点击 window 时,它成功读取我的点击并将 xcor
和 ycor
变量更改为我的鼠标点击位置,但无法使用新坐标重新绘制线条。
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
调用的,我也试过从不同的 MouseListener
和 MouseMotionListener
方法调用它来没用。
注意: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
将框架的大小设置为其子组件的首选大小。