IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> JavaAwtSwing笔记之 Frame和JFrame的区别 -> 正文阅读

[移动开发]JavaAwtSwing笔记之 Frame和JFrame的区别

设置关闭按钮的关闭功能

Frame设置关闭按钮

		frame.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});

		Frame I = frame;
		frame.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				I.dispose();
			}
		});

		frame.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				Window window=(Window)e.getComponent();
                window.dispose();
			}
		});

JFrame设置关闭按钮

		jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Frame无Panel , JFrame有Panel

  • Frame add的子件的 Parent 是 Frame
  • JFrame add的子件的 Parent 是 JPanel
  • java5后 jframe.add() 和 jframe.getContentPane().add() 的效果相同

Frame用 add(子件)增加子件

Frame的默认layout是BorderLayout

可以用:

  • .add(子部件, BorderLayout.EAST);
  • .add(子部件, BorderLayout.WEST);
  • .add(子部件, BorderLayout.SOUTH);
  • .add(子部件, BorderLayout.NORTH);
  • .add(子部件, BorderLayout.CENTER);

增加子部件

JFrame有add(子件) 和 getContentPane().add(子件)

JFrame继承自Frame

public class JFrame  extends Frame implements WindowConstants,
                                              Accessible,
                                              RootPaneContainer,
                              TransferHandler.HasGetTransferHandler

JFrame直接add(子部件)方法

默认的add方法和Frame的一样, 都是继承自Container类的add方法
Jframe ? Frame ? Window ? Container ? Component ? Object

JFrame的默认layout也是BorderLayout

System.out.println(jframe.getLayout()); // java.awt.BorderLayout[hgap=0,vgap=0]

可以用:

  • .add(子部件, BorderLayout.EAST);
  • .add(子部件, BorderLayout.WEST);
  • .add(子部件, BorderLayout.SOUTH);
  • .add(子部件, BorderLayout.NORTH);
  • .add(子部件, BorderLayout.CENTER);

增加子部件

JFrame覆盖了Container的addImpl方法, 所以 JFrame的add 和 Frame的add 不一样

据说java1.4之前 JFrame直接用add会出现不可预测的情况, 但现在可以了
add调用了addImpl
java17的源代码如下👇

    protected void addImpl(Component comp, Object constraints, int index)
    {
        if(isRootPaneCheckingEnabled()) {
            getContentPane().add(comp, constraints, index);
        }
        else {
            super.addImpl(comp, constraints, index);
        }
    }

JFrame初始化时设置 setRootPaneCheckingEnabled(true); 源码👇

    protected void frameInit() {
        enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.WINDOW_EVENT_MASK);
        setLocale( JComponent.getDefaultLocale() );
        setRootPane(createRootPane());
        setBackground(UIManager.getColor("control"));
        setRootPaneCheckingEnabled(true);
        if (JFrame.isDefaultLookAndFeelDecorated()) {
            boolean supportsWindowDecorations =
            UIManager.getLookAndFeel().getSupportsWindowDecorations();
            if (supportsWindowDecorations) {
                setUndecorated(true);
                getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
            }
        }
        sun.awt.SunToolkit.checkAndSetPolicy(this);
    }

所以默认 jframe.add() 和 jframe.getContentPane().add()等价

JFrame的 getContentPane().add(子部件)

JFrame自带JRootPane和getRootPane() 方法 , JRootPane自带JPane

Jframe带JBootPane带JPane
getContentPane()就是调用rootPanel的getContentPane()方法, 源码如下👇

    public Container getContentPane() {
        return getRootPane().getContentPane();
    }

getContentPane()返回RootPane的JPane, 所以JFrame自带JPane

jframe.getContentPane().getClass() 的结果是 class javax.swing.JPanel

自带JPanel的layout是 JRootPane中的匿名内部类, 继承自 BorderLayout

可以看到getContentPane()获得的JPane的Layout是一个匿名内部类

System.out.println(jframe.getContentPane().getLayout()); // javax.swing.JRootPane$1[hgap=0,vgap=0]
jframe.getContentPane().getLayout() instanceof BorderLayout 的结果是 true

在JBootPane中的源码如下👇

    protected Container createContentPane() {
        JComponent c = new JPanel();
        c.setName(this.getName()+".contentPane");
        c.setLayout(new BorderLayout() {
            /* This BorderLayout subclass maps a null constraint to CENTER.
             * Although the reference BorderLayout also does this, some VMs
             * throw an IllegalArgumentException.
             */
            public void addLayoutComponent(Component comp, Object constraints) {
                if (constraints == null) {
                    constraints = BorderLayout.CENTER;
                }
                super.addLayoutComponent(comp, constraints);
            }
        });
        return c;
    }

所以JFrame 的 add() 等价 getContentPane().add() 等价 getRootPane().getContentPane().add()

JFrame 的 JRootPane

前面已述说
JFrame 默认 带 JRootPane 可通过 getRootPane()
add() 等价 getContentPane().add() 等价 getRootPane().getContentPane().add()
其实 JRootPane 也有add()方法
jframe.getRootPane().add(子件); 默认看不到, 因为被 JPanel 遮住了
用 jframe.getContentPane().setVisible(false); 将JPanel隐藏后就看到了

测试代码

package frameJframe;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.swing.*;


public class FrameJFrameCompare2205190743 {
	static String separator = " 的结果是 ";
	public static void pln(Object o) {System.out.println(o);}
	public static void main(String[] arguments) {
		
		Button b0 = new Button("b0");
		
		b0.setBackground(Color.DARK_GRAY); b0.setForeground(Color.ORANGE);
		
		final ArrayList<JButton> BtnAl = new ArrayList<>();
		for(int i=1; i<=100; i++) {
			JButton btn = new JButton("按钮-"+i);
			btn.setBackground(new Color(0,168,255));
			btn.setForeground(Color.WHITE);
			btn.setSize(100, 50);
			BtnAl.add(btn);
		}
		
		Frame frame = new Frame("Frame");
		frame.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				Window w = (Window)e.getComponent();
				pln(w==e.getOppositeWindow());
				w.dispose();
				System.exit(0);
			}
		});
		frame.setBounds(100, 100, 1600, 300);
		pln("frame.getParent()"+separator+frame.getParent());
		pln("frame.getLayout().getClass()"+separator+frame.getLayout().getClass());
		b0.setSize(100,100); 
		pln("frame add前 b0.getBounds()="+b0.getBounds());
		frame.add(b0);
		pln("frame add后 b0.getBounds()="+b0.getBounds());
		frame.setVisible(true);
		pln("frame.setVisible(true)后 b0.getBounds()="+b0.getBounds());
		b0.setSize(100,100); 
		pln("再次b0.setSize(100,100);后 b0.getBounds()="+b0.getBounds());
		
		pln("b0在Frame时的 b0.getParent()"+separator+( b0.getParent() ));
		
		try {Thread.sleep(1000);}catch(Exception th){}
		b0.setSize(100,100); 
		try {Thread.sleep(1000);}catch(Exception th){}
		
		JFrame jframe = new JFrame("JFrame");
//		jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		jframe.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				Window w = (Window)e.getComponent();
				pln(w==e.getOppositeWindow());
				w.dispose();
				System.exit(0);
			}
		});
		jframe.setBounds(100, 500, 1600, 300);
		jframe.setVisible(true);
		
		pln("jframe.getParent()"+separator+jframe.getParent());
		pln("jframe.getLayout()"+separator+jframe.getLayout());
		pln("jframe.getLayout().getClass()"+separator+jframe.getLayout().getClass());
		pln("jframe.getContentPane()"+separator+jframe.getContentPane());
		pln("jframe.getContentPane().getClass() 的结果是 "+jframe.getContentPane().getClass());
		pln("jframe.getContentPane().getLayout()"+separator+jframe.getContentPane().getLayout());
		pln("jframe.getContentPane().getLayout().getClass()"+separator+jframe.getContentPane().getLayout().getClass());
		pln("jframe.getContentPane().getLayout() instanceof BorderLayout"+separator+(jframe.getContentPane().getLayout() instanceof BorderLayout));
		
		pln("jframe.getContentPane()==jframe.getRootPane() 的结果是 "+(jframe.getContentPane()==jframe.getRootPane()));
		pln("jframe.getContentPane() instanceof JPanel 的结果是 "+(jframe.getContentPane() instanceof JPanel));
		pln("jframe.getContentPane().getClass()==JPanel.class 的结果是 "+(jframe.getContentPane().getClass()==JPanel.class));
		
		pln("jframe add前 b0.getBounds()="+b0.getBounds());
		
//		JRootPane rootPane = (JRootPane) jframe.getContentPane();
		jframe.add(b0,"Center");
//		jframe.getContentPane().add(b0,BorderLayout.EAST);
		jframe.getContentPane().add(BtnAl.get(0),BorderLayout.WEST);
		jframe.getRootPane().getContentPane().add(BtnAl.get(2),BorderLayout.SOUTH);
		pln("b0放到JFrame后 b0.getParent()="+b0.getParent());
		pln("BtnAl.get(0).getParent()="+BtnAl.get(0).getParent());
		pln("b0.getParent()==BtnAl.get(0).getParent()"+(b0.getParent()==BtnAl.get(0).getParent()));
		pln("b0.getParent()==BtnAl.get(2).getParent()"+(b0.getParent()==BtnAl.get(2).getParent()));
		JRootPane jrootPane = jframe.getRootPane();
		final JPanel JFrameJRootPaneJPane = (JPanel) jframe.getContentPane();
		final JPanel JRootPaneJPane = (JPanel) jrootPane.getContentPane();
		pln("JFrameJRootPaneJPane==JRootPaneJPane"+separator+ (JFrameJRootPaneJPane==JRootPaneJPane)  );
//		JFrameJRootPaneJPane.setVisible(false);
		jframe.getContentPane().setVisible(false);
		
//		jframe.add(BtnAl.get(0));
		jrootPane.add(BtnAl.get(1));
		pln("BtnAl.get(1).getParent()="+BtnAl.get(1).getParent());
		jrootPane.invalidate();
		jframe.setVisible(true);
//		jframe.dispose();
//		jframe.setVisible(true);
		
	}

}

结果

frame.getParent() 的结果是 null
frame.getLayout().getClass() 的结果是 class java.awt.BorderLayout
frame add前 b0.getBounds()=java.awt.Rectangle[x=0,y=0,width=100,height=100]
frame add后 b0.getBounds()=java.awt.Rectangle[x=0,y=0,width=100,height=100]
frame.setVisible(true)后 b0.getBounds()=java.awt.Rectangle[x=8,y=31,width=1584,height=261]
再次b0.setSize(100,100);后 b0.getBounds()=java.awt.Rectangle[x=8,y=31,width=100,height=100]
b0在Frame时的 b0.getParent() 的结果是 java.awt.Frame[frame0,100,100,1600x300,invalid,layout=java.awt.BorderLayout,title=Frame,resizable,normal]
jframe.getParent() 的结果是 null
jframe.getLayout() 的结果是 java.awt.BorderLayout[hgap=0,vgap=0]
jframe.getLayout().getClass() 的结果是 class java.awt.BorderLayout
jframe.getContentPane() 的结果是 javax.swing.JPanel[null.contentPane,0,0,1584x261,layout=javax.swing.JRootPane$1,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
jframe.getContentPane().getClass() 的结果是 class javax.swing.JPanel
jframe.getContentPane().getLayout() 的结果是 javax.swing.JRootPane$1[hgap=0,vgap=0]
jframe.getContentPane().getLayout().getClass() 的结果是 class javax.swing.JRootPane$1
jframe.getContentPane().getLayout() instanceof BorderLayout 的结果是 true
jframe.getContentPane()==jframe.getRootPane() 的结果是 false
jframe.getContentPane() instanceof JPanel 的结果是 true
jframe.getContentPane().getClass()==JPanel.class 的结果是 true
jframe add前 b0.getBounds()=java.awt.Rectangle[x=8,y=31,width=100,height=100]
b0放到JFrame后 b0.getParent()=javax.swing.JPanel[null.contentPane,0,0,1584x261,invalid,layout=javax.swing.JRootPane$1,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
BtnAl.get(0).getParent()=javax.swing.JPanel[null.contentPane,0,0,1584x261,invalid,layout=javax.swing.JRootPane$1,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
b0.getParent()==BtnAl.get(0).getParent()true
b0.getParent()==BtnAl.get(2).getParent()true
JFrameJRootPaneJPane==JRootPaneJPane 的结果是 true
BtnAl.get(1).getParent()=javax.swing.JRootPane[,8,31,1584x261,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777675,maximumSize=,minimumSize=,preferredSize=]


  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-05-21 19:06:35  更:2022-05-21 19:07:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 1:50:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码