Swing提供了三个常用的顶层容器类:JFrame,JDialog,JApplet。
JFrame
包含一个
JRootPane
作为其唯一的子容器。根据规定,根窗格所提供的
内容窗格
应该包含
JFrame
所显示的所有非菜单组件。
JFrame可以使用add方法来添加组件,像:
这里有对应的code:
所以平时我们在add组件(调用JFrame.add(Component))的时候,其实是把这些组件添加到内容窗格中(contentPane),更准确的做法是JFrame.getContentPane().add(Component), 由于是JFrame重写了Add方法,所以直接用 JFrame.add(Component), 也就是调用的上面的getContentPane再add的调用形式。
而当我们查看api文档的时候,我们发现还有两个pane可以get,即:
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:以上代码均非原创,来自互联网,如有人以此来从事商业行为,概与本人无关。