应用程序入口
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
@SuppressWarnings("serial")
public class DrawNameOnBg extends JFrame {
private JTextField textFrameRate;
private JTextField textBlockSize;
private JPanel panel;
// private PicPanel picPanel = new PicPanel();
private PicPanelUseBuffer picPanel = new PicPanelUseBuffer();
public DrawNameOnBg() {
setUndecorated(true);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(picPanel,BorderLayout.CENTER);
getContentPane().add(getPanel(), BorderLayout.SOUTH);
this.pack();//自动调整窗口大小
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);//移至屏幕中心
setVisible(true);
}
public static void main(String[] args) {
new DrawNameOnBg();
}
/**
* @return 按钮面板
*/
protected JPanel getPanel() {
if (panel == null) {
panel = new JPanel();
//帧率
final JLabel label_1 = new JLabel();
label_1.setText("帧率:");
panel.add(label_1);
textFrameRate = new JTextField();
textFrameRate.setText("20 ");
panel.add(textFrameRate);
//块大小
final JLabel label = new JLabel();
label.setText("块大小:");
panel.add(label);
textBlockSize = new JTextField();
textBlockSize.setText(picPanel.subImWidth+" ");
textBlockSize.setMinimumSize(new Dimension(30, 20));
panel.add(textBlockSize);
//演示按钮
final JButton buttonShow = new JButton();
buttonShow.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
new Thread(){
@Override
public void run() {
try {
int temp = Integer.valueOf(textBlockSize.getText().trim());
picPanel.subImWidth=temp;
picPanel.subImWidth=temp<5?5:temp;
picPanel.subImWidth=temp>120?120:picPanel.subImWidth;
textBlockSize.setText(String.valueOf(picPanel.subImWidth));
} catch (Exception e2) {
textBlockSize.setText(String.valueOf(picPanel.subImWidth));
}
try {
int temp = Integer.valueOf(textFrameRate.getText().trim());
if(temp<1)
picPanel.frameRate=1;
else if(temp>24) picPanel.frameRate=24;
else picPanel.frameRate=temp;
textFrameRate.setText(String.valueOf(picPanel.frameRate));
} catch (Exception e2) {
textFrameRate.setText(String.valueOf(picPanel.frameRate));
}
picPanel.restart();
}}.start();
}
});
panel.add(buttonShow);
buttonShow.setText("演示");
//退出按钮
final JButton buttonExit = new JButton();
buttonExit.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
System.exit(0);
}
});
buttonExit.setText("退出");
panel.add(buttonExit);
//旋转复选框
final JCheckBox checkBoxRotate = new JCheckBox();
checkBoxRotate.setSelected(picPanel.rotate);
checkBoxRotate.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
picPanel.rotate=!picPanel.rotate;
}
});
checkBoxRotate.setText("旋转");
panel.add(checkBoxRotate);
}
return panel;
}
}
主要的Jpanel
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class PicPanelUseBuffer extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
BufferedImage bgIm, nameIm;//背景图片和名字图片
BufferedImage[][][] nameSubIms;//分割后的图片,最后一维为各个方向的图片
Point posCenters[][];//各个小图的中心坐标
int subImWidth = 7;//分割后图片的宽度
int x; //名字图片的左上角坐标
int y = 30;
int xCenter;//汇聚中心坐标
int yCenter = -30;
int frames = 50;//帧数
boolean act = false;//是否动画,控制绘图用
int currentFrame;//当前帧
final int coefficient = 10;//将汇聚中心到小图的距离分为10份,作为小图移动的步长
int frameRate = 20;//帧率
AffineTransform tr; //仿射变换对象
final int directionNum = 8;//图片旋转方向数目
int direction = 0;//当前帧绘制的图片的方向的序号
boolean rotate = true;//控制是否旋转
public PicPanelUseBuffer() {
try {
setDoubleBuffered(true);
bgIm = ImageIO.read(new File("bg.jpg"));
//在背景上写上名字和E-mail
Graphics2D g = bgIm.createGraphics();
g.setColor(Color.BLUE);
g.setXORMode(Color.white);
g.setFont(new Font("宋体", Font.BOLD | Font.ITALIC, 20));
g.drawString("制作:2009310399 梁超 @ 清华", 5, g.getFontMetrics().getHeight());
String email = "E-mail: [email protected]";
g.drawString(email, bgIm.getWidth()
- SwingUtilities.computeStringWidth(g.getFontMetrics(), email) - 5, bgIm
.getHeight() - 10);
g.dispose();
nameIm = ImageIO.read(new File("name.png"));
x = (bgIm.getWidth() - nameIm.getWidth()) >> 1;//使得名字绘制在中心
xCenter = bgIm.getWidth() / 2;
tr = new AffineTransform();
init();
} catch (IOException e) {
e.printStackTrace();
}
}
private void init() {//初始化分割后的图像
nameSubIms = new BufferedImage[nameIm.getHeight() / subImWidth][nameIm.getWidth()
/ subImWidth][directionNum];
posCenters = new Point[nameSubIms.length][nameSubIms[0].length];
for (int i = 0; i < nameSubIms.length; i++) {
for (int j = 0; j < nameSubIms[i].length; j++) {
nameSubIms[i][j][0] = nameIm.getSubimage(j * subImWidth, i * subImWidth,
subImWidth, subImWidth);//旋转前的图像
int xC = x + j * subImWidth + (subImWidth >> 1);//小图的中心坐标
int yC = y + i * subImWidth + (subImWidth >> 1);
// System.out.println(xC+" "+yC+" "+(xC -
// xCenter)+" "+(yC - yCenter));
posCenters[i][j] = new Point(xC - xCenter, yC - yCenter);//到汇聚中心的向量
for (int k = 1; k < nameSubIms[i][j].length; k++) {//产生各个方向的图片,注意由于旋转后图片变大,有删减
nameSubIms[i][j][k] = new BufferedImage(subImWidth, subImWidth,
BufferedImage.TYPE_INT_ARGB_PRE);
Graphics2D g = nameSubIms[i][j][k].createGraphics();
double angle = Math.PI * 2 / directionNum * k;
if (xC < xCenter)
angle = -angle;
// tr.rotate(angle, subImWidth / 2, subImWidth / 2);
tr.setToRotation(angle, subImWidth / 2, subImWidth / 2);
g.drawImage(nameSubIms[i][j][0], tr, this);
// System.out.println(nameSubIms[i][j][k]+" "+subImWidth);
}
}
}
}
@Override
public void paint(Graphics g) {
// final float alphaLow = 0.7f;
super.paint(g);
g.drawImage(bgIm, 0, 0, this);//绘制背景
Graphics2D g2 = (Graphics2D) (g);
if (act) {//动画时
currentFrame--;
direction++;//改变分割图片的方向
if (direction >= directionNum)
direction = 0;
//绘制分割后的图片
for (int j = 0; j < nameSubIms.length; j++) {
for (int k = 0; k < nameSubIms[j].length; k++) {
int xPos = xCenter + posCenters[j][k].x * Math.abs(currentFrame) / coefficient
- (subImWidth >> 1);// + (int) ((Math.random() -
// 0.5) * subImWidth);
int yPos = yCenter + posCenters[j][k].y * Math.abs(currentFrame) / coefficient
- (subImWidth >> 1);// + (int) ((Math.random() -
// 0.5) * subImWidth);
tr.setToTranslation(xPos, yPos);
if (rotate)
g2.drawImage(nameSubIms[j][k][direction], tr, this);
else
g2.drawImage(nameSubIms[j][k][0], tr, this);
;
}
}
} else {
// ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
// alphaLow);
// g2.setComposite(ac);
g2.drawImage(nameIm, x, y, this);
}
}
public void restart() {
if (subImWidth != nameSubIms[0][0][0].getWidth())//改变分割图像大小,重新初始化
init();
act = true;
currentFrame = frames;
while(currentFrame > -coefficient) {
try {
Thread.sleep(1000 / frameRate);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
repaint();
}
act = false;
repaint();
}
@Override
public void update(Graphics g) {
repaint();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(bgIm.getWidth(), bgIm.getHeight());
}
}