GameCanvas全屏尺寸的问题

很多人都问过我这个问题,解释了很多遍,干脆写出来。

Q: 为什么我在setFullScreenMode(true)后,调用getWidth(),getHeight()得到的屏幕尺寸比实际尺寸小?

A: 因为当Canvas没有被显示时,调用setFullScreenMode(true)后,并不会立即生效。在生效过后,系统会回调sizeChanged(int w, int h) 来通知屏幕大小已经改变。
public void sizeChanged(int w,int h){
    this.screen_width=w;
    this.screen_height=h;
}


摘自MIDP2.0 spec, Canvas.sizeChanged():
If the size of a Canvas changes while it is not visible, the implementation may choose to delay calls to sizeChanged until immediately prior to the call to showNotify. In that case, there will be only one call to sizeChanged, regardless of the number of size changes.

我已在Nokia6600测试过了,结果为 176 X 208

PS: 有的人的解决办法是调用 setFullScreenMode()后,sleep()一段时间,然后再调用getWidth()/getHeight().这样可能能解决问题,但并不能保证得到的结果一定是正确的。

测试代码如下:

//TestCanvas.java
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;

public class TestCanvas extends GameCanvas implements Runnable {
  int[] sw = new int[20];
  int[] sh = new int[20];
  String[] msgs = new String[20];
  private int id = 0;
  private void update(String msg){
      update(msg, getWidth(), getHeight());
  }
  private void update(String msg, int w, int h){
      if( id < sw.length-1 ){
          msgs[id] = msg;
          sw[id] = w;
          sh[id++] = h;
      }
  }
 
  public TestCanvas() {
    super(false);
    update("BeforeSet");
    setFullScreenMode(true);
    update("AfterSet");
  }
  public void sizeChanged(int w, int h){
      update("sizeChanged(w,h)", w, h);
      update("sizeChanged()");
  }
  public void run(){
      while(true){
          repaint();
          serviceRepaints();
          try {  Thread.sleep(50);  }
          catch (InterruptedException ex) {  }
      }
  }
  public void paint(Graphics g){
      if( getWidth() != sw[id-1] || getHeight() != sh[id-1] )
        update("paint()");
     
      g.setColor(0xffffff);
      g.fillRect(0, 0, 176, 208);
      int fh = g.getFont().getHeight();
      g.setColor(0);
      for(int i = 0 ;i < id; i ++ )
          g.drawString(msgs[i] + "   /t" +sw[i]+","+sh[i], 1, i*fh, 20);
     
  }
}

//TestCanvas.java
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;

public class TestCanvas extends GameCanvas implements Runnable {
  int[] sw = new int[20];
  int[] sh = new int[20];
  String[] msgs = new String[20];
  private int id = 0;
  private void update(String msg){
      update(msg, getWidth(), getHeight());
  }
  private void update(String msg, int w, int h){
      if( id < sw.length-1 ){
          msgs[id] = msg;
          sw[id] = w;
          sh[id++] = h;
      }
  }
 
  public TestCanvas() {
    super(false);
    update("BeforeSet");
    setFullScreenMode(true);
    update("AfterSet");
  }
  public void sizeChanged(int w, int h){
      update("sizeChanged(w,h)", w, h);
      update("sizeChanged()");
  }
  public void run(){
      while(true){
          repaint();
          serviceRepaints();
          try {  Thread.sleep(50);  }
          catch (InterruptedException ex) {  }
      }
  }
  public void paint(Graphics g){
      if( getWidth() != sw[id-1] || getHeight() != sh[id-1] )
        update("paint()");
     
      g.setColor(0xffffff);
      g.fillRect(0, 0, 176, 208);
      int fh = g.getFont().getHeight();
      g.setColor(0);
      for(int i = 0 ;i < id; i ++ )
          g.drawString(msgs[i] + "   /t" +sw[i]+","+sh[i], 1, i*fh, 20);
     
  }
}

你可能感兴趣的:(J2ME)