JFrame 的層次結構 及 背景設置說明


感謝原文: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類常數取得。


補充:

	持續組件居中方法:監聽

在這里插入圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM