学会JavaSwing构建程序界面后,小伙伴们最大的困惑可能是“为什么我们做出来的界面那么丑、不跟市面流行的程序界面一样呢?”
像这个界面,我们发现标题栏跟默认状态不一样,关闭按钮的样式也变了。
实现的方法其实很简单,使用setUndecorated(true);取消窗体装饰,其他效果通过图片完成即可。
下面的代码实现了无标题栏窗体,使用背景拉伸的技术为处于上部分的面板设置了背景图片;实现了关闭按钮的鼠标经过以及鼠标单击事件;实现了鼠标拖拽新标题栏移动整个窗体的功能。
其他功能及特效大家可以自行实现。
Constants.java
/**
* @Description: 用来保存常量
* @author: 老九学堂·窖头
* @date: 2017年12月25日 下午2:47:31
* @version V1.0
* @Copyright: 2017 http://www.xuetang9.com Inc. All rights reserved.
*/
public class Constants {
/** 全局字体名称 */
public static String SysFontName = "宋体";
/** 登录窗体的宽 */
public static int Width_LoginFrame = 387;
/** 登录窗体的高 */
public static int Height_LoginFrame = 266;
}
LoginFrame.java
/**
* @Description: 登录界面
* @author: 老九学堂·窖头
* @date: 2017年12月25日 下午2:40:07
* @version V1.0
* @Copyright: 2017 http://www.xuetang9.com Inc. All rights reserved.
*/
public class LoginFrame extends JFrame{
private JPanel pnlTop = new TopPanel("images/sknin1.jpg");
private JPanel pnlMiddle = new JPanel();
private JPanel pnlBottom = new JPanel();
private JPanel contentPane = null;
private BorderLayout contentPaneLayout = null; //内容面板的边框布局
private Point mousePressedPoint; //点击pnlTop面板时记录下的鼠标坐标
public LoginFrame(){
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); //关闭窗体时什么也不做
setTitle("登录电脑管家"); //设置窗体标题
setSize(Constants.Width_LoginFrame, Constants.Height_LoginFrame); //这里的窗体大小可以参考图片素材的大小(界面素材需复制到images文件夹下)
initComponents(); //调用自定义方法初始化窗体上的组件
setLocationRelativeTo(null); //设置窗体居中
setUndecorated(true); //设置窗体无装饰为真
}
private void initComponents() {
contentPane = new JPanel();
contentPaneLayout = new BorderLayout();
contentPane.setLayout(contentPaneLayout);
/********************** start of 设置pnlTop相关控件 *************************/
JLabel lblTitle = new JLabel(" 登录电脑管家");
lblTitle.setFont(new Font(Constants.SysFontName, Font.PLAIN, 14));
lblTitle.setForeground(Color.WHITE);
//网格包布局
GridBagLayout pnlTopLayout = new GridBagLayout();
pnlTop.setLayout(pnlTopLayout);
pnlTop.add(lblTitle);
JLabel lblClose = new JLabel();
lblClose.setIcon(new ImageIcon("images/close.png"));
pnlTop.add(lblClose);
//设置网格包布局的规则
GridBagConstraints grConstraints = new GridBagConstraints();
grConstraints.insets = new Insets(0, 0, 0,245);//设置四方向边距
pnlTopLayout.setConstraints(lblTitle, grConstraints);//为控件设置新规则
//越过布局设置控件的宽高
pnlTop.setPreferredSize(new Dimension(Constants.Width_LoginFrame, 30));
contentPane.add(pnlTop, BorderLayout.NORTH);
lblClose.addMouseListener(new MouseAdapter() {//关闭按钮图片替换
ImageIcon icon = new ImageIcon("images/close.png");
@Override
public void mouseEntered(MouseEvent e) {
lblClose.setIcon(null);
lblClose.setForeground(Color.RED);
lblClose.setText("X"); //没有其他图片素材,使用X字母模拟实现切换效果
lblClose.setPreferredSize(new Dimension(icon.getIconWidth(), icon.getIconHeight()));
}
@Override
public void mouseExited(MouseEvent e) {
lblClose.setIcon(icon);
}
@Override
public void mouseClicked(MouseEvent e) {
int result = JOptionPane.showConfirmDialog(null, "确认关闭吗?", "窗口关闭",JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if(result == 0) System.exit(0);
}
});
pnlTop.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
//鼠标点击时先记录鼠标的坐标
mousePressedPoint = e.getPoint();
}
});
pnlTop.addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
//获得窗体当前的坐标
Point p = getLocation();
//设置窗体坐标:当前坐标+鼠标移动后的当前坐标-鼠标原坐标 == 当前坐标+鼠标移动距离
setLocation((int)(p.getX() + e.getX() - mousePressedPoint.getX()), (int)(p.getY() + e.getY() - mousePressedPoint.getY()));
}
});
/********************** end of 设置pnlTop相关控件 *************************/
this.setContentPane(contentPane);
}
class TopPanel extends JPanel{//重写上部面板(实现了背景图片拉伸效果)
private ImageIcon background;
public TopPanel(String backImagePath) {
if(null == backImagePath) return;
background = new ImageIcon(backImagePath);
}
@Override
protected void paintComponent(Graphics g) {//重绘组件
if(background == null) return;
//拉伸图片
g.drawImage(background.getImage(), 0, 0, Constants.Width_LoginFrame, background.getIconHeight(), null);
}
}
public static void main(String[] args) {
new LoginFrame().setVisible(true);
}
}