Java JPanel的getSize()方法 有时候得到的结果为0 的原因(涉及语句顺序、paint方法的调用)
来源:互联网 发布:淘宝ulike脱毛仪骗局 编辑:程序博客网 时间:2024/05/18 11:26
废话少说,放码上来
public class MarioFrame extends JFrame {public MarioFrame() {this.initFrame();}public void initFrame() {this.setTitle("Mario");this.setSize(600, 480);this.setDefaultCloseOperation(3);this.setLocationRelativeTo(null);GamePanel gp = new GamePanel();this.add(gp);this.setJMenuBar(new Menu());<span style="color:#ff0000;">System.out.println(gp.getSize());</span>this.setVisible(true);}}
在上面窗体类的代码中,给窗体对象添加了一个JPanel类的对象gp,之后调用getSize()方法并打印到控制台。添加了面板对象,之后得到它的大小并且打印,看似没错,然而实际的运行结果是
java.awt.Dimension[width=0,height=0]
窗体正常显示,但得到的JPanel大小为0.当然,调用getPreferredSize()结果也是一样。
为什么呢?
原因是 此方法的调用在窗体显示之前
在以上代码中,虽然成功给Frame窗体添加了JPanel面板,但是代码没有运行到
this.setVisible(true);
语句,窗体并没有显现,面板也就没有显现,此时面板的大小当然为0;
就算已经给JPanel设置了大小,由于没有显示的原因,getSize()方法还是不能得到面板的数据。
由此得到一个结论,getSize()和getPreferredSize()方法的执行,是从闪存中调用数据的。就算已经加载到了内存里面,在代码加载到闪存显示画面之前还是不能得到数据。
因此,只要把上面代码中的getSize()语句放到setVisible(true)语句之后,就能正常得到面板大小。
那么,问题来了,为什么getSize()能够在JPanel的paint()方法里得到JPanel的大小的?
比如下面的代码
import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics;import java.awt.image.BufferedImage;import java.util.ArrayList;import java.util.Random;import javax.swing.JPanel;public class GamePanel extends JPanel{public static ArrayList<Pipe> pipeList = new ArrayList<Pipe>();Background background = new Background(2, 0, 2);Mario mario = new Mario(150, 0, 28, 34, 4);MarioMoveListener mml = new MarioMoveListener(mario,this,background);public GamePanel() {this.addGamePanel();}public void addGamePanel(){//设置焦点this.setFocusable(true);//添加监听this.addKeyListener(mml);//添加管道this.addPipe();//添加管道}public void paint(Graphics g) {<span style="color:#ff0000;">System.out.println(this.getSize());</span>//准备一张缓冲背景图片BufferedImage bi = (BufferedImage) this.createImage(this.getWidth(),this.getHeight());//获取缓冲图片画笔Graphics g_buffer = bi.getGraphics();//将要绘制的内容,绘制到缓冲图片上g_buffer.drawImage(background.image.getImage(), background.x, 0,10292,(int)this.getSize().getHeight(), null);g_buffer.drawImage(mario.image.getImage(), mario.x, (int)(this.getSize().getHeight() * 0.8),mario.width,mario.height, null);for(int i = 0;i < pipeList.size();i++){Pipe pipe = pipeList.get(i);g_buffer.drawImage(pipe.image.getImage(), pipe.x, pipe.y, pipe.width, pipe.height, null);}//将缓冲图片绘制到窗体g.drawImage(bi, 0, 0, null);}public void addPipe(){for(int i = 0; i < 100; i++){Random ran = new Random();int speed = 4;int height = 100;int width = 40;Pipe pipe = new Pipe(400 + 200 * i , 200,width,height,4);pipeList.add(pipe);}}}此时运行代码就能在控制台打印JPanel的大小
原因就是在窗口显示之后,系统自动调用了一次paint方法进行重绘。此时就涉及到paint方法的调用时机。
一般javax.swing包里的组件大部分是轻量级组件,所以查API可知,JPanel是轻量级组件。(轻重量级组件的具体内容见博客下另一篇)
轻量级组件处理系统触发的请求有两种方法
一种是系统触发的请求,由本地系统发起,例如轻量级组件的重量级祖先组件第一次显示,将会调用paint()方法;
一种是系统触发的请求,由轻量级框架发起,例如轻量级组件大小被调整,将会调用update(),这个方法默认调用paint()方法。
因此,JPanel面板显示之后,调用了一次paint方法,此时就能得到面板的大小了。
这也间接解释了 为什么必须把要绘制的内容放在paint方法内(直接画在面板上会在显示一次之后被调用的paint方法覆盖掉,显示结果就是 闪一下就消失)
0 0
- Java JPanel的getSize()方法 有时候得到的结果为0 的原因(涉及语句顺序、paint方法的调用)
- js有时候方法没有被调用的原因
- JPanel的背景图片设置方法
- super.getClass()方法调用返回结果的原因
- Paint 的set方法
- Java 静态语句块 语句块 构造方法的调用顺序
- java中构造方法的调用顺序
- Java方法调用的优先顺序
- Java中多态的方法调用顺序问题
- java构造方法的调用顺序
- java JPanel中添加一张图片的方法
- JPanel中添加一个新的JPanel,结果新的JPanel会自动占满父JPanel
- java静态方法不能调用非静态方法的原因
- 编译得到不同结果的原因之一
- GetSize与cvSize的区别
- didLoadFromCCB方法的调用顺序
- listview方法的调用顺序
- 构造方法的调用顺序
- java开发中常用的SQL语句
- jquery如何在页面加载完成后模拟出一个鼠标点击事件?
- Python序列——列表
- scala基础4-for循环进阶
- jquery - div显示隐藏
- Java JPanel的getSize()方法 有时候得到的结果为0 的原因(涉及语句顺序、paint方法的调用)
- ACM_CUGOJ_1012_Joseph Problem约瑟夫
- Head First设计模式PHP版
- LeetCode 34 Search for a Range
- 使用myeclipse的反向工程来生成相应的hibernate映射文件和POJO类
- PHP学习-DAY1-PHP基础1
- jquery操作复选框(checkbox)的12个小技巧总结
- jquery如何判断checkbox(复选框)是否被选中
- ES6 知识点小记