设置关闭按钮的关闭功能
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());
可以用:
- .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());
jframe.getContentPane().getLayout() instanceof BorderLayout 的结果是 true
在JBootPane中的源码如下👇
protected Container createContentPane() {
JComponent c = new JPanel();
c.setName(this.getName()+".contentPane");
c.setLayout(new BorderLayout() {
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.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());
jframe.add(b0,"Center");
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) );
jframe.getContentPane().setVisible(false);
jrootPane.add(BtnAl.get(1));
pln("BtnAl.get(1).getParent()="+BtnAl.get(1).getParent());
jrootPane.invalidate();
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=]
|