|
java程序的外表总是一板一眼的,看多了难免审美疲劳,能不能使我们的JAVA程序外观变得更美观更独特呢?答案是肯定的,我们可以让JAVA程序根据图片来生成自定义的不规则窗体。比如下图的这种外观:
图中的这个人物(蕾米莉亚)便是定义好的不规则窗体,怎么样?很漂亮吧!那么让我们开始学习吧。
首先要说明一下,本方法是基于com.sun.awt.AWTUtilities这个类实现的,而这个类只能在jdk-6u10版本以后的版本才能体现出来的,在本文中讨论的所有 API 在新 com.sun.awt.AWTUtilities 类中出现,该类不是官方支持的部分 API。它在 Java SE 7 中的位置最有可能发生改变,签名方法可能在现在和最终的 Consumer JRE 发行之间发生轻微变化。
所以当你的JDK版本不匹配的时候需要你将JDK插件更新。
地址: http://java.sun.com/javase/downloads/index.jsp
=================================================================
好了,准备工作妥当,下面就让我们通过代码来学习根据图片制作不规则窗体的方法。
IrregularFormSample.java- import java.awt.Graphics;
- import java.awt.Image;
- import java.awt.MediaTracker;
- import java.awt.Point;
- import java.awt.Rectangle;
- import java.awt.Shape;
- import java.awt.Toolkit;
- import java.awt.event.MouseAdapter;
- import java.awt.event.MouseEvent;
- import java.awt.event.MouseMotionAdapter;
- import java.awt.geom.Area;
- import java.awt.image.PixelGrabber;
- import java.io.IOException;
- import java.util.ArrayList;
- import javax.swing.JFrame;
- import com.sun.awt.AWTUtilities;
- /**
- * 不规则窗体示例
- * @author Hexen
- */
- public class IrregularFormSample extends JFrame {
- private static final long serialVersionUID = 1L;
- private Point origin; //用于移动窗体
- private Image img; //用来设定窗体不规则样式的图片
- public IrregularFormSample() {
- super();
-
- /* 首先初始化一张图片,我们可以选择一张有透明部分的不规则图片
- * (当然我们要选择支持Alpha(透明)层的图片格式,如PNG),这张
- * 图片将被用来生成与其形状相同的不规则窗体
- */
- MediaTracker mt=new MediaTracker(this);
- img=Toolkit.getDefaultToolkit().createImage("remi.png");
- mt.addImage(img, 0);
- try {
- mt.waitForAll();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- try {
- initialize();//窗体初始化
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * 窗体初始化
- * @throws IOException
- */
- private void initialize() throws IOException {
- //设定窗体大小和图片一样大
- this.setSize(img.getWidth(null), img.getHeight(null));
- //设定禁用窗体装饰,这样就取消了默认的窗体结构
- this.setUndecorated(true);
- //初始化用于移动窗体的原点
- this.origin=new Point();
-
- //调用AWTUtilities的setWindowShape方法设定本窗体为制定的Shape形状
- AWTUtilities.setWindowShape(this,getImageShape(img));
- //设定窗体可见度
- AWTUtilities.setWindowOpacity(this, 0.8f);
-
- this.setLocationRelativeTo(null);
-
- //由于取消了默认的窗体结构,所以我们要手动设置一下移动窗体的方法
- addMouseListener(
- new MouseAdapter(){
- public void mousePressed(MouseEvent e){
- origin.x = e.getX();
- origin.y = e.getY();
- }
- //窗体上单击鼠标右键关闭程序
- public void mouseClicked(MouseEvent e) {
- if(e.getButton()==MouseEvent.BUTTON3)
- System.exit(0);
- }
- public void mouseReleased(MouseEvent e) {
- super.mouseReleased(e);
- }
- @Override
- public void mouseEntered(MouseEvent e) {
- repaint();
- }
- }
- );
- addMouseMotionListener(
- new MouseMotionAdapter(){
- public void mouseDragged(MouseEvent e){
- Point p = getLocation();
- setLocation(p.x + e.getX() - origin.x, p.y + e.getY() - origin.y );
- }
- }
- );
- }
-
- /**
- * 将Image图像转换为Shape图形
- * @param img
- * @param isFiltrate
- * @return Image图像的Shape图形表示
- * @author Hexen
- */
- public Shape getImageShape(Image img) {
- ArrayList<Integer> x=new ArrayList<Integer>();
- ArrayList<Integer> y=new ArrayList<Integer>();
- int width=img.getWidth(null);//图像宽度
- int height=img.getHeight(null);//图像高度
- //筛选像素
- //首先获取图像所有的像素信息
- PixelGrabber pgr = new PixelGrabber(img, 0, 0, -1, -1, true);
- try {
- pgr.grabPixels();
- } catch (InterruptedException ex) {
- ex.getStackTrace();
- }
- int pixels[] = (int[]) pgr.getPixels();
-
- //循环像素
- for (int i = 0; i < pixels.length; i++) {
- //筛选,将不透明的像素的坐标加入到坐标ArrayList x和y中
- int alpha = getAlpha(pixels[i]);
- if (alpha == 0){
- continue;
- }else{
- x.add(i%width>0 ? i%width-1:0);
- y.add(i%width==0 ? (i==0 ? 0:i/width-1):i/width);
- }
- }
-
- //建立图像矩阵并初始化(0为透明,1为不透明)
- int[][] matrix=new int[height][width];
- for(int i=0;i<height;i++){
- for(int j=0;j<width;j++){
- matrix[i][j]=0;
- }
- }
-
- //导入坐标ArrayList中的不透明坐标信息
- for(int c=0;c<x.size();c++){
- matrix[y.get(c)][x.get(c)]=1;
- }
-
- /* 由于Area类所表示区域可以进行合并,我们逐一水平"扫描"图像矩阵的每一行,
- * 将不透明的像素生成为Rectangle,再将每一行的Rectangle通过Area类的rec
- * 对象进行合并,最后形成一个完整的Shape图形
- */
- Area rec=new Area();
- int temp=0;
-
- for(int i=0;i<height;i++){
- for(int j=0;j<width;j++){
- if(matrix[i][j]==1){
- if(temp==0)
- temp=j;
- else if(j==width){
- if(temp==0){
- Rectangle rectemp=new Rectangle(j,i,1,1);
- rec.add(new Area(rectemp));
- }else{
- Rectangle rectemp=new Rectangle(temp,i,j-temp,1);
- rec.add(new Area(rectemp));
- temp=0;
- }
- }
- }else{
- if(temp!=0){
- Rectangle rectemp=new Rectangle(temp,i,j-temp,1);
- rec.add(new Area(rectemp));
- temp=0;
- }
- }
- }
- temp=0;
- }
- return rec;
- }
-
- /**
- * 获取像素的Alpha值
- * @param pixel
- * @return 像素的Alpha值
- */
- private int getAlpha(int pixel) {
- return (pixel >> 24) & 0xff;
- }
-
-
- /* 我们可以选择在窗体上绘制图片,是窗体完全呈现出图片的样式,
- * 当然我们也可以根据需要不绘制它,而采取其他操作
- */
- @Override
- public void paint(Graphics g) {
- super.paint(g);
- g.drawImage(img, 0, 0, null);
- }
-
- public static void main(String[] args) {
- IrregularFormSample sample = new IrregularFormSample();
- sample.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- sample.setVisible(true);
- }
- }
复制代码
使用这种方法,我们可以自由的定义窗体外观,使我们的JAVA程序更加美观。现在就去尝试一下吧! |
|