直接在JFrame上画图,采用双缓冲防止闪烁
package Homework;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MyMoonJFrame extends JFrame implements ActionListener {
JComboBox<Integer> jComboBox1,jComboBox2,jComboBox3,jComboBox4;
JPanel jPanel;
int x = 100, y = 100;
int x1;
int velocity; //延迟时间
int size = 50 ; //初始大小
public MyMoonJFrame() {
super("月食动画");
this.setSize(1000,500);
this.setLocationRelativeTo(null); //放在中央
Container container = this.getContentPane();
jPanel = new JPanel();
jPanel.setBackground(Color.white);
jPanel.setSize(1000,50);
JLabel jLabel1 = new JLabel("大小:");
JLabel jLabel2 = new JLabel("X坐标:");
JLabel jLabel3 = new JLabel("Y坐标:");
JLabel jLabel4 = new JLabel("延迟时间:");
jComboBox1 = new JComboBox<Integer>();
for(int i = 100;i < 1100;i += 100) //可设置100到1000的大小
{
jComboBox1.addItem(i);
}
jComboBox1.addActionListener(this);
jPanel.add(jLabel1);
jPanel.add(jComboBox1);
jComboBox2 = new JComboBox<Integer>(); //下拉列表决定X坐标
for(int i = 10; i < 500; i += 10)
jComboBox2.addItem(i);
jComboBox2.addActionListener(this);
jPanel.add(jLabel2);
jPanel.add(jComboBox2);
jComboBox3 = new JComboBox<Integer>(); //设置Y坐标
for(int i = 80; i < 500; i += 10)
jComboBox3.addItem(i);
jComboBox3.addActionListener(this);
jPanel.add(jLabel3);
jPanel.add(jComboBox3);
jComboBox4 = new JComboBox<Integer>(); //设置延迟时间,越大表示月食越慢
for(int i = 10; i < 500; i += 10)
jComboBox4.addItem(i);
jComboBox4.addActionListener(this);
jPanel.add(jLabel4);
jPanel.add(jComboBox4);
this.getContentPane().add(jPanel);
// 新建一个Moon类,并且是继承的Canvas类,是在画布上进行操作,可以直接添加到容器中
Moon moon = new Moon();
this.getContentPane().add(moon);
this.setVisible(true);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new MyMoonJFrame();
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getSource() instanceof JComboBox)
{
Integer i = (Integer)jComboBox1.getSelectedItem(); //将选中的大小进行设置
size = i;
}
if(e.getSource() instanceof JComboBox)
{
Integer i = (Integer)jComboBox2.getSelectedItem();
x = i;
x1 = x + size / 2; //在圆心的
}
if(e.getSource() instanceof JComboBox)
{
Integer integer = (Integer)jComboBox3.getSelectedItem();
y = integer;
}
if(e.getSource() instanceof JComboBox)
{
Integer integer = (Integer)jComboBox4.getSelectedItem();
velocity = integer;
}
}
//内部类,放在一个类的内部可以使用x,y等一些变量,方便访问,
class Moon extends Canvas implements Runnable{ //采用runnable接口运行线程
public Moon() {
// TODO Auto-generated constructor stub
this.setBackground(Color.black);
Thread thread = new Thread(this);
thread.start();
}
@Override
public void paint(Graphics arg0) {
//进行双缓冲
// TODO Auto-generated method stub
super.paint(arg0);
arg0.setColor(Color.white);
arg0.fillOval(x, y, size, size);
arg0.setColor(Color.black);
arg0.fillOval(x1 + size / 2, y, size, size);
}
@Override
public void run() {
while(true){
try {
Thread.sleep(velocity);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
repaint();
x1 -- ;
if(x1 == x - size * 3 / 2)
x1 = x + size / 2;
}
}
@Override
public void update(Graphics g) {
// TODO Auto-generated method stub
//采用双缓冲,先画到虚拟画布上,再重绘到屏幕上
//https://cloud.tencent.com/developer/article/1189719 见这个原理
Image offScreenImage = this.createImage(this.getWidth(), this.getHeight());
Graphics offScreenGraphics = offScreenImage.getGraphics();
Color c = offScreenGraphics.getColor();
offScreenGraphics.setColor(Color.white);
offScreenGraphics.fillRect(0, 0, this.getWidth(), this.getHeight());
offScreenGraphics.setColor(c);
paint(offScreenGraphics);
g.drawImage(offScreenImage, 0, 0, null);
}
}
}