https://blog.csdn.net/qq_32006373/article/details/49659129
一、JFrame 的层次结构
我们通过两个图来说明一下 JFrame 的层次结构:
从视觉效果来看(从 View 层来看),一个 JFrame 的结构是这样的:


可以看出,
Frame 的最底层是 RootPane,
然后是 LayeredPane
再上面就是 ContentPane
最顶层是 GlassPane
最顶层的 GlassPane 默认是透明的,
关于 GlassPane 这个层次,其实有很多可以利用的技巧,以后我再慢慢告诉大家,
今天说我们的重点:ContentPane
可以看出,这个 ContentPane 就是默认盛放控件的那个层次,
那 ContentPane 在默认的情况下又是什么呢?
我们来看两个方法:
JFrame 中的 getContentPane:
public Container getContentPane() {
return getRootPane().getContentPane();
}
JRootPane 中的 createContentPane:
protected Container createContentPane() {
JComponent c = new JPanel();
……
……
return c;
}
可以明显的看出,默认的 ContentPane 就是一个 JPanel;
现在我们再来看另一张图,从模型的角度来看 JFrame 的层次:

可以看出,其实 ContentPane 是添加在 LayeredPane 上的一个控件。
而 LayeredPane 和 GlassPane 是直接添加在 RootPane 上的,
RootPane 直接添加在 JFrame 上。
其实你只要记住:
1、你现在不再需要去 getContentPane(),
2、ContentPane 默认是一个 JPanel ,
这两个结论就可以了……

二、java中如何对JFrame设置背景颜色及背景图片
setVisible()说明:当设置为flase时,组件本身及增加在该组件上的组件都不可见;
setOpaque()说明: 当设置为flase时,只针对设置了透明的组件,其他组件不受影响;
Java窗口是指JFrame或者Frame
其次,窗口背景颜色是指直接调用JFrame或者Frame的setBackground(Color color)方法设置后显示出来的颜色。其实,J在你直接调用这个方法后,你的确设置了背景颜色,而你看到的却不是直接的JFrame或者Frame,而是JFrame.getContentPane().而JFrame上的contentPane默认是Color.WHITE的,所以,无论你对JFrame或者Frame怎么设置背景颜色,你看到的都只是contentPane.
最后,讲解决办法:
办法A:在完成初始化,调用getContentPane()方法得到一个contentPane容器,然后将其设置为不可见,即setVisible(false)。这样,你就可以看到JFrame的庐山真面貌啦!
核心代码this.getContentPane().setVisible(false);//得到contentPane容器,设置为不可见
方法B:将contentPane的颜色设置为你想要的颜色,而不是对JFrame本身设置;
核心代码:this.getContentPane().setBackground(Color.red);//设置contentPane为红色
将核心代码替换方法A核心代码即可实现
方法C:为JFrame添加一个Panel或者JLabel等其他组件,设置其颜色为你想要的颜色,然后将其覆盖JFrame窗口即可
JFrame默认是BorderLayout
JPanel默认是FlowLayout
1.JFrame设置背景色,注意体会注释的
package com.tools; import java.awt.Color;import javax.swing.JFrame;
public class Test extends JFrame
{
public static void main(String[] args)
{
new Test();
}
public Test()
{
this.setSize(400,300);
this.setLocation(400,300);
this.setBackground(Color.blue);
this.getContentPane().setBackground(Color.red);
this.getContentPane().setVisible(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}
2.给JFrame设置背景图片。
方法1:通过在JFrame中添加一个JPanel,背景图片放在JPanel上来实现。代码如下:
import java.awt.*;
import javax.swing.*;
public class Test extends JFrame
{
Container ct;
BackgroundPanel bgp;
JButton jb;
public static void main(String[] args)
{
new Test();
}
public Test()
{
ct=this.getContentPane();
this.setLayout(null);
bgp=new BackgroundPanel((new ImageIcon("images\\background.jpg")).getImage());
bgp.setBounds(0,0,400,300);
ct.add(bgp);
jb=new JButton("测试按钮");
jb.setBounds(60,30,160,30);
ct.add(jb);
this.setSize(400,300);
this.setLocation(400,300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}
class BackgroundPanel extends JPanel
{
Image im;
public BackgroundPanel(Image im)
{
this.im=im;
this.setOpaque(true);
}
public void paintComponent(Graphics g)
{
super.paintComponents(g);
g.drawImage(im,0,0,this.getWidth(),this.getHeight(),this);
}
}
方法2:我们用JLayeredPane,JLayeredPane 为 JFC/Swing 容器添加了深度,允许组件在需要时互相重叠。Integer 对象指定容器中每个组件的深度,其中编号较高的组件位于其他组件之上

package com.swingpractise;
import javax.swing.*;
public class JFrameBackground4 extends JFrame
{
JLayeredPane layeredPane;
JPanel jp;
JLabel jl;
ImageIcon image;
JButton jb;
public static void main(String[] args)
{
new JFrameBackground4();
}
public JFrameBackground4()
{
layeredPane=new JLayeredPane();
image=new ImageIcon("images\\background.jpg");
jp=new JPanel();
jp.setBounds(0,0,image.getIconWidth(),image.getIconHeight());
jl=new JLabel(image);
jp.add(jl);
jb=new JButton("测试按钮");
jb.setBounds(100,100,100,100);
layeredPane.add(jp,JLayeredPane.DEFAULT_LAYER);
layeredPane.add(jb,JLayeredPane.MODAL_LAYER);
this.setLayeredPane(layeredPane);
this.setSize(image.getIconWidth(),image.getIconHeight());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocation(image.getIconWidth(),image.getIconHeight());
this.setVisible(true);
}
}


第二个程序和三个程序的窗体
Java中有关Frame背景的设置总结
我们在进行图形用户界面编程时,为了做出一个漂亮、个性化的界面,那么界的背景就必须考虑了。
要想灵活使用背景,就一定要对frame的基本有一些了解,因为在java编程中没有直接设置背景的有关方法,
了解一些基本知识后我们就可以随意设置背景了。
首先还是要了解框架JFrame中的层次结构。
JFrame中的层次分布及相对关系是:
最底层是:JRootPane;
第二层是:JlayerPane,这层上面包含一层ContentPane(默认不透明),也正是我们常说的内容面板。
所以一般我们拖放的控件就是在ContentPane层上。;
最上层就是:GlassPane(默认是透明的);
有了这些常识后我们就可以随意设计背景了。
在这里笔者提供两种方法为一个
frame设置一张背景图片。
方法一:
原理:
我们把图片放置在第二层:JlayerPane容器上,然后让最上层的:
ContentPane透明,这样就实现了背景的设置。(当然把图片放置最低层,让上面两层透明也是可以的)
具体步骤:
// 加载背景图片
ImageIcon bg = new ImageIcon(“background.jpg”);
// 把背景图片显示在一个标签里
JLabel label = new JLabel(bg);
//把标签的大小位置设置为图片刚好填充整个面
label.setBounds(0,0,bg.getIconWidth(),bg.getIconHeight());
//添加图片到frame的第二层
frame.getLayeredPane().add(label,newInteger(Integer.MIN_VALUE));
//获取frame的最上层面板为了设置其背景颜色(JPanel有设置透明的方法)
JPanel jp=(JPanel)frame.getContentPane();
jp.setOpaque(false); //设置透明
//测试用的JPanel
JPanel panel=new JPanel();
panel.setOpaque(false); //也要让他透明
panel.setLayout(null);
//为了使用按钮的定位
JButton button=new JButton(“OK”);
button.setSize(100, 20);
button.setLocation(100, 50);
panel.add(button);
frame.add(panel);
效果如图:
方法二:
原理:
我们直接在最上层容器内重写paintComponent(Graphics g)方法在容器中画一张图片。(这种方法很直观,原理很简单)
具体步骤:
只需要在构造JPanel时重写paintComponent(Graphics g)就ok了。
class PanelTest extends JPanel{
ImageIcon background = new ImageIcon(“background.jpg”);
//加载图片
Image im=Toolkit.getDefaultToolkit().getImage(“background.jpg”);
int h,w;
public void paintComponent(Graphics g) {
g.drawImage(im, 0, 0, null);
}
}
总结:
只要了解了基本原理我们就可以更随意一点设计我们的风格了,我在这了抛砖引玉,希望对初学者有所帮助。
感谢原文:https://blog.csdn.net/xietansheng/article/details/74366560
补充:
- 概述
官方JavaDocsApi: javax.swing.JLayeredPane
JLayeredPane,层级面板。
JLayeredPane为容器添加了深度,允许组件在需要时互相重叠。
JLayeredPane将深度范围按 层 划分,在同一层内又对组件按位置进一步划分,将组件放入容器时需要指定组件所在的层,以及组件在该层内的 位置(position/index)。
层的编号越大越显示在前面;同层内位置编号越大越靠近底部(位置编号取值范围: [-1, n - 1],n 表示层内组件数量,其中 -1 表示最底,0 表示最顶)。
通过 setLayer(Component c, int layer) 可设置组件所在的层数。
同一层内的组件,可通过调用 moveToFront(Component)、moveToBack(Component) 和 setPosition(int) 调整层内的位置。
PS: 添加到 JLayeredPane 内的组件需要明确指定组在位置和宽高,否则不显示(类似绝对布局)。
JLayeredPane 构造方法:
JLayeredPane()
JLayeredPane 常用方法:
void add(Component comp, Object layer)
void add(Component comp, Object layer, int position)
void setLayer(Component c, int layer)
void setLayer(Component c, int layer, int position)
void moveToFront(Component c)
void moveToBack(Component c)
void setPosition(Component c, int position)
2. 代码实例
package com.xiets.swing;
import javax.swing.*;
import java.awt.*;
public class Main {
public static void main(String[] args) {
JFrame jf = new JFrame("测试窗口");
jf.setSize(300, 300);
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JLayeredPane layeredPane = new JLayeredPane();
JPanel panel_100_1 = createPanel(Color.RED, "L=100, P=1", 30, 30, 100, 100);
layeredPane.add(panel_100_1, new Integer(100));
JPanel panel_200_0 = createPanel(Color.GREEN, "L=200, P=0", 70, 70, 100, 100);
layeredPane.add(panel_200_0, new Integer(200), 0);
JPanel panel_200_1 = createPanel(Color.CYAN, "L=200, P=1", 110, 110, 100, 100);
layeredPane.add(panel_200_1, new Integer(200), 1);
JPanel panel_300 = createPanel(Color.YELLOW, "L=300", 150, 150, 100, 100);
layeredPane.add(panel_300, new Integer(300));
jf.setContentPane(layeredPane);
jf.setVisible(true);
}
private static JPanel createPanel(Color bg, String text, int x, int y, int width, int height) {
JPanel panel = new JPanel(new GridLayout(1, 1));
panel.setBounds(x, y, width, height);
panel.setOpaque(true);
panel.setBackground(bg);
JLabel label = new JLabel(text);
label.setHorizontalAlignment(SwingConstants.CENTER);
label.setVerticalAlignment(SwingConstants.TOP);
panel.add(label);
return panel;
}
}
结果:

本人代码练习:
package test;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.*;
import javax.swing.JPanel;
public class TestAgain {
public static void main(String[] args) {
JFrame f1=new JFrame("Calculator");
f1.setBounds(0,0,400,200);
JPanel p1,p2,p3;
p1=new JPanel();
p2=new JPanel();
p3=new JPanel();
p1.setBounds(10,10,50,50);
p2.setBounds(20,20,50,50);
p3.setBounds(30,30,50,50);
p1.setBackground(Color.RED);
p2.setBackground(Color.YELLOW);
p3.setBackground(Color.BLUE);
JLayeredPane lay1=new JLayeredPane();
lay1.add(p1,new Integer(1));
lay1.add(p2,new Integer(1));
lay1.add(p3,new Integer(1));
lay1.setPosition(p3,new Integer(0));
f1.setLayeredPane(lay1);
((JPanel)(f1.getContentPane())).setOpaque(false);
f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f1.setVisible(true);
}
}
再补充:
感谢原文:https://blog.csdn.net/kewbblog/article/details/8625917
Swing的容器结构与JLayeredPane的使用
类层次结构图:
java.lang.Object
–java.awt.Compontent
–java.awt.Container
–javax.swing.JComponent
–javax.swing.JLayeredPane
我们可把Swing容器的结构看似如下图所示:
|Grass Pane
|
Root Pane|
| |Content Pane
|Layered Pane|
|Menu Bar
其中,Root Pane可以看成是虚拟的容器,包含着Grass Pane、Layered Pane、Content Pane与Menu Bar.Swing的容器包括JApplet ,JFrame,JDialog,JWindow与JInternalFrame都是构造在此结构上,JApplet、JFrame、JDialog、JWindow都是heavyweight容器,只 有JInternalFrame是lightweight容器。当我们要加入某个组件到Swing的容器中时,并不是直接加入到Root Pane,而是加入到 RootPane下面的某一成员(Layered Pane或Content Pane)
Content Pane与Menu Bar只是Layered Pane的其中一层,我们称此层为Frame-Content Layer.若你想知道Frame-Content Layer 在Layered Pane的层次是什么?你可以由JLayeredPane类中的Frame_Content_layer类常数取得。
补充:
持续组件居中方法:监听
