我有一辆"汽车"使用图形g使用各种对象制作,我想在按下按钮时移动它。有了这个,我没有问题,但我的路径有问题。当汽车移动时,旧位置不会被清除。
汽车代码(按下按钮时移动):
static void gPostavi2(Graphics g){
Graphics2D g2d = (Graphics2D) g;
for(int x=500; x>89; x--){
//risanje
g2d.setColor(Color.blue);
g2d.fillRect(x+10, 351, 118, 23);
g2d.fillRect(x+12, 321, 30, 40);
g2d.fillRect(x+45, 330, 83, 20);
g2d.setColor(Color.black);
g2d.fillOval(x+19, 362, 20, 20);
g2d.fillOval(x+90, 362, 20, 20);
g2d.drawString("2t", x+70, 344);
try {
Thread.sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
在这个类中只有移动东西的方法,类扩展了另一个具有非移动对象,按钮,标签......和paintComponent方法的方法。
每次for语句出现时,我如何清除旧位置?
编辑:这里有更多代码。在主类我只有这个代码:
public static void main(String[] args) {
staticnaGrafika.dodajGumbe();
}
在staticnaGrafika中我有很多代码,但这是paintComponent的开头:
public class staticnaGrafika extends JPanel{
staticnaGrafika(){
setBorder(BorderFactory.createLineBorder(Color.black));
}
public Dimension getPreferredSize(){
return new Dimension(1100, 740);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.RED);
//opticno stikalo
//preveri, ce ga plosca prekriva pri max. dvigu
g2d.setColor(Color.black);
g2d.fillOval(21, 148, 33, 33);
g2d.setColor(Color.yellow);
g2d.fillOval(22, 149, 31, 31);
g2d.setColor(Color.black);
g2d.fillRect(13, 159, 11, 1); //el. prikljucnice
g2d.fillRect(13, 166, 10, 1);
g2d.drawOval(7, 157, 5, 5);
g2d.drawOval(7, 164, 5, 5);
//naslon; spodnji omejevalec hoda bata
g2d.setColor(Color.black);
g2d.fillRect(5, 350, 13, 43);
g2d.fillRect(5, 380, 63, 13);
g2d.fillRect(262, 350, 408, 13);
g2d.fillRect(262, 350, 13, 43);
g2d.fillRect(212, 380, 63, 13);
这里只画画。下面我有另一个方法,它添加了按钮,actionListeners:
public static void dodajGumbe() {
final JFrame f = new JFrame();
//dvig, stop, spust
JButton dvig = new JButton("DVIGNI");
dvig.setBackground(Color.WHITE);
dvig.setFocusPainted(false);
dvig.setBounds(850,15,120,30);
JButton stop = new JButton("STOP");
stop.setBackground(Color.WHITE);
stop.setFocusPainted(false);
stop.setBounds(850,50,120,30);
JButton spust = new JButton("SPUSTI");
spust.setBackground(Color.WHITE);
spust.setFocusPainted(false);
spust.setBounds(850,85,120,30);
//komande bremen
JButton postavi2 = new JButton("nalozi breme");
postavi2.setBackground(Color.WHITE);
postavi2.setFocusPainted(false);
postavi2.setBounds(760,240,120,30);
JButton odvzemi2 = new JButton("razlozi breme");
odvzemi2.setBackground(Color.WHITE);
odvzemi2.setFocusPainted(false);
odvzemi2.setBounds(760,275,120,30);
JButton postavi5 = new JButton("nalozi breme");
postavi5.setBackground(Color.WHITE);
postavi5.setFocusPainted(false);
postavi5.setBounds(760,330,120,30);
JButton odvzemi5 = new JButton("razlozi breme");
odvzemi5.setBackground(Color.WHITE);
odvzemi5.setFocusPainted(false);
odvzemi5.setBounds(760,365,120,30);
Container gumbi = f.getContentPane();
spust.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gSpusti(f.getGraphics());
}});
dvig.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gDvigni(f.getGraphics());
}});
stop.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gStop(f.getGraphics());
}});
postavi2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gPostavi2(f.getGraphics());
}});
odvzemi2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gOdvzemi2(f.getGraphics());
}});
postavi5.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gPostavi5(f.getGraphics());
}});
odvzemi5.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gOdvzemi5(f.getGraphics());
}});
gumbi.add(dvig);
gumbi.add(stop);
gumbi.add(spust);
gumbi.add(postavi2);
gumbi.add(odvzemi2);
gumbi.add(postavi5);
gumbi.add(odvzemi5);
f.getContentPane();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new staticnaGrafika());
f.pack();
f.setVisible(true);
}
答案 0 :(得分:4)
你可能忘了打电话了
super.paintComponent(g);
您的paintComponent()
方法中的
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g); //Clear screen before redraw
//Your codes for painting..
}
答案 1 :(得分:4)
你永远不应该在UI线程上调用sleep()。相反,我强烈建议您使用javax.swing.Timer和ActionListener。类似的东西:
void paintCar(Graphics2D g2d, int x) {
g2d.setColor(Color.blue);
g2d.fillRect(x+10, 351, 118, 23);
g2d.fillRect(x+12, 321, 30, 40);
g2d.fillRect(x+45, 330, 83, 20);
g2d.setColor(Color.black);
g2d.fillOval(x+19, 362, 20, 20);
g2d.fillOval(x+90, 362, 20, 20);
g2d.drawString("2t", x+70, 344);
}
int x = 0;
public MyConstructor() {
new Timer(5, this).start();
}
public void actionPerformed(ActionEvent ae) {
x++;
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
paintCar(g2d, x);
}
答案 2 :(得分:1)
看起来问题在于您的实施。您可以为Car对象创建一个类,并且每个car对象都会跟踪它们自己的坐标。
对于您的情况,如果您仅在单击按钮时移动汽车,则甚至不需要计时器。只需在每次点击按钮时更新汽车在ActionListener中的位置。
class Car
{
private Color carColor;
private int x, y;
private int speed;
private static int carWidth = 100;
private static int carHeight = 30;
public Car(Color carColor, int speed){
this.carColor = carColor;
this.speed = speed;
x = 0;
y = 0;
}
public void moveTo(int x, int y){
this.x = x;
this.y = y;
}
public void draw(Graphics g){
//Draw a car object
g.setColor(carColor);
g.fillRect(x, y, carWidth, carHeight);
g.setColor(Color.BLACK);
//Draw Wheels
g.fillOval(x, y+carHeight, 30, 30);
g.fillOval(x+carWidth-30, y+carHeight, 30, 30);
}
public int getX(){return x;}
public int getY(){return y;}
public int getSpeed(){return speed;}
}
因此,当您移动汽车时,只需更新他们的位置,这就是您需要做的一切。请特别注意我的paintComponent()
方法。你应该保持这种方法简单,无杂乱。它只负责绘画。汽车的所有动作都在其他地方完成。
class DrawingSpace extends JPanel implements ActionListener{
Car c1, c2, c3;
public DrawingSpace(){
setPreferredSize(new Dimension(800, 400));
c1 = new Car(Color.RED, 5);
c2 = new Car(Color.GREEN, 8);
c3 = new Car(Color.BLUE, 10);
c1.moveTo(10, 50);
c2.moveTo(10, 180);
c3.moveTo(10, 280);
}
public void moveCars(){
}
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
c1.draw(g);
c2.draw(g);
c3.draw(g);
}
@Override
public void actionPerformed(ActionEvent e){
//Used for timer (to animate moving cars)
c1.moveTo((c1.getX()+c1.getSpeed()), c1.getY());
c2.moveTo(c2.getX()+c2.getSpeed(), c2.getY());
c3.moveTo(c3.getX()+c3.getSpeed(), c3.getY());
if(c1.getX() > 800)
c1.moveTo(0, c1.getY());
if(c2.getX() > 800)
c2.moveTo(0, c2.getY());
if(c3.getX() > 800)
c3.moveTo(0, c3.getY());
repaint();
}
}
对于这样的任务,使用javax.swing.timer
而不是使用Thread.sleep()
实现自己的循环会更好更容易。
class MovingCars{
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run() {
JFrame f = new JFrame("Moving Cars");
DrawingSpace ds = new DrawingSpace();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(ds);
f.pack();
f.setLocationRelativeTo(null);
Timer t = new Timer(50, ds); //Delay of 50 milliseconds
t.start();
}
});
}
}