感谢原文: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);//如果改为true那么就变成了红色。
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); //在这里随便找一张400*300的照片既可以看到测试结果。
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);
}
//Draw the back ground.
public void paintComponent(Graphics g)
{
super.paintComponents(g);
g.drawImage(im,0,0,this.getWidth(),this.getHeight(),this); }
}

方法2:我们用JLayeredPane,JLayeredPane 为 JFC/Swing 容器添加了深度,允许组件在需要时互相重叠。Integer 对象指定容器中每个组件的深度,其中编号较高的组件位于其他组件之上

/**
* 给JFrame 添加一个背景图案。
*/
package com.swingpractise;
import javax.swing.*;
public class JFrameBackground4 extends JFrame
{
//创建一个JLayeredPane用于分层的。
JLayeredPane layeredPane;
//创建一个Panel和一个Label用于存放图片,作为背景。
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);
// jl.setBounds(0,0,image.getIconWidth(),image.getIconHeight());
jp.add(jl); //创建一个测试按钮
jb=new JButton("测试按钮");
jb.setBounds(100,100,100,100); //将jp放到最底层。
layeredPane.add(jp,JLayeredPane.DEFAULT_LAYER);
//将jb放到高一层的地方
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

补充:

Java Swing 图形界面开发(目录)

  1. 概述

    官方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 常用方法:

/**
* 添加组件到指定的层(默认放到层内最底部),参数说明:
* comp: 待添加的组件
* layer: 所在的层, 层数是int类型, 由于该方法与另一个 add(Component, int) 方法类似, 直接使用会有冲突, 所以使
* 用该方法传递 layer 参数时, 必须使用 Integer 类型来明确调用的是下面 add(Component, Object) 方法。
*/
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) // 设置组件在其所在层的位置,其中 position 取值范围为: [-1, n - 1],n 表示层内组件数量,其中 -1 表示最底,0 表示最顶
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(); // 层数: 100
JPanel panel_100_1 = createPanel(Color.RED, "L=100, P=1", 30, 30, 100, 100);
layeredPane.add(panel_100_1, new Integer(100)); // 层数: 200, 层内位置: 0(层内顶部)
JPanel panel_200_0 = createPanel(Color.GREEN, "L=200, P=0", 70, 70, 100, 100);
layeredPane.add(panel_200_0, new Integer(200), 0); // 层数: 200, 层内位置: 1
JPanel panel_200_1 = createPanel(Color.CYAN, "L=200, P=1", 110, 110, 100, 100);
layeredPane.add(panel_200_1, new Integer(200), 1); // 层数: 300
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);
} /**
* 创建一个面板容器(容器内包含一个水平方向居中, 垂直方向顶部对其的标签)
*
* @param bg 容器背景
* @param text 容器内标签显示的文本
* @param x 容器的横轴坐标
* @param y 容器的纵坐标
* @param width 容器的宽度
* @param height 容器的高度
* @return
*/
private static JPanel createPanel(Color bg, String text, int x, int y, int width, int height) {
// 创建一个 JPanel, 使用 1 行 1 列的网格布局
JPanel panel = new JPanel(new GridLayout(1, 1)); // 设置容器的位置和宽高
panel.setBounds(x, y, width, height); // 设置 panel 的背景
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);
//f1.setBackground(Color.RED); 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,JLayeredPane.DEFAULT_LAYER);
// lay1.add(p2,JLayeredPane.PALETTE_LAYER);
// lay1.add(p3,JLayeredPane.MODAL_LAYER);
lay1.add(p1,new Integer(1));
lay1.add(p2,new Integer(1));
lay1.add(p3,new Integer(1));
//不同层,Integer数值小,层越靠近底部//同层Integer值越小,越靠近顶部
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类常数取得。


补充:

	持续组件居中方法:监听

JFrame 的层次结构 及 背景设置说明的更多相关文章

  1. JFrame的层次结构以及背景颜色设置问题

    JFrame的层次结构: JFrame:窗体,也就是窗口的框架.默认为不可见.不透明的(可以使用isVisible和isOpaque来验证).创建窗口时,最后一步需要调用setVisible(true ...

  2. HT For Web 拓扑图背景设置

    HT For Web 的HTML5拓扑图组件graphView背景设置有多种途径可选择: divBackground:通过css设置graphView对应的div背景 Painter:通过graphV ...

  3. ArcGIS for Android 中MapView的地图背景设置

    转自:http://blog.csdn.net/wozaifeiyang0/article/details/7535704 根据多方面测速,终于解决了一个蛋疼的问题,MapView的背景设置问题. 在 ...

  4. SurfaceView类透明背景设置

    将SurfaceView背景设置为透明,主要添加以下几句话就可以了: 在SurfaceView创建后设置一下下面的参数: setZOrderOnTop(true); getHolder().setFo ...

  5. 将android界面背景设置为黑色

    屏幕背景设置为黑色的几种方式: 新建项目时候 第二次next之后(不同sdk版本号可能不同),Background Color项点击可选. 开公布局文件,选择视图查看 就是下边二个选项卡中的第一个(G ...

  6. Python数据可视化Matplotlib——Figure画布背景设置

    之前在今日头条中更新了几期的Matplotlib教学短视频,在圈内受到了广泛好评,现应大家要求,将视频中的代码贴出来,方便大家学习. 为了使实例图像显得不单调,我们先将绘图代码贴上来,此处代码对Fig ...

  7. CEdit编辑框字体和背景设置

    CEdit编辑框字体和背景设置注意事项:当CEdit为“disable”时,设置编辑框的字体和背景会没有效果.解决方案:将CEdit的Style设置为“readonly”,这样设置就能生效了,同时也能 ...

  8. Android webview背景设置为透明无效 拖动时背景闪烁黑色

    Adndroid 2.X的设置 webview是一个使用方便.功能强大的控件,但由于webview的背景颜色默认是白色,在一些场合下会显得很突兀(比如背景是黑色). 此时就想到了要把webview的背 ...

  9. CSS之背景设置、字体设置、文本设置

    <html> <head> <meta charset="utf-8"> <title>单行文本框与多行文本框</title& ...

随机推荐

  1. Sublime Text3快速创建HTML5框架

    输入html:5 按tab键即可

  2. EMA

    目录 源 设置 结果 源 Exponential moving average (EMA) 是一个非常有用的trick, 起到加速训练的作用. 近来发现, 该技巧还可以用于提高网络鲁棒性(约1% ~ ...

  3. Unsupervised Feature Learning via Non-Parametric Instance Discrimination

    目录 概 主要内容 Wu Z., Xiong Y., Yu S. & Lin D. Unsupervised Feature Learning via Non-Parametric Insta ...

  4. [源码解析] PyTorch 分布式之弹性训练(7)---节点变化

    [源码解析] PyTorch 分布式之弹性训练(7)---节点变化 目录 [源码解析] PyTorch 分布式之弹性训练(7)---节点变化 0x00 摘要 0x01 变化方式 1.1 Scale-d ...

  5. 标准基座获取定位可以获取address城市,自定义基座获取不到address

    正常的返回应该 { "type": "WGS84", "altitude": 0, "latitude": 31.830 ...

  6. MySQL百分比显示和显示前百分之几的方法

    前几天一个朋友让我帮忙写的,随手记录一下,感觉难度也不大,就是写的时候遇到一些问题.优化方便做得不太好.有好的优化方法欢迎分享!(数据库在文章结尾) 要求 1)查询所有时间内,所有产品销售金额占比,按 ...

  7. vert.x框架-使用spring注解功能

    1.前言 习惯了spring注解风格,方便好用,现在用vert.x框架,怎么使用spring注解呢? 2.maven安装依赖包 <!--spring注解依赖包--> <depende ...

  8. Hive的基本概念和常用命令

    原文链接: https://www.toutiao.com/i6766571623727235595/?group_id=6766571623727235595 一.概念: 1.结构化和非结构化数据 ...

  9. 【Java】集合

    文章目录 集合框架的概述 数组在存储多个数据方面的特点 数组在存储多个数据方面的缺点 集合框架 Collection接口中的方法的使用 add(Object e) size() addAll(Coll ...

  10. day 20 C语言顺序结构基础3

    (1).若有定义:int a=100:则语句printf("%d%d%d\n",sizeof("a"),sizeof(a),sizeof(3.14)); 则输出 ...