Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java在循环中绘制移动矩形_Java_Swing_Awt_Drawing - Fatal编程技术网

Java在循环中绘制移动矩形

Java在循环中绘制移动矩形,java,swing,awt,drawing,Java,Swing,Awt,Drawing,我需要画在AWT/摆动矩形,从帧到帧移动 我有一个操场班 public Playground(int sizeX, int sizeY) { frame = new JFrame(); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); panel = new JPanel(); panel.setSize(sizeX, sizeY); pane

我需要画在AWT/摆动矩形,从帧到帧移动

我有一个
操场

public Playground(int sizeX, int sizeY)
{
    frame = new JFrame();
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    panel = new JPanel();
    panel.setSize(sizeX, sizeY);
    panel.setDoubleBuffered(true);

    panel.setVisible(true);
    frame.add(panel);
    frame.pack();
    frame.setSize(sizeX, sizeY);
}

public void refresh()
{
    panel.repaint();
}

public Graphics getGraphics()
{
    return panel.getGraphics();
}
这是应在其中绘制对象的类:

public class Star {

    private static int size = 10;

    private int posX;
    private int posY;

    public Star(int posX, int posY)
    {
        this.posX = posX;
        this.posY = posY;
    }

    public void paint(Graphics g)
    {
        g.fillRect(posX, posY, size, size);
    }

    public int getPosX() {
        return posX;
    }

    public int getPosY() {
        return posY;
    }
}
这是主要的方法:

public static void main(String[] args) {
    Playground playground = new Playground(400, 400);
    Star star = new Star(100, 100);
    Star star2 = new Star(125, 125);
    while(1 == 1)
    {
        playground.refresh();
        star.paint(playground.getGraphics());
        star2.paint(playground.getGraphics());
    }
}
对象已绘制但正在闪烁,如何阻止其闪烁

编辑:我通过将刷新方法更改为:

public void refresh()
{
    panel.getGraphics().clearRect(0,0, panel.getWidth(), panel.getHeight());
}

不幸的是,只有一个元素没有闪烁,所有其他元素仍在闪烁。

以下是一个单文件mcve,演示了通过自定义绘制移动(旋转以简化)矩形。 一个文件意味着您可以将整个代码复制粘贴到一个文件(AnimateRectangle.java)中并执行它

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class AnimateRectangle {

    private JFrame frame;

    public AnimateRectangle(Model model){

        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel = new MyJPanel(model);
        panel.setDoubleBuffered(true);

        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }

    void refresh() {
        frame.repaint();
    }

    public static void main(String[] args) throws InterruptedException {
        Controller controller = new Controller(400, 400);
        while (true) {
            Thread.sleep(1000);
            SwingUtilities.invokeLater(()->controller.animate());
        }
    }
}

//"wires" gui and model 
class Controller{

    private Model model;
    private AnimateRectangle view;

    Controller(int sizeX, int sizeY){

         model = new Model(sizeX, sizeY);
         view = new AnimateRectangle(model);
    }

    void animate() {
        int newAngle = (model.getAngle() < 360 ) ? model.getAngle()+1 : 0 ;
        model.setAngle(newAngle);
        view.refresh();
    }
}

//represents the inforamtion the GUI needs 
class Model{

    int sizeX, sizeY, angle = 0;

    public Model(int sizeX, int sizeY) {
        this.sizeX = sizeX;
        this.sizeY = sizeY;
    }

    int getSizeX() { return sizeX; }

    int getSizeY() {return sizeY;}

    int getAngle() {return angle;}

    //degrees
    void setAngle(int angle) {  this.angle = angle; }
}

//a JPanel with custom paint component 
class MyJPanel extends JPanel {

    private Model model;

    public MyJPanel(Model model) {
        this.model = model;
        setPreferredSize(new Dimension(model.getSizeX(), model.getSizeY()));
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D)g;
        g2d.setColor(Color.RED);
        int sizeX = model.getSizeX(), sizeY = model.getSizeY();
        g2d.rotate(Math.toRadians(model.getAngle()), sizeX /2, sizeY/2);
        g2d.fillRect(sizeX/4, sizeY/4, sizeX/2, sizeY/2);
    }
}
并更改
main
以使用它:

public static void main(String[] args) throws InterruptedException {
    Controller controller = new Controller(400, 400);
    controller.animateWithTimer();
}

欢迎来到SO。“在循环中绘制移动矩形”-在移动它之前,您需要绘制一个。你做到了吗?我在代码中看不到它(填充的)矩形是画出来的(在主循环中,这是一个无休止的循环,现在只需要为元素画两次),它们也在移动,所有的东西都在移动。问题是,有严重的闪烁,不管我是否总是在一个地方画它们,或者它们是否在移动:/Please post,这样我们就不用猜了。在上结束无休止的循环将冻结GUI。我可以将循环放入另一个线程,但问题仍然存在(即使我在循环上设置了条件以便可以停止它)。没有应该与之交互的GUI,它基本上只是用于可视化算法。发布的代码不是mcve。要做到这一点,它必须在复制过去之后才可执行<代码>操场无法编译发布的内容。请参阅我答案中的mcve示例。
另一个选项是使用swing Timer设置动画。
-实际上,这是应该使用的选项。GUI的所有更新都应该在事件调度线程上完成。main()方法中的代码也应该从EDT调用。@camickr感谢您的反馈。我用
SwingUtilities.invokeLater(()->controller.animate())更新了代码。不使用计时器的选项被发布,因为我认为OP想要的是对动画的外部控制。没有办法从“外部”绘制。在这里和其他例子中,我总是看到paintComponent被覆盖,在这里进行一些绘图。但我将有无限量的元素被绘制(这就是为什么我想把绘制从它们调用到我从JPanel获得的图形对象)?当我不使用刷新时(当然旧位置没有被清除,并且画了一条线),它不会闪烁,是否有控制重绘方法的方法?更改模型中的绘图属性(包括要绘制的元素数量)。这些属性应该由用户使用。绘制的图元数量可以是动态的。参见示例
public static void main(String[] args) throws InterruptedException {
    Controller controller = new Controller(400, 400);
    controller.animateWithTimer();
}