【Swing 1】paint / paintComponent的区别和背景颜色设置的三种方法

    都说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     

相关文章
相关标签/搜索