Java使用图片自定义登录窗体
2016-06-03 10:49
435 查看
一、问题概述
Java是一门面向对象的编程语言,从出版至今,Java对其自身不断改进,Java的图形界面编程也做的越来越好,从AWT到更高级的Swing。但是,我们的需求永远是无法满足的,有时候我们需要自定义窗体,特别是一张漂亮的图片做一个窗体,那就再好不过了。那么,今天我就把用图片自定义应用窗体的方法分享给大家。
二、实现方法
1、用图片自定义应用窗体效果图;
2、创建一个类继承Swing中JFrame,然后定义一个BufferedImage变量,用于设定应用窗体背景图,在定义一个ImageIcon变量,用来保存你自定义的图片;在根据图1的样子,分别定义两个JLable,一个JTextField,一个JPasswordField,三个JButton。图片的导入和组件的创建不在鳌诉。
说明:图1右上角的红色关闭窗体按钮是自定义图片p上去的,然后通过Java的鼠标事件来判断鼠标点击的范围是否在红色区域内,如果觉得上诉的按钮或者是文本框不好看,也可以用自定义的图片去定义样式,此内容不再本教程讲解范围之类,具体方法请参阅我博客“Java自定义图片按钮”。
下面给出变量代码:
如果不使用JLable 来显示background图片,效果是这样的:
为方便测试,再此给出图片原图(P得不是很好,P得越清晰,就越不容易产生锯齿和白边哦):
3、创建一个和图片形状一样的窗体;
4、初始化窗体并显示
5、事件响应
三、小结
1、要实现自定义图片创建窗体,必须使用Java的第三方库的类“AWTUtilities”,如果你在使用时发现找不到此类,原因可能是你的JDK版本过低或者是你配置时没有导入第三方库。如无法解决,请联系我。
2、创建窗体时,采用绝对布局,要将原有的默认布局置空,否则很难控制。具体原因可以自己去尝试。
3、如果要实现窗体透明,图片必须使用png格式,小编曾经就是实现不了透明效果头疼了很久,最后发现只有png格式的图片可以实现透明效果。
4、部分源码参考网络和前辈博客,感谢提供相应资料。
5、由于小编初出茅庐,文中难免有错误之处,还望指正,谢谢合作。
四、完整源码
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 = 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; } /** * 取得透明度 * @param pixel * @return */ private int getAlpha(int pixel) { return (pixel >> 24) & 0xff; }
4、初始化窗体并显示
/** * 构造方法 * 初始化窗体 */ public LoginWindow() { super(); sql = new DriveSQL(); background = new ImageIcon("image1\\login1.png"); JLabel back = new JLabel(background); back.setBounds(0, 0, background.getIconWidth(), background.getIconHeight()); /* * 首先初始化一张图片,我们可以选择一张有透明部分的不规则图片 * (要想图片能够显示透明,必须使用PNG格式的图片) */ MediaTracker mt = new MediaTracker(this); try { img = ImageIO.read(new File("image1\\login1.png")); } catch (IOException e1) { e1.printStackTrace(); } mt.addImage(img, 0); try { mt.waitForAll(); // 开始加载由此媒体跟踪器跟踪的所有图像 } catch (InterruptedException e) { e.printStackTrace(); } try { initialize(); // 窗体形状初始化 } catch (IOException e) { e.printStackTrace(); } addMenu(); this.add(back); this.setVisible(true); } /** * 组件初始化 */ public void addMenu() { //采用绝对布局,要将默认布局置空 this.setLayout(null); //设置字体 Font font = new Font("", 0, 18); userLabel.setForeground(Color.white); passwordLabel.setForeground(Color.white); userLabel.setFont(font); passwordLabel.setFont(font); passwordText.setEchoChar('*'); userLabel.setBounds(80, 120, 100, 50); passwordLabel.setBounds(80, 160, 100, 50); userText.setBounds(140, 130, 170, 30); passwordText.setBounds(140, 170, 170, 30); okbtn.setBounds(81, 210, 60, 25); resert.setBounds(166, 210, 60, 25); register.setBounds(251, 210, 60, 25); this.add(userLabel); this.add(userText); this.add(passwordLabel); this.add(passwordText); this.add(okbtn); this.add(resert); this.add(register); okbtn.addMouseListener(new OwnListener()); resert.addMouseListener(new OwnListener()); register.addMouseListener(new OwnListener()); userText.addKeyListener(new KeyOwnListener()); passwordText.addKeyListener(new KeyOwnListener()); }
5、事件响应
/** * 事件监听 * @author Admin * */ private class OwnListener extends MouseAdapter { public void mousePressed(MouseEvent e) { origin.x = e.getX(); origin.y = e.getY(); } // 窗体上单击鼠标右键关闭程序 public void mouseClicked(MouseEvent e) { //如果点击的区域位于右上角红色按钮,则关闭程序 if (new Circle(350, 63, 11).contants(e.getX(), e.getY())) { System.exit(0); } else if (e.getSource() == okbtn) { //验证用户是否合法,并打开主程序 } else if (e.getSource() == resert) { userText.setText(""); passwordText.setText(""); } else if (e.getSource() == register) { //打开注册页面 } } public void mouseReleased(MouseEvent e) { super.mouseReleased(e); } }
三、小结
1、要实现自定义图片创建窗体,必须使用Java的第三方库的类“AWTUtilities”,如果你在使用时发现找不到此类,原因可能是你的JDK版本过低或者是你配置时没有导入第三方库。如无法解决,请联系我。
2、创建窗体时,采用绝对布局,要将原有的默认布局置空,否则很难控制。具体原因可以自己去尝试。
3、如果要实现窗体透明,图片必须使用png格式,小编曾经就是实现不了透明效果头疼了很久,最后发现只有png格式的图片可以实现透明效果。
4、部分源码参考网络和前辈博客,感谢提供相应资料。
5、由于小编初出茅庐,文中难免有错误之处,还望指正,谢谢合作。
四、完整源码
import java.awt.Color; import java.awt.Font; import java.awt.Image; import java.awt.MediaTracker; import java.awt.Point; import java.awt.Rectangle; import java.awt.Shape; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.awt.geom.Area; import java.awt.image.BufferedImage; import java.awt.image.PixelGrabber; import java.io.File; import java.io.IOException; import java.util.ArrayList; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPasswordField; import javax.swing.JTextField; import com.assistclass.Circle; import com.data.Reader; import com.frame.MainFrame; import com.sqlservice.DriveSQL; import com.sun.awt.AWTUtilities; /** * 用户登录窗体 * @author Admin * */ public class LoginWindow extends JFrame { private static final long serialVersionUID = 1L; private Point origin; // 用于移动窗体 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("注册"); /** * 初始化窗体 */ public LoginWindow() { super(); background = new ImageIcon("image1\\login1.png"); JLabel back = new JLabel(background); back.setBounds(0, 0, background.getIconWidth(), background.getIconHeight()); /* * 首先初始化一张图片,我们可以选择一张有透明部分的不规则图片 * (要想图片能够显示透明,必须使用PNG格式的图片) */ MediaTracker mt = new MediaTracker(this); try { img = ImageIO.read(new File("image1\\login1.png")); } catch (IOException e1) { e1.printStackTrace(); } mt.addImage(img, 0); try { mt.waitForAll(); // 开始加载由此媒体跟踪器跟踪的所有图像 } catch (InterruptedException e) { e.printStackTrace(); } try { initialize(); // 窗体形状初始化 } catch (IOException e) { e.printStackTrace(); } addMenu(); this.add(back); this.setVisible(true); } /** * 组件初始化 */ public void addMenu() { this.setLayout(null); //设置字体 Font font = new Font("", 0, 18); userLabel.setForeground(Color.white); passwordLabel.setForeground(Color.white); userLabel.setFont(font); passwordLabel.setFont(font); passwordText.setEchoChar('*'); userLabel.setBounds(80, 120, 100, 50); passwordLabel.setBounds(80, 160, 100, 50); userText.setBounds(140, 130, 170, 30); passwordText.setBounds(140, 170, 170, 30); okbtn.setBounds(81, 210, 60, 25); resert.setBounds(166, 210, 60, 25); register.setBounds(251, 210, 60, 25); this.add(userLabel); this.add(userText); this.add(passwordLabel); this.add(passwordText); this.add(okbtn); this.add(resert); this.add(register); okbtn.addMouseListener(new OwnListener()); resert.addMouseListener(new OwnListener()); register.addMouseListener(new OwnListener()); userText.addKeyListener(new KeyOwnListener()); passwordText.addKeyListener(new KeyOwnListener()); userText.setText("20160601"); passwordText.setText("84878323"); } /** * 创建和图片形状一样的窗体 * @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 = 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; } /** * 取得透明度 * @param pixel * @return */ private int getAlpha(int pixel) { return (pixel >> 24) & 0xff; } /** * 事件监听 * @author Admin * */ private class OwnListener extends MouseAdapter { public void mousePressed(MouseEvent e) { origin.x = e.getX(); origin.y = e.getY(); } // 窗体上单击鼠标右键关闭程序 public void mouseClicked(MouseEvent e) { //如果点击的区域位于右上角红色按钮,则关闭程序 if (new Circle(350, 63, 11).contants(e.getX(), e.getY())) { System.exit(0); } else if (e.getSource() == okbtn) { //验证用户是否合法,合法打开主程序 } else if (e.getSource() == resert) { userText.setText(""); passwordText.setText(""); } else if (e.getSource() == register) { //打开注册页面 } } public void mouseReleased(MouseEvent e) { super.mouseReleased(e); } } /** * 监听键盘Enter键,实现Enter登录 * @author Admin * */ private class KeyOwnListener extends KeyAdapter { public void keyPressed(KeyEvent e) { if (10 == e.getKeyCode()) { //验证用户是否合法,合法打开主程序 } } } }
相关文章推荐
- Qt4下创建自定义窗体
- WinForm自定义窗体
- SpringMvc入门指南(必看)
- Myeclipse提示:The import javax.servlet cannot be resolved
- Struts2 深入理解
- Spring视频
- java类变量、类方法
- Java中的IO笔记Mars(1)(2)
- myeclipse在编写jsp文件时,光标乱跳
- Java输出数组
- java查找字符串中的包含子字符串的个数实现代码
- java代码主动消费消息ActiveMQ消息{StringMessage}
- shiro表单认证(系统默认的form认证器)
- spring mvc与html中处理引用js等静态文件的问题
- 使用XFire+Spring构建Web Service(一)——helloWorld篇
- worldwind java对tile服务(谷歌、必应、opensteetmap、高德……)的支持
- 多线程学习(十二)新特征-有返回值的线程
- [java源码分析]HashMap源码分析
- Example of BeanFactoryAware in Spring--转
- 02、eclipse 中使用maven