• ベストアンサー

違いについて

g.drawImage(buffer,0,0,this);とg.drawImage(buffer,0,0,null);の違いについて教えてください。

  • mos21
  • お礼率46% (128/273)
  • Java
  • 回答数1
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • liar_adan
  • ベストアンサー率48% (730/1515)
回答No.1

こんにちは。先日はポイントをどうも。 ところで、質問は、背景も含めて書いた方がいいと思います。 この書き方だと私以外は回答が困難です。 これはアプレットのpaint()内で、描画をするときの問題ですね。 drawImageの最後の引数にはImageObserverが入ります。 まあそれはAPIドキュメントを見ればわかりますね。 ではImageObserverとはなにか、という事になります。 普通、「イメージ」と言ったら、画面に表示されたイメージや、そのデータを考えるでしょうが、 Javaでのイメージは少し違います。 Imageは一種のストリーム(流れ)のように考えられています。 インターネットを通じてイメージデータをやりとりするとき、かなり時間がかかるため、 「静的なイメージがすぐに表示される」としてしまうと、 イメージデータを読み込むまでプログラムが止まってしまうからです。 g.drawImage(image, x, y, observer)は、 「イメージの描画を行う」のではなくて、 「イメージの描画を開始する」のような意味を持っています。 イメージを時間をかけて読み込むわけですが、 「イメージの大きさが判明した」「読み込みが完了した」など、 読み込んだ段階があります。 描写する側では読み込んだ段階ごとにいろいろ仕事をしなければなりません。 その情報を与える相手が、ImageObserverです。 ImageObserverは、AppletとかCanvasとかのイメージを描写するコンポーネントです。 通常drawImage()は、それらのpaint()の中で使われるので、thisを使います。 まとめると、ImageObserverを指定しないと、 正常に表示されないかもしれないのです。 問題のプログラムで使っていたのは、ダブルバッファリング用のImageですので、 イメージデータの読み込みには時間はほとんどかからないと予想され、 実際にはnullを指定しても動くかもしれません。 (このへんは私にもよくわかりません) ただ、ちゃんとthisを指定するのが基本なので、そちらを奨めます。 追伸、一つ前の質問も見ているのですが、 ちょっと問題がややこしいので答えかねています。 すみません。

mos21
質問者

お礼

丁寧な回答ありがとうございます^^paint()内でnullと記述してrun()内でrepaintしたところうまく動きました。thisを記述したらrepaintがないのに画像が次々と表示されてしまいました。一つ前の質問は、わかりずらいし何が聞きたいのかわからないですね(^^;すいませんでした。でも解決しました!わざわざありがとうございます^^/

関連するQ&A

  • 意味がわかりません

    この部分の意味がわからなくて困っています。わかる方いましたら解説をお願いします。m(_ _)m public void paint(Graphics g){ int w,h; w = (int)getSize().width; h = (int)getSize().height; if(f==0){ bufferGraphics.drawImage(image,0,0,this); bufferGraphics.setColor(Color.white); for(int i=0;i<h;i+=2){ bufferGraphics.drawLine(0,i,w,i); } g.drawImage(buffer,0,0,null); f = 1; } else if(f==1) { bufferGraphics.drawImage(image,0,0,this); bufferGraphics.setColor(Color.white); for(int i=1;i<h;i+=2){ bufferGraphics.drawLine(0,i,w,i); } g.drawImage(buffer,0,0,null); f = 0; } }

    • ベストアンサー
    • Java
  • コンパイルできません

    次のようなプログラムを作成しましたのですが、コンパイルできなくて困っています。img2,img3,img4にはそれぞれ画像データが入っていて、それを順番に表示させながらループさせたいのですけど(^^; public void update(Graphics g) {paint(g);} public void paint(Graphics g){ for(int state=0; state < 3; state++); { switch(state){ case 0:  buffer=img2; break; case 1:  buffer=img3; break; case 2:  buffer=img4; break; } } g.drawImage(buffer,0,0,null); } switch(state){の部分で「シンボルを解釈処理できません。シンボル: 変数 state」というエラーが出てしまいます。どこが間違っているかわかりません。お願いします。

    • ベストアンサー
    • Java
  • boolean型ではなくて

    booleanの2つの値を取る変数ではなく、3つの値を取れる変数ってあるのでしょうか?booleanを2つ使用した場合もやってみたのですがうまく動きませんでした。先に次のようにbooleanを記述して。 boolean state=true; boolean state1=true; boolean state2=true; 後半部分で次のようにやってみたのですが、3値とったことにはならないですかね?(^^; if(state)     {      if(state1){buffer=img2;}      else{buffer=img3;}      if(state2){buffer=img4;} else{buffer=img5;}     } else{} g.drawImage(buffer,0,0,null); state1 = !state1; state2 = !state2;

    • ベストアンサー
    • Java
  • Appletのrepaint()が動作しません

    import java.applet.*; import java.awt.*; /*<applet code="zxy" width="1000" height="1000"></applet>*/ class Object extends Applet { protected int x; /* オブジェクトのx座標 */ protected int y; /* オブジェクトのy座標 */ protected int width; protected int height; Image buffer; Graphics buffer_g; Dimension d = getSize(); public Object() { x = 0; y = 0; width = 0; height = 0; } } /* 楕円クラス */ class Oval extends Object implements Runnable { public Oval() { width = (int)(Math.random() * 56 + 10); height = (int)(Math.random() * 56 + 10); } public void run() { while( true ){ try{ repaint(); Thread.sleep(50); } catch( Exception e ){} } } public void paint( Graphics g ) { if( buffer_g == null ) buffer_g = buffer.getGraphics(); Dimension d = getSize(); buffer_g.setColor( Color.white ); buffer_g.fillRect( 0, 0, d.width, d.height ); buffer_g.setColor( Color.black ); buffer_g.drawOval( x, y, width, height ); x += (int)(Math.random() * 10); y += (int)(Math.random() * 10); g.drawImage( buffer, 0, 0, this ); } } public class A extends Applet { Image buffer; Graphics buffer_g; Oval ov1 = new Oval(); Thread thOv1 = new Thread( ov1 ); public void start() { thOv1.start(); Dimension d = getSize(); buffer = createImage( d.width, d.height ); } } 上記プログラムを実行しても、paint()の中が実行されずにtryブロックを繰り返すだけになってしまいます。paint()を実行するにはどうすればいいでしょうか?

  • 意味がわかりません。

    2から902の中で乱数を10個ranに格納し、それをi=0からi+=ran表示するというプログラムを作成しました。下のプログラムはその1部なのですが、意味のわからない部分があり困っています。ranには得られた10個の乱数のうちの1つの数字が格納されますよね。10個取得したとはどういった処理がされるのでしょうか? public void paint(Graphics g){ int w,h; w = (int)getSize().width; h = (int)getSize().height; bufferGraphics.drawImage(image,0,0,this); bufferGraphics.setColor(Color.black); int rand; //2から902の中で乱数を10個ranに格納 for(int j=0; j<10; j++){ int ran = (int)(Math.random() * 1000)+2; for(int i=0;i<h;i+=ran){ bufferGraphics.drawLine(0,i,w,i); } g.drawImage(buffer,0,0,null); } }

    • ベストアンサー
    • Java
  • Graphics gra = this.getGraphics( );について

    public void drawPhotograph( ) { Graphics gra = this.getGraphics( ); if (image != null) { x = 0; y = 0; gra.drawImage(image,x,y,this); } } この場合、graの値がnullとなり、実行時に、NullPointer Exceptionが起こります。その原因は何なのでしょうか、また回避策はどのようにすればよいでしょうか?

  • シンボルが見つけられません。8個のエラー。

    シンボルが見つけられません。 8個のエラーメッセージがでました。 何度も打ち直しましたが、これ以上減りません。 ドコが誤ってますか? ご多忙中申し訳ありません。 ご回答の程、宜しくお願い申し上げます。 import java.applet.*; import java.awt.*; import java.util.*; public class DigitalClock extends Applet implements Runnable { Thread thread = null; Image Digit[ ] = new Image[11]; int DigitWidth, DegitHeight; Image WorkImage; Graphics WorkGraphics; int AppletWidth, AppletHight; //初期化処理---------------------------------------------------- public void init() { AppletWidth = getSize().width; AppletHight = getSize().height; WorkImage = createImage(AppletWidth, AppletHight); WorkGraphics = WorkImage.getGraphics(); MediaTracker mediaTracker = new MediaTracker(this); for(int i = 0; i < 11;i++) { Digit[i] = getImage(getCodeBase(),"Image/" + i +".gif"); mediatracker.addImage(Digit[i],1); } try{ mediatracker.waitForID(1); } catch (InterruptedException e) { showStatus(""+e); } DigitWidth = Degit[0].getWidth(this); DegitHeight = Digit[0].getHeight(this); } //アプレット開始------------------------------------------------------- public void start() { thread = new Thread(this); thread.start(); } //描画処理-------------------------------------------------------------- public void paint(Graphics g) { g.drawImage(WorkImage, 0, 0, this); } //スレッド処理------------------------------------------------------------ public void run(){ while (thread != null) { DispTime(); repaint(); try { thread.sleep(100); } catch(InterruptedException e) { showStatus(""+e); } } } //描画更新処理再定義---------------------------------------------------------- public void update(Graphics g) { paint(g); } //時間描画-------------------------------------------------------------------- void DispTime() { //カレンダーオブジェクト作成 Calendar date = Calendar.getInstance(TimeZone.getTimezone("JST")); int hour = date.get(Calender.HOUR); int minute = date.get(Calender.MINUTE); int second = date.get(Calendar.SECOND); //作業グラフィックに描画 WorkGraphics.setcolor(color.white); WorkGraphics.fillRect(0, 0, DigitWidth*8, DigitHight); int h1 = hour / 10, h2 = hour % 10; WorkGraphics.drawImage(Digit[h1], 0,0, this); WorkGraphics.drawImage(Digit[h2], DigitWidth*1, 0, this); WorkGraphics.drawImage(Digit[10], DigitWidth*2, 0, this); int m1 = minute / 10, m2 = minute % 10; WorkGraphics.drawImage(Digit[m1], DigitWidth*3, 0, this); WorkGraphics.drawImage(Digit[m2], DigitWidth*4, 0, this); WorkGraphics.drawImage(Digit[10], DigitWidth*5, 0, this); int s1 = second / 10, s2 = second % 10; WorkGraphics.drawImage(Digit[s1], DigitWidth*6, 0, this); WorkGraphics.drawImage(Digit[s2], DigitWidth*7, 0, this); } //アプレット停止 public void stop() { thread = null; } }

    • ベストアンサー
    • Java
  • 改良したいのですが

    画面上に表示している静止画像(img)の上に、ランダムに黒色のライン(buffer)を数本表示するというプログラムを作成しました。次はそのプログラムの一部なのですが、静止画像の上に表示している線を、黒色ではなく、静止画像の輝度情報が半分(50%)になっている線(画質が劣化している線)を表示させるように改良したいのですが、どこを変えたらいいのか、どのように変えたらいいのかわかりません。わかる方いましたら、アドバイス等お願いします。多分setColorの部分を変えると思うのですが・・・(^^; public void paint(Graphics g){ int w,h; w = (int)getSize().width; h = (int)getSize().height; bufferGraphics.drawImage(img,0,0,this); bufferGraphics.setColor(Color.black); //処理を10回繰り返す for(int j=0; j<10; j++){ //2から1002の中で乱数を1つranに取得 int ran = (int)(Math.random() * 1000)+2; for(int i=0;i<h;i+=ran){ //ranの値にしたがって画面上にラインを表示 bufferGraphics.drawLine(0,i,w,i); } g.drawImage(buffer,0,0,null); } } public void update(Graphics g){ paint(g); } public void run(){ while( true ){ try{ Thread.sleep(10); } catch(InterruptedException e){ } } } public void start(){ thread = new Thread(this); thread.start(); } }

    • ベストアンサー
    • Java
  • drawImageの描画速度について

    gをGraphics、imgをImageとして、g.drawImage(img, 0, 0, null);などをする時の描画速度について、imgのサイズが小さい場合はまあまあ一定なんですが、ある程度大きくなると数回に一回、数十ミリ秒程余計に時間がかかります。なぜ大きいとこうなるのか、理由を教えて下さい。

  • java - ifブロック内の変数スコープについて

    java初心者です。宜しくお願いします。 javaでポケットPC用のプログラムを作っています。ポケットPCだけでなく、パソコンでも 動かしたいのですが、ポケットPC用のjava("mySaifu")にはGraphics2Dクラスがサポート されていません。なのでここの記述を ・ポケットPCならGraphicsクラスを使用 ・ポケットPC以外ならGraphics2Dクラスを使う ようにしたいと思い次の様に記述しました。 protected void paintComponent(Graphics g) { if (System.getProperty("java.vm.vendor").equals("Mysaifu")) { Graphics g2 = (Graphics)g; } else { Graphics g2 = (Graphics2D)g; } g2.drawImage(im, 0, 0, 480, 640, this);    : (省略)    : } しかし、これではコーディング時点でエラーになります(Eclipse上で赤波線表示) ifブロックで宣言されている変数g2が"g2.drawImage(im, 0, 0, 480, 640, this)"以降に 適用されないためです(と自分では認識している)。 結局のところ"g2.drawImage(im, 0, 0, 480, 640, this)"以降の記述をifの両ブロック PC用、ポケットPC用ともに書かなければならない。少し非効率だと思います。 対策として、次のコーディングをしました Graphics2D g2 = null; if (System.getProperty("java.vm.vendor").equals("Mysaifu")) { g2 = (Graphics)g; } else { g2 = (Graphics2D)g; } これだと、ポケットPCだった場合(vm.vendorが"Mysaifu"の時)、キャストできま せんと言われます。 この事(if文で違う変数を宣言する)は、この例に限らず結構あると思います。 みなさんは、この様な場合どうしているのでしょうか?

    • ベストアンサー
    • Java

専門家に質問してみよう