repaint() 突然不起作用
repaint() suddenly doesn't work
我进行了大约 30 次不同的 google 搜索,但没有找到答案,所以我来到了这里。所以我试图在屏幕上左右移动播放器的矩形(黑色方块)。当我使用常规图形时它工作正常,但现在我使用 Graphics2D 时 repaint() 似乎什么都不做(即当你按下左右箭头键时,矩形不会移动)。
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class boxface extends JComponent implements KeyListener {
private boxobj obj;
private int x=0, y=650;
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()== KeyEvent.VK_RIGHT)
moveRight();
else if(e.getKeyCode()== KeyEvent.VK_LEFT)
moveLeft(); }
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
Rectangle player = new Rectangle(x, y, 50, 50);
Rectangle floor = new Rectangle(0, 700, 750, 700);
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g.setColor(Color.GREEN);
g2.fill(floor);
g.setColor(Color.BLACK);
g2.fill(player); }
public void moveLeft() {
if(x > 0) {
x -= 50;
repaint(); }}
public void moveRight() {
if(x < 700) {
x += 50;
repaint(); }}
public boxface(){
this.obj=new boxobj();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false); }
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setBounds(400, 200, 756, 779);
f.setMinimumSize(new Dimension(756, 0));
f.setResizable(false);
f.getContentPane().add(new boxface());
f.setVisible(true);
}
});
final java.util.Timer tmr = new java.util.Timer();
tmr.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
System.out.println("A second has passed.");
/* the idea is that I could make a square with random
* dimensions (within a certain limit), so that every
* time the timer loops, a new, random square is made.
* I just can't seem to move the rectangles using
* repaint(); because they're Graphics2D rectangles,
* and I can't find a way around this.
*
* An example of this can be shown if you run this
* code; the "player" rectangle cannot be moved, even
* though keylistener is picking up inputs and the
* rectangle's co-ordinates are being changed. In
* other words, repaint(); isn't doing anything. */
}
},0,1000);
}//end main
}//end class
此外,"boxobj" class 现在只是一个空的 class。这是我计划放置随机矩形初始化的地方。我就放在这里方便复制粘贴。
public class boxobj {
}
问题是您正在更新 x
变量,但绘制了 player
对象。
当你构造player
(通过Rectangle player = new Rectangle(x, y, 50, 50);
)时,它会在执行该行时获取x
值的副本。由于您同时声明和初始化,我们知道 x
为零,因此 player
将用 (0, 650, 50, 50)
.
实例化
稍后,用户按下右箭头键,您的事件侦听器将触发。这会将 x
增加到 50 并调用 repaint
但重要的是,根本不会更新 player
对象。当 paintComponent
方法被绘画系统调用时 player
仍然是 (0, 650, 50, 50)
.
本质上 x
和 y
记录了玩家的位置,但是您使用 player
对象来绘制玩家并且这些变量没有同步更新。
纠正这个问题的最好方法是将玩家的位置准确地存储在一个地方。您可以保留 x
和 y
并修改 paintComponent
方法以使用它们,或者您可以丢弃这两个变量并改为修改 player
对象(使用 player.setLocation
).两种方法都行。
我进行了大约 30 次不同的 google 搜索,但没有找到答案,所以我来到了这里。所以我试图在屏幕上左右移动播放器的矩形(黑色方块)。当我使用常规图形时它工作正常,但现在我使用 Graphics2D 时 repaint() 似乎什么都不做(即当你按下左右箭头键时,矩形不会移动)。
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class boxface extends JComponent implements KeyListener {
private boxobj obj;
private int x=0, y=650;
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()== KeyEvent.VK_RIGHT)
moveRight();
else if(e.getKeyCode()== KeyEvent.VK_LEFT)
moveLeft(); }
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
Rectangle player = new Rectangle(x, y, 50, 50);
Rectangle floor = new Rectangle(0, 700, 750, 700);
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g.setColor(Color.GREEN);
g2.fill(floor);
g.setColor(Color.BLACK);
g2.fill(player); }
public void moveLeft() {
if(x > 0) {
x -= 50;
repaint(); }}
public void moveRight() {
if(x < 700) {
x += 50;
repaint(); }}
public boxface(){
this.obj=new boxobj();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false); }
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setBounds(400, 200, 756, 779);
f.setMinimumSize(new Dimension(756, 0));
f.setResizable(false);
f.getContentPane().add(new boxface());
f.setVisible(true);
}
});
final java.util.Timer tmr = new java.util.Timer();
tmr.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
System.out.println("A second has passed.");
/* the idea is that I could make a square with random
* dimensions (within a certain limit), so that every
* time the timer loops, a new, random square is made.
* I just can't seem to move the rectangles using
* repaint(); because they're Graphics2D rectangles,
* and I can't find a way around this.
*
* An example of this can be shown if you run this
* code; the "player" rectangle cannot be moved, even
* though keylistener is picking up inputs and the
* rectangle's co-ordinates are being changed. In
* other words, repaint(); isn't doing anything. */
}
},0,1000);
}//end main
}//end class
此外,"boxobj" class 现在只是一个空的 class。这是我计划放置随机矩形初始化的地方。我就放在这里方便复制粘贴。
public class boxobj {
}
问题是您正在更新 x
变量,但绘制了 player
对象。
当你构造player
(通过Rectangle player = new Rectangle(x, y, 50, 50);
)时,它会在执行该行时获取x
值的副本。由于您同时声明和初始化,我们知道 x
为零,因此 player
将用 (0, 650, 50, 50)
.
稍后,用户按下右箭头键,您的事件侦听器将触发。这会将 x
增加到 50 并调用 repaint
但重要的是,根本不会更新 player
对象。当 paintComponent
方法被绘画系统调用时 player
仍然是 (0, 650, 50, 50)
.
本质上 x
和 y
记录了玩家的位置,但是您使用 player
对象来绘制玩家并且这些变量没有同步更新。
纠正这个问题的最好方法是将玩家的位置准确地存储在一个地方。您可以保留 x
和 y
并修改 paintComponent
方法以使用它们,或者您可以丢弃这两个变量并改为修改 player
对象(使用 player.setLocation
).两种方法都行。