Javaでのifブロック内の変数スコープについて

このQ&Aのポイント
  • Javaのifブロック内での変数スコープについて質問があります。ポケットPC用のプログラムを作成していますが、ポケットPCとそれ以外で使用するクラスが異なるため、if文を使用して適切なクラスを選択しています。
  • コーディング時にエラーが発生しており、変数g2がifブロック以降で適用されていないためだと考えています。非効率な解決策として、ifブロック外で変数g2を宣言し、if文内でキャストする方法も試しましたが、ポケットPCの場合にキャストできないという問題が発生しました。
  • このような場合、どのように対処しているかご意見をいただきたいです。他の開発者はどのような方法を取っているのでしょうか?
回答を見る
  • ベストアンサー

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
  • 回答数3
  • ありがとう数3

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

  • ベストアンサー
  • salsberry
  • ベストアンサー率69% (495/711)
回答No.2

変更後のg2 = (Graphics)g;がエラーになるのはJavaの型システム上当然です。この場合、変数g2に代入できるのはGraphics2Dクラス(またはそのサブクラス)のオブジェクトだけなので。 一方、変更前のコードのGraphics g2 = (Graphics2D)g;には意味がありません。 変数g2に対してメソッドを呼ぶことができるかどうかは変数の型で決まるので、g2に対して呼べるのはGraphicsクラスで宣言されているメソッド(およびそれをGraphics2Dクラスでオーバーライドしたもの)だけだけです。 上記のようなキャストをしても、g2に対してGraphics2Dにしかないメソッド(たとえばrotate())を呼ぼうとするとコンパイル時にエラーになります。 もしポケットPCでない場合にGraphics2D固有のメソッドを呼びたいのであれば、結局ポケットPCの場合とそうでない場合でコードを分けて書く必要が生じます。 こんな風になります。変数g2は使っていません。 protected void paintComponent(Graphics g) { g.drawImage(im, 0, 0, 480, 640, this); // GraphicsとGraphics2Dで共通のメソッド if (ポケットPCではない) { ((Graphics2D)g).rotate(1.0); // Graphics2D固有のメソッド } g.drawLine(); // GraphicsとGraphics2Dで共通のメソッド    : (省略)    : }

ttomioka
質問者

お礼

回答ありがとうございます。 なるほど、確かにそうですね。Graphics2D固有の部分だけをif文で 切り分ければ良かったですね。多分、「変数g2を使う」と固執した為に それに気づかなかったのだと思います。 またGraphics2DがGraphicsを継承している点も勉強になりました。 ありがとうございました。

その他の回答 (2)

回答No.3

Graphics2Dクラスの継承図は下記となっています。 java.lang.Object └java.awt.Graphics └java.awt.Graphics2D Graphics2Dクラスは Graphicsを継承しています。 なので Graphics2Dのインスタンスを上位クラスのGraphicsにキャストは 可能ですが 逆に Graphics のインスタンスを Graphics2Dにキャストは 出来ません。 (∵Graphics2Dクラスで拡張されている機能をGraphicsクラスは知り得ません) つまり 下記メソッドの引数 Graphics g から Graphics2Dクラス キャストに失敗した原因は gの実体が Graphics2Dクラスのものでは なかったという事です。 protected void paintComponent(Graphics g)

ttomioka
質問者

お礼

回答ありがとうございます。 私の質問べたが原因で、本来の質問を取り違われている様です。 言いたかったことは g2.drawImage(im, 0, 0, 480, 640, this);    : (省略)    : の部分は、パソコンでもポケットPCでもほぼ共通なので、 「変数を共通化して1回の記述で済ませたい。すると何らかの  修正が発生した時でも1ケ所の修正で済む。でも出来ない。」 と言う点です。 その障壁となっているのがifブロック内の変数スコープでして 皆さんはどう対応しているのかな? と聞きたかったのです。 説明べたですみません。 Graphics2DがGraphicsを継承しているという点は勉強になりました。 ありがとうございました。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

もともとの (上の) プログラムでは Graphics g2 としているのに, なぜ書き換えた (下の) プログラムでは Graphics2D g2 なんでしょうか.

ttomioka
質問者

お礼

回答ありがとうございます。 ちょっと質問が変で申し訳ありません。言いたかったことは g2.drawImage(im, 0, 0, 480, 640, this);    : (省略)    : の部分は、パソコンでもポケットPCでもほぼ共通なので、 「変数を共通化して1回の記述で済ませたい。すると何らかの  修正が発生した時でも1ケ所の修正で済む。でも出来ない。」 と言う点です。 その障壁となっているのがifブロック内の変数スコープでして 皆さんはどう対応しているのかな? と聞きたかったのです。 説明べたですみません。 変数g2がGraphicsだとかGraphics2Dだとかと言うことは、java 初心者なのでという事でご容赦ください。 ありがとうございました。

関連するQ&A

  • JAVAの文法について教えてください。

    JAVAを学習しはじめたばかりの初心者です。 下記のプログラムに関してわからないので教えてください。 下記はtest.gif画像を表示するプログラムなのですが、 イメージを表示するために import java.awt.Graphicsをインポートして、 Image im でオブジェクトを宣言するのはわかるのですが、 通常はこの後に im = new Image() のようにインスタンス化する必要があると思うのですが、 このプログラムにはありません。 なぜ不要なのでしょうか? ********************** import java.applet.Applet; import java.awt.Graphics; import java.awt.Image; public class MyImage extends Applet{ Image im; public void init(){ im = getImage( getDocumentBase(), "test/test.gif" ); } public void paint(Graphics g){ g.drawImage( im ,10,10, this); } }

    • ベストアンサー
    • Java
  • javaの配列について。

    javaのプログラミングについてなのですが、配列を利用して、 画像イメージ zu0.jpg,zu1.jpg,zu2,jpgをウィンドウズアプリケーションで 3つ縦に並べて表示させ、ページ上部にタイトルを入れろという課題が出たのですが、 なかなかうまいきません。原因がわからないので質問させていただきます。 どうかお力添えお願いいたします。 ↓↓プログラム文↓↓ import java.awt.*; class PictF extends Frame{ Font f; Image im; PictF(){ setBackground(new Color(200,255,255)); f=new Font("Dialog",Font.ITALIC,36); Image[] im=new Image[3]; for(int i=0;i<im.length;i++) im[i]=Toolkit.getDefaultToolkit().getImage("zu"+i+".jpg"); setTitle("image"); setSize(400,700); } public void paint(Graphics g){ Image[] im=new Image[3]; for(int i=0;i<im.length;i++) g.drawImage(im[0],10,10,this); g.drawImage(im[1],10,100,this); g.drawImage(im[2],10,210,this); g.setFont(f); g.setColor(Color.blue); g.drawString("Ikeda Auditorium",100,240); } public static void main(String[] args){ PictF pf=new PictF(); pf.setVisible(true); } }

    • ベストアンサー
    • Java
  • パネルの絵の差し替え方法

    JBuilderでJavaの開発を勉強しています。 パネルがクリックされるたびに、パネルに張られている絵を差し替えたいのですが最初の2回のクリックではパネルの絵が消えてしまい3回目からのクリックでは問題なく絵は切り替わります。下記のロジックで問題があるのでしょうか? メインフレームのパネルクリックイベントから"public void ChangeImage(int num)"関数を呼びます。 ************************************************* public class New_Panel extends Panel { Image img; Image im_off; Image im_on; //CONSTRUCT public Panel_FD() { im_off = Toolkit.getDefaultToolkit().getImage("OFF.jpg"); im_on = Toolkit.getDefaultToolkit().getImage("ON.jpg");   //初期イメージ img = Toolkit.getDefaultToolkit().getImage("ON.jpg"); } public void paint(Graphics g){ g.drawImage(img, 0, 0, this); } //イメージ変更 public void ChangeImage(int num){ Graphics g; img.flush(); img = this.createImage(100, 40); if (sw == 0) { g = img.getGraphics(); g.drawImage(im_off, 0, 0, this); } else { g = img.getGraphics(); g.drawImage(im_on, 0, 0, this); } //再描画 repaint(); } } *************************************************

    • ベストアンサー
    • Java
  • インターネット上の画像をJavaで処理する方法について

    こんにちは! いつもお世話になってます(^^) mkimさんのおかげでマウスでブラウザ(IE5.0)上の灰色の部分の座標値を得ることはできました(^o^) 私の質問 http://oshiete1.goo.ne.jp/kotaeru.php3?q=77352 しかし、その灰色の部分に画像を貼り付け、その画像の座標値を得たいのですが、画像をうまく貼り付けることができません。 javaファイルのと同じディレクトリにあるローカルな画像は貼り付けて座標値を得ることができたのですが、インターネット上にある画像を貼り付けることができませんでした。 最終的にはライブカメラの画像を貼り付けようと考えているので、これができないと先に進むことができません。 誰かご存知でしたら教えてください(^^) わかりにくい質問でごめんなさいm(__)m 一応、うまくいかなかったjavaファイルを載せておきます。 // My_Image03.java import java.awt.Graphics; import java.applet.Applet; import java.awt.Image; public class My_Image03 extends Applet { Image im; public void init() { im = getImage(getDocumentBase(), "http://www.honda.co.jp/image/b_hmark.gif"); } public void paint(Graphics g) { g.drawImage(im, 10, 10, this); } } 構文が間違っているのでしょうか? 回答、お待ちしております(^o^)丿

    • ベストアンサー
    • Java
  • Javaを説明するには

    4枚の絵をパラパラアニメにするソースなのですが。これをわけ合って説明しなくてはならなくなってしまいました。 薄らぼんやりとはわかるのですが。どう説明したらいいのかさっぱり分かりません、どう説明すれば、分かりやすく正しく伝えられるでしょうか?>< import java.applet.Applet; import java.awt.Graphics; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class DNA extends Applet implements Runnable, ActionListener { Image image[] = new Image[4]; int[] timing = { 400,350,230,350}; Thread t; int index1 = 0; int no = 0; private static final long serialVersionUID = 1L; public void init(){ for(int i = 0; i<4; i++){ image[i] = getImage(getDocumentBase(),"img"+(i)+".gif"); } } public void paint(Graphics g){ g.drawImage(image[index1],0,0,this); } public void update(Graphics g) { paint(g); if(++no==4)no=0; } public void start(){ t = new Thread(this); t.start(); } public void run() { while(true){ index1++; if(index1 == 4){ index1 = 0; } repaint(); try{ Thread.sleep(timing[no]); }catch(InterruptedException e){} }} public void actionPerformed(ActionEvent arg0) { } }

  • Javaのダブルバッファリングについてお伺いしたいのですが、

    Javaのダブルバッファリングについてお伺いしたいのですが、 Thred.sleep(20) ペイント部 public void paint(Graphics g) { g.drawImage(wbuffer, int x, int y, this); } アップデートメソッド public void update(Graphics g) { paint(g); } 他のクラスからもこのwbufferの中にいったん書き込むようにしています。 チラつきが出る要因として考えられるのはどんなことがあるのでしょうか? ・オブジェクトの数が多い というのが原因でしょうか。 だいたい5秒おきくらいにチラつきが生じます。

    • ベストアンサー
    • Java
  • javaでgraphicsの描画の件

    今日は javaでgraphicsの描画を行っていますが、CENTERのペインには、描画できますが、 それ以外のペイン(NORTH,WEST、EAST,、SOUTH)には、描画できないように思います。 Q1)この件について、コメント頂けますと大変助かります。 下記に、ソースコードを添付いたします。 =================== package pkg; import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.Line2D; import javax.swing.JFrame; import javax.swing.JPanel; public class SampleApp extends JFrame { public SampleApp(){ this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(600, 300); this.add(new GPanel(), BorderLayout.WEST); this.add(new GPanel(), BorderLayout.CENTER); } public static void main(String[] args) { new SampleApp().setVisible(true); } } class GPanel extends JPanel { @Override public void paintComponent(Graphics g) { super.paintComponent(g); // int w = this.getWidth(); // int h = this.getHeight(); int w=200; int h=200; g.setColor(Color.RED); g.fillOval(0, 0, w/2, h/2); Graphics2D g2 = (Graphics2D)g; g2.draw(new Line2D.Double(40, 40, w,h)); g.setColor(Color.BLUE); g.setFont(new Font("Serif", Font.BOLD, 36)); g.drawString("Graphics draw!", 10, h - 50); // g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.draw(new Line2D.Double(30.0d, 50.0d, 180.0d, 140.0d)); g2.setPaint(Color.PINK); BasicStroke wideStroke = new BasicStroke(8.0f); g2.setStroke(wideStroke); g2.draw(new Line2D.Double(30.0d, 120.0d, 250.0d, 70.0d)); } }

    • ベストアンサー
    • Java
  • javaでエラーを起こす変数の特定

    こんにちは. java初心者です. try~catchでエラー処理を行うことについて質問です. try~catchでは,エラーを起こした変数を特定することは出来ないのでしょうか? 例えばアプレットで画像を表示させる下記のコードについて, img1とimg2の変数を使いますが,img1に読ませるファイルは存在するが img2に読ませるファイルが存在しない場合に,「img2に読み込ませるファイルが存在しません」と表示したいのです. このようにどの変数がエラーを起こしたかを特定することはできますか? ============== import java.awt.*; import java.applet.*; import java.awt.event.*; public class Sample extends Applet{ Image img1, img2; int x=0, y=0; public void init() { System.out.println("init"); try{ img1 = getImage(getClass().getResource("img/sample1.jpg")); img2 = getImage(getClass().getResource("img/sample2.png")); } catch(Exception e){ System.out.println("エラー" + e + "が返されました."); } } public void paint(Graphics g){ g.drawImage(img1, 0, 0, this); g.drawImage(img2, 50, 50, this); } } ============== try{  img1に関する処理 } catch(Exception e){ img1に関するエラー処理 } try{  img2に関する処理 } catch(Exception e){ img2に関するエラー処理 } とやればできそうですが,あまりに冗長なので他に方法があると思うのですが… 自分もまだ勉強しはじめたばかりなので,初歩的な質問で恐縮です. 教本やネットで調べても分からなかったので質問させていただきました. よろしくお願いいたします.

    • ベストアンサー
    • Java
  • Java appletプログラムで困ってます。

    市販の本に掲載せれているEclipse下記プログラムを丸写しで打込みコンパイルしました。 それでWEB上で確認した所、オブジェクト動作上(.pngの表示・非表示)では動作している様に思います。 しかし、どうもLANネットワーク(最終的にはRS232C)動作反応がありません プログラムに問題があるのでしょうか? ネットワーク・セキュリティー・ファイヤウォール等に問題があるのでしょうか? まったく見当がつきません。Java言語は初心者です。 ご教授宜しくお願い致します。 import java.applet.Applet; import java.awt.Button; import java.awt.Event; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; public class xport002 extends Applet implements Runnable{ boolean sw1,sw2,run; Image img1,img2,img3; String buff; char com; Thread th=null; int port=10001; InetAddress xport_ip=null; Socket xport_socket; DataInputStream socketin; DataOutputStream socketout; public void init(){ try{ xport_ip=InetAddress.getByName(getCodeBase().getHost()); } catch(UnknownHostException e){} try{ xport_socket=new Socket(xport_ip,port); //socketin=new DataInputStream(xport_socket.getInputStream()); socketout=new DataOutputStream(xport_socket.getOutputStream()); } catch(Exception e){} img1=getImage(getDocumentBase(),"base2.png"); img2=getImage(getDocumentBase(),"Red3.png"); img3=getImage(getDocumentBase(),"Red4.png"); add(new Button("LED-R1")); add(new Button("LED-R2")); repaint(); } public boolean action (Event e,Object obj){ if(obj.equals("LED-R1")){ sw1=!sw1; com='1'; repaint(); run=true; } else if(obj.equals("LED-R2")){ sw2=!sw2; com='2'; repaint(); run=true; } return true; } public void start(){ if(th==null){ th=new Thread(this); th.start(); } } public void run(){ Thread me=Thread.currentThread(); while(th==me){ if(run){ try{ socketout.writeByte(com); socketout.flush(); repaint(); th.sleep(1000); } catch(Exception e){} run=false; sw1=false; sw2=false; repaint(); } try{ buff=socketin.readLine(); repaint(); } catch(IOException e){} } } public void stop(){ if(th!=null){ try{ socketin.close(); socketout.close(); xport_socket.close(); } catch(Exception e){} th.stop(); th=null; } } public void paint(Graphics g){ g.drawImage(img1,100,50,this); if (sw1)g.drawImage(img2,100,50,this); if (sw2)g.drawImage(img3,150,50,this); String t1=buff+"℃"; g.setFont(new Font("MS明朝",Font.BOLD,36)); g.drawString(t1, 100, 200); } }

  • java.lang.OutOfMemoryErrorというエラーがでる。

    javaを勉強しています。タイトルのように java.lang.OutOfMemoryErrorというエラーが出てしまいます。少し調べてみたらどうやらメモリーの使いすぎ(?)のようなのですが、プログラムの方に問題があるのでしょうか?それとも使えるメモリーを増やすといった解決策を取ったほうがいいのでしょうか? よろしくお願いします。プログラムはまず画像が表示されて、左クリックすると次の画像へ変わる、といった処理をするアプレットです。 package jibundesukosidutu; import java.applet.Applet; import java.awt.Graphics; import java.awt.MediaTracker; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; public class Main extends Applet implements MouseListener{ File[] imagelist; File image = new File("image"); BufferedImage drawImage; static int i = 0; MediaTracker mt = new MediaTracker(this); public void init(){ imagelist = image.listFiles();//ディレクトリの画像ファイルたちを配列に入れていく。 addMouseListener(this); try { drawImage = ImageIO.read(imagelist[i]);//drawImageメソッドで画像ファイルとして引数を取れるように、型変換しておく。 } catch (IOException e) { e.printStackTrace(); } } public void paint(Graphics g){//drawImageファイルを表示するだけ int w, h; w = getSize().width; h = getSize().height; mt.addImage(drawImage,0); try { mt.waitForID(0); } catch (InterruptedException e) { e.printStackTrace(); } g.drawImage(drawImage,0,0,w,h,this);//imagelist[0]を表示したい。 } public void mouseClicked(MouseEvent e) { int btn = e.getButton(); if(btn == MouseEvent.BUTTON1){//左クリック=進め System.out.println("左クリック"); i++; //searchFile(true); try { drawImage = ImageIO.read(imagelist[i]); } catch (IOException e1) { e1.printStackTrace(); } repaint(); }else if(btn == MouseEvent.BUTTON2){ System.out.println("右クリック"); //searchFile(false); } } public void searchFile(boolean next){ //next→次の画像、false→前の画像 } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } }

    • ベストアンサー
    • Java

専門家に質問してみよう