使用Swing布局打造仿QQ登录界面2.0:基础组件设定、鼠标操作与事件处理技巧全面解析
最编程
2024-02-06 09:19:24
...
package qqLayoutLoginDemo;
import java.awt.Image;
import java.util.HashMap;
import java.util.Map;
import javax.swing.ImageIcon;
/**
* 加载图片工具类,实现加载过的图片可以下次直接获取
* @author
*
*/
public class ImageUtil {
//定义Map集合(键:图片路径, 值 图片控件)
public static Map<String, ImageIcon> mapImage = new HashMap<String, ImageIcon>();
//获取图片控件
public static ImageIcon getImage(String path) {
//判断图片是否加载过
if(mapImage.containsKey(path)) { //加载过的图片,就直接返回图片控件
return mapImage.get(path);
}
//没有加载过的图片
ImageIcon image = new ImageIcon(path);
mapImage.put(path, image);
return image;
}
/**
* 缩放图片比例后,返回缩放后的图片控件
* @param image
* @param scale
*/
public static ImageIcon scaleImageIcon(Image image, double scale) {
//调用Image控件的方法
int newWidth = (int) (image.getWidth(null) * scale);
int newHigt = (int) (image.getHeight(null) * scale);
Image scaleImage = image.getScaledInstance(newWidth, newHigt, image.SCALE_DEFAULT);
//图标控件里放图片控件
return new ImageIcon(scaleImage);
}
}
package qqLayoutLoginDemo;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
/**
* qq登录界面布局管理类
* @author*/
public class QQLayoutLoginDesign extends JFrame{
//图片路径
private String ImagePath = "qqPhotos\\background.png";
//按钮图片路径
private String buttonPath = "qqPhotos\\close.png";
//鼠标接近时按钮图片路径
private String nearButtonPath = "qqPhotos\\near_close.png";
//头像路径
private String headerPath = "qqPhotos\\headerImage.png";
//内容面板
JPanel contentPane = null;
//添加按钮
JButton imageButton = null;
//添加带文本的注册标签控件
JLabel lblRegister = null;
public QQLayoutLoginDesign() {
//设置标题
setTitle("qq登录界面布局管理类");
//加载背景图片
ImageIcon imageBackground = ImageUtil.getImage(ImagePath);
//设置大小,与背景图片一样大
setSize(imageBackground.getIconWidth(), imageBackground.getIconHeight());
//居中
setLocationRelativeTo(null);
//内容面板
contentPane = (JPanel) getContentPane();
//其他部分的初始工作
initComponnets();
//设置退出模式
setDefaultCloseOperation(EXIT_ON_CLOSE);
//设置窗体为无修饰
setUndecorated(true);
}
private void initComponnets() {
//设置内容面板为无布局,后边有布局的,设置啥无布局哩
// contentPane.setLayout(null);
//设置背景图片
setBackground(ImagePath);
//设置上区域布局
initTopLayout();
//设置左区域布局
initLeftLayout();
//设置中间区域布局
initMiddleLayout();
//设置右区域布局
initRightLayout();
}
//上区域的布局--选择流式布局
private void initTopLayout() {
//创建面板,设置为流式布局,并且调用流式布局的属性设置向右对齐,方便添加关闭按钮
JPanel topPane = new JPanel();
topPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
//设置一下边框,方便观察
// topPane.setBorder(BorderFactory.createLineBorder(Color.black));
//设置布局面板大小
topPane.setPreferredSize(new Dimension(getWidth(), 54));
//添加按钮
imageButton = new JButton(new ImageIcon(buttonPath));
//设置按钮的空间大小
imageButton.setPreferredSize(new Dimension(40, 40));
//设置按钮图片,鼠标接近,按下的图片切换
imageButton.setRolloverIcon(new ImageIcon(nearButtonPath));
imageButton.setPressedIcon(new ImageIcon(buttonPath));
//取消掉按钮的边框
imageButton.setBorder(BorderFactory.createEmptyBorder());
//为按钮添加事件,提示框提醒用户是否关闭窗体
btnEvent();
//添加按钮到布局面板
topPane.add(imageButton);
//设置流式布局面板为透明
topPane.setOpaque(false);
//把流式布局的面板添加到内容面板,并且设置位置为边框的上边
contentPane.add(topPane, BorderLayout.NORTH);
}
//为按钮添加事件,提示框提醒用户是否关闭窗体
private void btnEvent() {
imageButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//以对话框形式提醒用户,这里调用了工具类JOptionPane的showConfirmDialog方法
int result = JOptionPane.showConfirmDialog(QQLayoutLoginDesign.this, "是否真的要残忍抛下小可爱");
//看返回值是否与工具类JOptionPane的属性OK_OPTION一致,是的话销毁控件对象
if(result == JOptionPane.OK_OPTION) {
QQLayoutLoginDesign.this.dispose();
}
}
});
}
private void initLeftLayout() {
//左区域设置为边框式布局
JPanel leftPane = new JPanel();
leftPane.setLayout(new BorderLayout());
//设置边框用来观察
// leftPane.setBorder(BorderFactory.createLineBorder(Color.black));
//设置布局大小
leftPane.setPreferredSize(new Dimension(82, getHeight()));
//添加带文本的注册标签控件
lblRegister = new JLabel("用户注册");
//设置字体前景色
lblRegister.setForeground(Color.GRAY);
lblRegister.setPreferredSize(new Dimension(100, 40));
//通过SwingConstants 的常量CENTER 设置位置居中
lblRegister.setHorizontalAlignment(SwingConstants.CENTER);
//设置字体
Font font = new Font("华文行楷", Font.BOLD, 16);
lblRegister.setFont(font);
//设置鼠标经过时变成手形,通过.setCursor(Cursor对象); 对象里传递参数Cursor工具类的HAND_CURSOR常量
lblRegister.setCursor(new Cursor(Cursor.HAND_CURSOR));
//添加鼠标接近、离开标签字体颜色改变事件
fontColorEvent();
//添加标签控件到布局面板,并且设置位置为边框的底部
leftPane.add(lblRegister, BorderLayout.SOUTH);
//设置布局面板为透明
leftPane.setOpaque(false);
//添加布局面板控件到内容面板中,并且设置位置为边框的左边
contentPane.add(leftPane, BorderLayout.WEST);
}
//添加鼠标接近、离开标签字体颜色改变事件
private void fontColorEvent() {
lblRegister.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
lblRegister.setForeground(Color.BLUE);
}
@Override
public void mouseExited(MouseEvent e) {
lblRegister.setForeground(Color.GRAY);
}
});
}
private void initMiddleLayout() {
//中间区域的布局面板
JPanel middlePane = new JPanel();
//默认就是流式布局
// middlePane.setLayout(new FlowLayout());
//设置布局大小
middlePane.setPreferredSize(new Dimension(360, getHeight()));
//设置观察边框
// middlePane.setBorder(BorderFactory.createEtchedBorder());
//头像面板(这方便以后更换头像标签)--这个过程头像位置不对,选择法1:添加空白的控件来挤压
JPanel pnlHeaderImage = new JPanel();
//设置头像面板大小
pnlHeaderImage.setPreferredSize(new Dimension(80, 80));
//设置头像面板的边框,方便观察
// pnlHeaderImage.setBorder(BorderFactory.createLineBorder(Color.black));
//头像标签
JLabel lblHeaderImage = new JLabel(new ImageIcon(headerPath));
//设置头像标签大小
lblHeaderImage.setPreferredSize(new Dimension(80, 80));
//空白控件
JLabel lblTemp = new JLabel();
//设置控件的大小
lblTemp.setPreferredSize(new Dimension(350, 43));
//设置控件边框,方便观察
// lblTemp.setBorder(BorderFactory.createLineBorder(Color.black));
//添加头像标签到头像面板
pnlHeaderImage.add(lblHeaderImage);
//添加空白控价到中间布局面板来挤压头像面板的位置
middlePane.add(lblTemp);
//设置头像面板为透明
pnlHeaderImage.setOpaque(false);
//添加头像面板到中间布局面板
middlePane.add(pnlHeaderImage);
//添加文本框
JTextField txtField = new JTextField();
//设置文本框的边框,方便观察
txtField.setBorder(BorderFactory.createLineBorder(Color.black));
//设置文本框大小
txtField.setPreferredSize(new Dimension(260, 40));
//添加文本框到中间布局---由于又出现位置偏差,这时候写得顺手就把文本框添加到布局面板,调节文本框在布局面板的位置
// middlePane.add(txtField);
JPanel pnlTxt = new JPanel();
//设置文本框布局面板的边框,方便观察
pnlTxt.setBorder(BorderFactory.createLineBorder(Color.black));
//设置文本框布局的一个大小
pnlTxt.setPreferredSize(new Dimension(360, getHeight()));
//添加文本框到文本框布局里
pnlTxt.add(txtField);
//设置文本框布局为透明
pnlTxt.setOpaque(false);
//添加文本框布局面板到中间布局面板
middlePane.add(pnlTxt);
//设置布局面板为透明
middlePane.setOpaque(false);
//添加布局面板到内容面板中,并且设置边框的中间位置
contentPane.add(middlePane, BorderLayout.CENTER);
}
private void initRightLayout() {
//右区域面板,默认布局--流式布局
JPanel pnlRight = new JPanel();
//设置布局面板大小
pnlRight.setPreferredSize(new Dimension(80, getHeight()));
//设置边框方便观察
// pnlRight.setBorder(BorderFactory.createLineBorder(Color.black));
//设置布局面板为透明
pnlRight.setOpaque(false);
//添加布局面板到内容面板,并且设置位置为边框的右边
contentPane.add(pnlRight, BorderLayout.EAST);
}
/**
* 设置自定义背景图片
*/
private void setBackground(String path) {
//获取背景图片
ImageIcon imageIcon = ImageUtil.getImage(path);
//通过标签控件封装图片标签后,添加到布局控件
JLabel jLabelImage = new JLabel(imageIcon);
//设置标签边界
jLabelImage.setBounds(0, 0, imageIcon.getIconWidth(), imageIcon.getIconHeight());
//添加至布局面板,z 轴 的距离new Integer(Integer.MIN_VALUE)
JLayeredPane layoutPane = getLayeredPane();
layoutPane.add(jLabelImage, new Integer(Integer.MIN_VALUE));
// contentPane.add(layoutPane);
//设置内容面板不透明为假
contentPane.setOpaque(false);
}
public static void main(String[] args) {
new QQLayoutLoginDesign().setVisible(true);
}
}