都說Swing是個坑,果不其然,今天在學習繪圖組件的時候,照着書上的代碼,就出現了彈出窗體,java
卻沒出現繪圖組件的問題,固然,我仍是菜鳥。因此還請原諒我犯這麼低級的錯誤。函數
參考: 《Head First Java》P-364佈局
C博客大伽: http://blog.csdn.net/u012270113/article/details/38898083學習
一不當心就過年了。2017, 新年快樂this
1、下面介紹paint/paintComponent區別的時候,會用到背景顏色,因此咱們先來研究窗口的spa
背景顏色該如何設置?.net
方法1: 最經常使用的方法, 經過JFrame自帶的子容器(ContentPane)內容窗體來設置【如下只是代碼片段】code
1 import javax.swing.*; 2 import java.awt.Color; 3 4 // 經典的錯法 5 // Color是java.awt包的類, 因此別忘了導入java.awt.*; 6 JFrame f= new JFrame(); 7 f.setBackground(Color.pink); 8 9 // 正確的方法 10 f.getContentPane().setBackground(Color.pink);
方法2: 利用JPanel類的paintComponent()方法, 設置背景顏色【Code Snippet】對象
1 import javax.swing.*; 2 import java.awt.*; 3 4 class MyPanel extends JPanel { 5 6 // this是調用本類的方法, 因爲MyPanel類繼承了JPanel類, 因此使用的是它的getWidth()和getHeight()方法 7 public void paintComponent(Graphics g) { 8 g.setColor(Color.pink); 9 g.fillRect(0, 0, this.getWidth(), this.getHeight()); 10 } 11 }
方法3: 不推薦。上面的方法,其實就等同於直接在JFrame裏面建立一個面板, 而後直接設置面板的blog
背景顏色,該方法的缺點就是, 因爲面板是直接添加在JFrame上的, 因此它的背景顏色要受到JFrame
默認的邊界佈局的制約! 【完整代碼】
1 import javax.swing.*; 2 import java.awt.*; 3 4 public class MyDrawPanel { 5 public static void main(String[] args) { 6 JFrame f= new JFrame(); 7 JPanel p = new JPanel(); 8 9 p.setBackground(Color.pink); 10 /* 11 * 看到了吧, 這裏實際上是默認把面板放在窗口的中間位置, 至關於f.add("Center", p); 12 * 因此一旦這個位置放了其它組件, 面板就會被覆蓋掉 13 */ 14 f.add(p); 15 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 16 f.setSize(800, 600); 17 f.setVisible(true); 18 } 19 }
2、paint/paintComponent
1. 咱們首先來建立一個窗口/界面
1 package demo; // 導入包名 2 3 import javax.swing.JFrame; // 或import javax.swing.*; 4 5 public class MyPanel { 6 public static void main(String[] args) { 7 new MyPanel(); // 用new方法建立MyPanel對象, 執行構造函數 8 } 9 10 MyPanel() { // 構造函數——類名(){}, 在創造類的實例(使用new)時執行 11 12 JFrame frame = new JFrame(); 13 // 關閉window時結束程序, 否則每運行一次代碼, 就會產生一個javaw.exe進程, 佔用內存 14 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 15 frame.setSize(800, 600); // 設置窗口的長和寬 16 frame.setVisible(true); // 設置true纔是可見, 才能彈出窗口/界面 17 } 18 }
2. 接着就是建立繪圖組件
少了frame.getContentPane().add(this),沒法顯示Panel(面板)及背景顏色
所以,若是沒有前面單獨爲label設置一個佈局的話,那麼lable也是沒法顯示的。
1 package demo; // 導入包名 2 3 import java.awt.*; 4 import javax.swing.*; // 或import javax.swing.*; 5 6 public class MyPanel extends JPanel { 7 public static void main(String[] args) { 8 new MyPanel(); // 用new方法建立MyPanel對象, 執行構造函數 9 } 10 11 MyPanel() { // 構造函數——類名(){}, 在創造類的實例(使用new)時執行 12 13 JFrame frame = new JFrame(); 14 JLabel label = new JLabel("標籤"); 15 16 this.add(label); // 除了JFrame對象不可使用add(), 像JPanael, JLabel都可 17 frame.getContentPane().add(BorderLayout.NORTH, label); //把label放在面板的北邊 18 frame.getContentPane().add(this); //把JPanel及JPanel上的其餘組件都加入頂層容器JFrame 19 this.setBackground(Color.pink); 20 21 // 關閉window時結束程序, 否則每運行一次代碼, 就會產生一個javaw.exe進程, 佔用內存 22 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 23 frame.setSize(800, 600); // 設置窗口的長和寬 24 frame.setVisible(true); // 設置true纔是可見, 才能彈出界面 25 } 26 27 public void paintComponent(Graphics g) { 28 super.paintComponent(g); // super用來調用JPanel父類的方法, "Ctrl + /"註釋掉該行的話,背景顏色就會消失 29 g.setColor(Color.orange); 30 g.fillRect(20, 50, 100, 100); 31 } 32 }
1.JFrame和JPanel區別
包含Swing組件的程序必須包含一個頂級容器。可是Swing組件不能夠直接加入到頂級容器中,而
JFrame是頂級容器。一般是把Swing組件先加入JFrame, JDialog, and JApplet三個頂層容器類中
的一個(Swing還包括另外一個JWindow頂級容器組件),而後再放入JFrame中。
2.add()是任何JComponent均可以調用的,JPanel也能夠,可是JFrame不能夠。
對JFrame添加組件有兩種方式
方法1: 經過 getContentPane ()方法得到JFrame自帶的子容器(ContentPane: 內容窗體),再對其
加入組件,如frame. getContentPane ().add(childComponent)。
方法2: 我更喜歡用frame.add(), 其實本質仍是向 ContentPane 添加組件,不信的話作個實驗 >^<
frame.getContentPane().setVisible(false); 保證除了一個窗口, 什麼組件都沒有!
3. Swing中paint與paintComponent的區別
當Swing中的paint方法被調用時, paintComponent、paintBorder、 paintChildren 這三個方法也
會被按順序調用,之因此要按這個順序調用是爲了保證子組件能正確地顯示在目前這個組件之上。
paintComponent就是自己這個容器本身畫出本身組件的方法,且在JComponent中的方法paintCom
ponent()仍是保護類型的,即咱們日常並不用管這個方法。只在咱們須要改變繪製組件動做的時候,
類只要先繼承paintComponent(通常是JFrame),而後重寫這個方法便可。
總之:
(1)若是隻是爲了在Swing中改變組件樣式,重寫paintComponent就能夠了,其餘paintBorder和
paintChildren默認。若是還要保留容器中的本來組件就別忘了調用super.paintComponent(g)。
(2)若是要改寫paint方法來改變自己這個容器組件,那麼也別忘了要調用super.paint(g),否則出
來的東西是不包含Jpanel的原組件、原邊框和子組件的。
今天忽然發現,若是不在this上設置背景顏色。而是在printComponent()或者print()方法直接設置的
話,那麼,super行就不會影響到背景顏色了。同理,若是直接在frame.getContentPane().add(label);
添加label,那麼也不會受super.paint(g)的影響。
不過,兩種狀況下,frame.getContentPane().add(this);都是必須的,由於仍是要把JPanel及其組件
添加到frame中的。 ————2017 1/30