在這篇博文中,筆者會介紹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);