众所周知,Java的默认窗口使用的是系统默认样式,那么我们如何自己定义样式使其更好看呢?下面我就来分享一下如何自定义样式。
效果:
先新建一个窗口实例并设定基本属性,需要将窗口去边框处理:
JFrame frame = new JFrame();
frame.setSize(400, 235);
// 窗口居中
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation((screenSize.width - frame.getWidth()) / 2, (screenSize.height - frame.getHeight()) / 2);
frame.setUndecorated(true); // 窗口去边框
然后通过下列代码实现将任意图片作为窗口背景:
JLabel backgroundLabel = new JLabel(new ImageIcon("res\\bg1.png")); // 把一个ImageIcon对象加到一个名JLabel实例中里
backgroundLabel.setBounds(0, 0, frame.getWidth(), frame.getHeight()); // 设置标签大小
((JPanel) frame.getContentPane()).setOpaque(false); // 将窗口容器设置为透明以显示背景
frame.getLayeredPane().add(backgroundLabel, Integer.valueOf(Integer.MIN_VALUE)); // 将上述图片JLabel实例加入到窗体最底层作为背景
可以看到我们使用的是相对路径,是相对我们软件导出后的jar文件的运行路径。而在eclipse ide中,工程文件夹的bin文件夹就可以等效为我们导出的jar文件。
但发现我们的窗口无法拖动。现在就要加入一段代码实现拖动。
先在我们的类里面定义两个全局变量作为鼠标位置:
private int mouseAtX;
private int mouseAtY;
然后在主方法加入如下代码:
jf.addMouseListener(new MouseAdapter() { // 设置窗口可拖动,添加监听器
public void mousePressed(MouseEvent e) { // 获取点击鼠标时的坐标
mouseAtX = e.getPoint().x;
mouseAtY = e.getPoint().y;
}
});
jf.addMouseMotionListener(new MouseMotionAdapter() { // 设置拖拽后,窗口的位置
public void mouseDragged(MouseEvent e) {
jf.setLocation(e.getXOnScreen() - mouseAtX, e.getYOnScreen() - mouseAtY);
}
});
窗口就做出来了。
现在添加组件,按钮为了好看需要去按钮边框和设置按钮背景透明,并加入贴图,如下:
JButton close = new JButton(buttonc); //实例化按钮对象并加入上面的贴图
close.setContentAreaFilled(false); //设置按钮背景透明
close.setBorderPainted(false); //去掉按钮边框
创建标签文本:
JLabel frtitle=new JLabel("窗口标题");
通常使用JPanel面板对象加入,规整并布局组件,再加入到窗口中,如下:
JPanel p = new JPanel(); //实例化JPanel对象
p.setLayout(null);
p.add(frtitle);
p.add(close);
jf.getContentPane().add(p);
但是运行后我们失望地发现:
背景没了!
那是因为JPanel也有一个不透明的背景,加入到窗口后遮挡了背景,只需一行代码设置面板透明即可:
p.setOpaque(false); //面板设置为透明以显示背景
窗口就做完了!
最后我写了两个方法可以用于设定JFrame和JDialog的背景图:
/**
* 设定JFrame窗口的背景图片
*
* @param frame 待设定的窗口
* @param image 背景图片
*/
public static void setFrameBackground(JFrame frame, ImageIcon image) {
JLabel backgroundLabel = new JLabel(image);
backgroundLabel.setBounds(0, 0, frame.getWidth(), frame.getHeight());
((JPanel) frame.getContentPane()).setOpaque(false);
frame.getLayeredPane().add(backgroundLabel, Integer.valueOf(Integer.MIN_VALUE));
}
/**
* 设置JDialog对话窗的背景图片
*
* @param dialog 待设定对话窗
* @param image 背景图片
*/
public static void setDialogBackground(JDialog dialog, ImageIcon image) {
JLabel backgroundLabel = new JLabel(image);
backgroundLabel.setBounds(0, 0, dialog.getWidth(), dialog.getHeight());
((JPanel) dialog.getContentPane()).setOpaque(false);
dialog.getLayeredPane().add(backgroundLabel, Integer.valueOf(Integer.MIN_VALUE));
}
传入窗口实例和ImageIcon实例即可。ImageIcon实例即为图片对象,可以用路径形式创建也可以用URL实例创建:
ImageIcon image = new ImageIcon("res\\bg1.png"); // 以当前路径下res\\bg1.png为图片创建ImageIcon对象
URL imageUrl = Main.class.getResource("/res/bg1.png"); // 获取jar包中的根目录下的res/bg1.png作为图片url,Main为我当前的类名
ImageIcon image = new ImageIcon(imageUrl); // 以url构建图片对象
这用于两种不同情况,前者是图片资源在jar包外部,后者是在jar包内部。