使用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好像是不受官方支持的,所以访问的时候会有一定的限制,可能编译会通不过,编译器会报错。看图
从国外网站找了找,发现是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编译错误
转载声明:本站文章若无特别说明,皆为原创,转载请注明来源:三十岁,谢谢!^^
分享到: | |
没有评论