在 Java 中移动球

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17738444/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 14:49:44  来源:igfitidea点击:

Moving Ball in Java

javagraphicsawtpaint

提问by Abdullah A Malik

when i run it, the repaint doesn't work. The frame opens and stays for 2000ms and then closes. else if i remove the System.exit(0); statement, it doesn't closes but the painted ball still doesn't shows up.

当我运行它时,重绘不起作用。帧打开并停留 2000 毫秒,然后关闭。否则,如果我删除 System.exit(0); 声明,它没有关闭,但彩绘球仍然没有出现。

BallWorld.java

球世界.java

import java.awt.*;
import javax.swing.JFrame;

public class BallWorld extends Frame {

public static void main(String[] args) {

    BallWorld bw1 = new BallWorld(Color.red);
    bw1.show();


}

public static final int framewidth = 600;
public static final int frameheight = 400;

private Ball aball;
private int counter = 0;

private BallWorld(Color ballColor){

    setSize(framewidth,frameheight);
    setTitle("Ball World");

    aball = new Ball(10, 15, 5);
    aball.setColor(ballColor);
    aball.setMotion(3.0, 6.0);

}


public void paint(Graphics g){

    aball.paint1(g);

    aball.move();


    if((aball.x() < 0) || (aball.x() > framewidth))

        aball.setMotion(-aball.xMotion(), aball.yMotion());

    if((aball.yMotion() < 0) || (aball.yMotion() > frameheight))

        aball.setMotion(aball.xMotion(),-aball.yMotion());

    //redraw  the frame

    counter = counter + 1;

    if(counter < 2000)
    repaint();
    else
        System.exit(0); 
}   
}

the other class is

另一个班级是

Ball.java

球.java

import java.awt.*;
import java.awt.Rectangle;

public class Ball {

protected Rectangle location;
protected double dx,dy;
protected Color color;



public Ball(int x,int y, int r){

    location =new Rectangle(x-r, y-r, 2*r, 2*r);

    dx=0;   //initially no motion
    dy=0;
    color = Color.blue;
}

// Setters
public void  setColor(Color newColor){
    color = newColor;
}

public void setMotion(double new_dx, double new_dy){
    dx = new_dx;
    dy = new_dy;
}


//Getters

public int radius(){    
    return location.width/2;
}

public int x(){
    return location.x + radius();
}

public int y(){
    return location.y + radius();
}

public double xMotion(){
    return dx;
}

public double yMotion(){    
    return dy;
}

public Rectangle region(){
    return location;
}

//Methods that change attributes of the ball

public void moveTo(int x, int y){
    location.setLocation(x, y);
}

public void move(){
    location.translate((int) dx,(int) dy);
}

public void paint1(Graphics g){

    g.setColor(color);
    g.fillOval(location.x, location.y,location.width,location.height);
}
}

回答by MadProgrammer

  1. Use Swing instead of AWT, AWT is basically obsolute
  2. Don't override paintof top level containers, you've actually stepped into one of the reason why you shouldn't
  3. Don't call repaintor any method that might call repaintfrom inside any paintmethod, it will create an infinite loop that will consume your CPU
  4. Painting is passive in AWT/Swing. That means that updates occur at irregular intervals based on changes, like mouse movements or changes to the size of the frame.
  1. 用Swing代替AWT,AWT基本过时了
  2. 不要覆盖paint顶级容器,您实际上已经进入了不应该的原因之一
  3. 不要调用repaint或任何可能repaint从任何paint方法内部调用的方法,它会创建一个会消耗 CPU 的无限循环
  4. 绘画在 AWT/Swing 中是被动的。这意味着更新会根据更改(例如鼠标移动或帧大小的更改)以不规则的间隔发生。

Now, to the core of your problem. Basically, you're painting under the frame decoration. This occurs because the window has decorations added inside it's visible area, not added onto it.

现在,到您问题的核心。基本上,您是在框架装饰下绘画。发生这种情况是因为窗口在其可见区域内添加了装饰,而不是添加到其上。

See How to get the EXACT middle of a screen, even when re-sizedand How can I set in the midst?for more details

请参阅如何获得屏幕的准确中间,即使重新调整大小以及如何在中间设置?更多细节

This is why it is recommended that you don't override paint of top level containers. You need to create a component which can be added to the frame and onto which you can then paint

这就是为什么建议您不要覆盖顶级容器的绘制。您需要创建一个组件,该组件可以添加到框架中,然后您可以在其上绘画