我需要绘制逐帧移动的AWT / Swing矩形。
我有一个Playground
班
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());
}
不幸的是,只有一个元素没有闪烁,其他所有元素仍在闪烁。
答案 0 :(得分:1)
以下是一个单文件mcve,它演示了如何通过自定义绘制移动(为简单起见旋转)矩形。 一个文件意味着您可以将整个代码复制粘贴到一个文件(AnimateRectangle.java)中并执行它。
as.formula
更好选项(请参见camickr注释)是使用挥杆动作Timer进行动画处理。为此,请删除tibble
方法,然后将其替换为:
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);
}
}
并更改animate()
以使用它:
void animateWithTimer(){
new Timer(1000,new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int newAngle = (model.getAngle() < 360 ) ? model.getAngle()+1 : 0 ;
model.setAngle(newAngle);
view.refresh();
}
}).start();
}