一、问题概述
Java是一门面向对象的编程语言,从出版至今,Java对其自身不断改进,Java的图形界面编程也做的越来越好,从AWT到更高级的Swing。但是,我们的需求永远是无法满足的,有时候我们需要自定义窗体,特别是一张漂亮的图片做一个窗体,那就再好不过了。那么,今天我就把用图片自定义应用窗体的方法分享给大家。
二、实现方法
1、用图片自定义应用窗体效果图;
图1 Java使用图片自定义应用窗体效果图
2、创建一个类继承Swing中JFrame,然后定义一个BufferedImage变量,用于设定应用窗体背景图,在定义一个ImageIcon变量,用来保存你自定义的图片;在根据图1的样子,分别定义两个JLable,一个JTextField,一个JPasswordField,三个JButton。图片的导入和组件的创建不在鳌诉。
说明:图1右上角的红色关闭窗体按钮是自定义图片p上去的,然后通过Java的鼠标事件来判断鼠标点击的范围是否在红色区域内,如果觉得上诉的按钮或者是文本框不好看,也可以用自定义的图片去定义样式,此内容不再本教程讲解范围之类,具体方法请参阅我博客“Java自定义图片按钮”。
下面给出变量代码:
// 用来设定窗体不规则样式的图片,这里只用它来创建窗体形状
private BufferedImage img;
//用它来显示这张图片
private ImageIcon background;
//用户名输入框
private JTextField userText = new JTextField(30);
//密码输入框
private JPasswordField passwordText = new JPasswordField(30);
private JLabel userLabel = new JLabel("账 号:");
private JLabel passwordLabel = new JLabel("密 码: ");
private JButton okbtn = new JButton("确定");
private JButton resert = new JButton("重置");
private JButton register = new JButton("注册");
// 记录窗体移动的坐标
private Point origin;
如果不使用JLable 来显示background图片,效果是这样的:
图2 未设置背景图像效果图
为方便测试,再此给出图片原图(P得不是很好,P得越清晰,就越不容易产生锯齿和白边哦):
图3 应用原图
3、创建一个和图片形状一样的窗体;
/**
* 创建和图片形状一样的窗体
* 并监听窗体移动事件
* @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);
this.setAlwaysOnTop(true);
// 由于取消了默认的窗体结构,所以我们要手动设置一下移动窗体的方法
this.addMouseListener(new OwnListener());
//监听鼠标移动事件
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
* @return
*/
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 =