使用com.sun.awt.AWTUtilities制作不规则窗体以及处理出现的Eclipse编译错误  

Java也可以实现窗体的自定义效果,基于com.sun.awt.AWTUtilities类实现.而该类只能在jdk-6版本以及以后的版本才能体现出来的,在本文中讨论的所有 API 在新 com.sun.awt.AWTUtilities 类中出现,该类不是官方支持的部分 API。可能在 jdk-7 中的位置最有可能发生轻微改变。

三十岁

就是用一张背景透明的png格式的图片做的,下面贴代码

package test.c30;
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;
import javax.swing.SwingUtilities;

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("1.png");
        mt.addImage(img, 0);
        try {
            mt.waitForAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        try {
            initialize();// 窗体初始化
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 窗体初始化
     */
    private void initialize() throws IOException {
        // 设定窗体大小和图片一样大
        this.setSize(img.getWidth(null), img.getHeight(null));
        // 设定禁用窗体装饰,这样就取消了默认的窗体结构
        this.setUndecorated(true);
        // 设置该窗口总是在其它窗口的最上方
        this.setAlwaysOnTop(true);
        // 初始化用于移动窗体的原点
        this.origin = new Point();

        // 调用AWTUtilities的setWindowShape方法设定本窗体为制定的Shape形状
        AWTUtilities.setWindowShape(this, getImageShape(img));
        // 设定窗体可见度
        AWTUtilities.setWindowOpacity(this, 1.0f);

        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图形
     */
    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) {
                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];
        // 导入坐标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值
     */
    private int getAlpha(int pixel) {
        return (pixel >> 24) & 0xff;
    }

    /*
     * 我们可以选择在窗体上绘制图片,是窗体完全呈现出图片的样式, 当然我们也可以根据需要不绘制它,而采取其他操作
     */
    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);
    }
}

由于com.sun.awt.AWTUtilities好像是不受官方支持的,所以访问的时候会有一定的限制,可能编译会通不过,编译器会报错。看图

image

从国外网站找了找,发现是Eclipse标准的问题,解决方法如下

When using com.sun.awt.AWTUtilities, Eclipse gives a error: 
- Access restriction: The method setWindowOpacity(Window, float) from the type AWTUtilities is not accessible due to restriction on required library C:\Program Files\Java\jre6\lib\rt.jar
- Access restriction: The type AWTUtilities is not accessible due to restriction on required library C:\Program Files\Java\jre6\lib\rt.jar 
You can fix it like this:
Preferences -> Java -> Compiler -> Errors/Warnings -> Deprecated and restricted API ->
Forbidden reference -> change "error" to "warning" 

欢迎大佬支持本博客的发展 -- Donate --

本文链接:使用com.sun.awt.AWTUtilities制作不规则窗体以及处理出现的Eclipse编译错误

转载声明:本站文章若无特别说明,皆为原创,转载请注明来源:三十岁,谢谢!^^


分享到:          
  1. 没有评论

  1. 没有通告