Java在循环中绘制移动矩形
我需要画在AWT/摆动矩形,从帧到帧移动 我有一个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
操场
班
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();
}