在这篇博文中,笔者会介绍JFrame窗口的分层。JFrame继承自Frame,同JFrame、JDialog、JApplet都是重量级组件。如果不弄清楚Frame的分层结构,那么在设置组件的某些特效的时候就会出错,比如设置背景。
Frame层次结构图:
每一个顶级容器,都有一个隐藏的中间容器,叫做Root Pane。Root Pane 管理着Content Pane 、Menu Bar 和 其它一些容器。
例如:
JFrame frame=new JFrame("测试"); frame.setBackground(Color.RED); frame.setSize(300, 300); frame.setVisible(true);
当程序运行出来后,会发现背景色并没有设置成功,这是因为Content Pane绘制在Root Pane之上,所以Content Pane的背景覆盖了,所以看不见。
把Content Pane隐藏了就可以了:
JFrame frame=new JFrame("测试"); frame.getContentPane().setVisible(false);//设置Content Pane不可见 frame.setBackground(Color.RED); frame.setSize(300, 300); frame.setVisible(true);
这样解决并不好,因为设置在Content Pane上的组件就不可见了,
通常设置为这样:
JFrame frame=new JFrame("测试"); JPanel p=new JPanel(); frame.getContentPane().setBackground(Color.RED); p.setOpaque(false);//设置透明 frame.add(p); //在p上添加一些组件... frame.setSize(300, 300); frame.setVisible(true);
上面中的 p.setOpaque(false) 表示设置JPane为背景透明的,只有JPane背景透明才可以看见Content Panel的背景。
上面修改的是Content Panel的背景,其实也可以修改JPane的背景:
JFrame frame=new JFrame("测试"); JPanel p=new JPanel(); frame.add(p); p.setOpaque(true);//设置不透明,默认是不透明的 p.setBackground(Color.RED);//设置背景 frame.setSize(300, 300); frame.setVisible(true);
这里需要注意的就是JPanel组件是不透明的,也就是isOpaque()返回true。不过其它一些组件默认就是透明的,比如JLabel
JFrame frame=new JFrame("测试"); JPanel p=new JPanel(); JLabel label=new JLabel("test"); label.setOpaque(true);//设置不透明 label.setBackground(Color.RED);//设置背景 p.add(label); frame.add(p); frame.setSize(300, 300); frame.setVisible(true);