感谢原文: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. Normalized Cuts and Image Segmentation

    目录 概 主要内容 求解 相似度 总的算法流程 skimage.future.graph.cut Shi J. and Malik J. Normalized cuts and image segme ...

  2. ZFNet: Visualizing and Understanding Convolutional Networks

    目录 论文结构 反卷积 ZFnet的创新点主要是在信号的"恢复"上面,什么样的输入会导致类似的输出,通过这个我们可以了解神经元对输入的敏感程度,比如这个神经元对图片的某一个位置很敏 ...

  3. Essentially No Barriers in Neural Network Energy Landscape

    目录 梗概 主要内容 path的定义 path的逼近 Mechanical Model Nudged Elastic Band 局部最优 Draxler F, Veschgini K, Salmhof ...

  4. WinForm应用程序的开机自启、记住密码,自动登录的实现

    一.思路: 1.开机自启,自然是需要用到注册表,我们需要把程序添加到电脑的注册表中去 2.记住密码,自动登录,开机自启,在页面的呈现我们都使用复选框按钮来呈现 3.数据持久化,不能是数据库,可以是sq ...

  5. JZOJ 3296 Luogu P3296 [SDOI2013]刺客信条

    前言 做法来自:@pzrpzr ,写一下!Orz pzr! 题目大意 \(n\) 个点的无根树,每个点有两个 \(0/1\) 权值,合适地安排节点在同构树中的顺序,使得前后对应的权值不同节点个数最小, ...

  6. PHP json_encode() 序列化对象、数组、空对象、空数组

    $result = [ "object" => ["a" => 1], "array" => [1,2,3,4,5], & ...

  7. [Flask] Flask问题集(后端模板渲染项目)

    1.redirect和render_template的区别? redirect:重定向,会改变url render_template:模板渲染,用模板来渲染当前页,不会改变url 2.关于 'g' 对 ...

  8. VM和CentOS7安装教程

    如果图片损坏,点击链接:https://www.toutiao.com/i6491076101664670222/ 安装软件 VMware_workstation_full_12.5.2 CentOS ...

  9. 【Java常用类】BigDecimal

    BigDecimal 一般的Float类和Double类可以用来做科学计算或工程计算,但在商业计算中, 要求数字精度比较高,故用到java.math.BigDecimal类. BigDecimal类支 ...

  10. 【Android UI设计与开发】8.顶部标题栏(一)ActionBar 奥义·详解

    一.ActionBar介绍 在Android 3.0中除了我们重点讲解的Fragment外,Action Bar也是一个非常重要的交互元素,Action Bar取代了传统的tittle bar和men ...