swing之JFrame 理解

Swing提供了三个常用的顶层容器类:JFrame,JDialog,JApplet。
JFrame  包含一个  JRootPane  作为其唯一的子容器。根据规定,根窗格所提供的 内容窗格 应该包含  JFrame  所显示的所有非菜单组件。
JFrame可以使用add方法来添加组件,像:
frame.add(child);
这样子级将被添加到contentPane面板上。内容窗格始终是非 null 的。试图将其设置为 null 会导致 JFrame 抛出异常。默认的内容窗格上会设置有BorderLayout管理器。
通常我们在new JFrame()实例的时候,这个顶级容器就为我们分配了两部分的内容,即:Menu Bar和contentPane.
如下图:

这里有对应的code:
/**
 * <br>
 * do what you want to do and never stop it.
 * <br>
 */
package com.infy.basecompent;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuBar;

/**
 * @author Jack
 * 2012-8-17
 * <br>
 */
public class TopLevelDemo {
	/** 
     * Create the GUI and show it.  For thread safety, 
     * this method should be invoked from the 
     * event-dispatching thread. 
     */
    private static void createAndShowGUI() { 
        //Create and set up the window. 
        JFrame frame = new JFrame("TopLevelDemo"); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
  
        //Create the menu bar.  Make it have a green background. 
        JMenuBar greenMenuBar = new JMenuBar(); 
        greenMenuBar.setOpaque(true);
        greenMenuBar.setBackground(new Color(154, 165, 127));
        greenMenuBar.setPreferredSize(new Dimension(200, 20));
  
        //Create a yellow label to put in the content pane. 
        JLabel yellowLabel = new JLabel(); 
        yellowLabel.setOpaque(true); 
        yellowLabel.setBackground(new Color(248, 213, 131)); 
        yellowLabel.setPreferredSize(new Dimension(200, 180)); 
  
        //Set the menu bar and add the label to the content pane. 
        frame.setJMenuBar(greenMenuBar); 
        frame.getContentPane().add(yellowLabel, BorderLayout.CENTER); 
  
        //Display the window. 
        frame.pack(); 
        frame.setVisible(true); 
    }

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// Schedule a job for the event-dispatching thread:
		// creating and showing this application's GUI.
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				createAndShowGUI();
			}
		});
	}

}

所以平时我们在add组件(调用JFrame.add(Component))的时候,其实是把这些组件添加到内容窗格中(contentPane),更准确的做法是JFrame.getContentPane().add(Component),  由于是JFrame重写了Add方法,所以直接用 JFrame.add(Component), 也就是调用的上面的getContentPane再add的调用形式。
而当我们查看api文档的时候,我们发现还有两个pane可以get,即:getLayeredPane(),getGlassPane()。

通过了解,我们知道,JFrame真的完整的结构是这样的:

悬浮在RootPane之上的,实际上有三个pane:LayeredPane、ContentPane、GlassPane
按照上面的叠放顺序我们可以很清楚的看到,LayeredPane相对于后面的两个来说,是离RootPane更近的窗格,几乎可以说管理着ContentPane和GlassPane,或者是ContentPane和GlassPane是放置于LayeredPane之上的。
那么到底GlassPane和LayeredPane是怎么用的呢:
GlassPane从字面来理解的话,就是玻璃窗格,玻璃的特性就是透明,所以这是一个透明的窗格,我们看到的所有画面都要经过这个层,只是在平时,我们根本就没有注意到这一点,因为我们几乎都没有在GlassPane上添加过组件。
下面的代码,就可以体验到,在GlassPane上添加组件的快感:
/**
 * <br>
 * do what you want to do and never stop it.
 * <br>
 */
package com.infy.basecompent;

import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 * @author Jack
 * 2012-8-17
 * <br>
 */
public class TestGlass {
	

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		JFrame f = new JFrame("GlassPane");

	    final JPanel p1 = new JPanel();
	    p1.add(new JLabel("GlassPane Example"));
	    JButton show = new JButton("Show");
	    p1.add(show);
	    p1.add(new JButton("No-op"));
	    f.getContentPane().add(p1);

	    final JPanel glass = (JPanel) f.getGlassPane();

	    glass.setVisible(true);
	    glass.setLayout(new GridBagLayout());
	    JButton glassButton = new JButton("Hide");
	    glass.add(glassButton);

	    f.setSize(400, 300);
	    f.setVisible(true);

	    boolean debug = true;
	    if (debug) {
	      System.out.println("Button is " + glassButton);
	      System.out.println("GlassPane is " + glass);
	    }
	    // Add actions to the buttons...
	    // show button (re-)shows the glass pane.
	    show.addActionListener(new ActionListener() {
	      public void actionPerformed(ActionEvent e) {
	        glass.setVisible(true);
	        p1.repaint();
	      }
	    });
	    
	    // hide button hides the Glass Pane to show what's under.
	    glassButton.addActionListener(new ActionListener() {
	      public void actionPerformed(ActionEvent e) {
	        glass.setVisible(false);
	        p1.repaint();
	      }
	    });


	}

}

而LayeredPane同样可以在上面添加我们需要的控件:
学习代码如下:
/**
 * <br>
 * do what you want to do and never stop it.
 * <br>
 */
package com.infy.basecompent;

import java.awt.BorderLayout;
import java.awt.Container;

import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;

/**
 * @author Jack
 * 2012-8-17
 * <br>
 */
public class JLayeredPaneSample {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		JFrame f = new JFrame("JDesktopPane Sample");
	    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	    Container content = f.getContentPane();
	    JLayeredPane desktop = new JDesktopPane();
	    desktop.setOpaque(false);
	    desktop.add(createLayer("Open 1"), JLayeredPane.POPUP_LAYER);
	    desktop.add(createLayer("Iconified"), JLayeredPane.DEFAULT_LAYER);
	    desktop.add(createLayer("Open 2"), JLayeredPane.PALETTE_LAYER);
	    content.add(desktop, BorderLayout.CENTER);
	    f.setSize(300, 200);
	    f.setVisible(true);

	}
	public static JInternalFrame createLayer(String label) {
	    return new SelfInternalFrame(label);
	  }
	
	static class SelfInternalFrame extends JInternalFrame {
		public SelfInternalFrame(String s) {
			getContentPane().add(new JLabel(s), BorderLayout.CENTER);
			setBounds(50, 50, 100, 100);
			setResizable(true);
			setClosable(true);
			setMaximizable(true);
			setIconifiable(true);
			setTitle(s);
			setVisible(true);
		}
	}
}

如此,一个完整的JFrame就构成了。
PS:以上代码均非原创,来自互联网,如有人以此来从事商业行为,概与本人无关。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值