先に計算したほうがいい?

このQ&Aのポイント
  • Math.PI / 180 の部分は先に計算しておいたほうが処理が早くなると言われたが、そうなのだろうか?
  • 質問文章から先に計算するかどうか悩んでいる。掛け算をしないといけないと思うが…
  • JavaのプログラムでMath.PI / 180 の計算を先にするべきか迷っている。
回答を見る
  • ベストアンサー

先に計算したほうがいいのでしょうか?

下記のプログラムを作ったのですが、 Math.PI / 180 の部分は先に計算しておいたほうが処理が 早くなると言われたのですがそうなのでしょうか? 先に掛け算をしないといけないような気がするのですが。 import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; import java.lang.Math; public class Test9 { public static void main(String[] args) { int r = (args.length > 0)? Integer.parseInt(args[0]):100; int n = (args.length > 1)? Integer.parseInt(args[1]):16; int x, y, x1, y1; try { BufferedImage image=new BufferedImage(r*2+10,r*2+10,BufferedImage.TYPE_INT_RGB); Graphics2D g2d=image.createGraphics(); g2d.setBackground(Color.WHITE); g2d.clearRect(0,0,r*2+10,r*2+10); g2d.setColor(Color.BLACK); for ( double i = 0.0; i < 360.0; i += 360.0 / n ) { x1 = (int) ( r * Math.cos( i * Math.PI / 180 ) ); y1 = (int) ( r * Math.sin( i * Math.PI / 180 ) ); for( double j = i + 360 / n; j < 360.0; j += 360.0 / n ) { x = (int) ( r * Math.cos( j * Math.PI / 180 ) ); y = (int) ( r * Math.sin( j * Math.PI / 180 ) ); g2d.drawLine( x1 + r + 5, y1 * (-1) + r + 5, x + r + 5, y * (-1) + r + 5 ); } } ImageIO.write(image, "JPEG", new File("c:\\test9.jpg")); } catch(Exception e) { e.printStackTrace(); } } }

  • Java
  • 回答数3
  • ありがとう数1

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

  • ベストアンサー
  • ninoue
  • ベストアンサー率52% (1288/2437)
回答No.1

確かに (j * Math.PI / 180)の中の*,/演算のどちらを先に実行するかで結果の最下位ビット等が異なる場合もあるかも知れません。 しかしそれは他にもプログラム内に出てくる短精度/倍精度の演算全てについて言える事で、特定の計算ステップを抜き出して問題にしても始まらないのではと思われます。 (全体として短(倍)精度で十分だとの判断がある筈なので) drawLine()の処理がずっと重いので、Math.PI / 180の部分を別の定数に置き換えてもトータルの実行時間には殆ど影響しないでしょう。 それと定数同士の割り算が(複数回)出てきますが、多分コンパイル時に最適化処理の一環として割り算結果を別の乗数として出力したりすると思われますので、この点からもそのままでも問題無いと思われます。 (結果的には同じ筈ですが、Math.PI / 180.0 と書く方が良いのではと思われます)

maiko0318
質問者

お礼

ありがとうございました。

その他の回答 (2)

回答No.3

結論から言うと、rの値を極端に大きな値にしないならMath.PI / 180を先に計算する誤差はまずプログラムの結果に影響しないと思います。また、やはり浮動小数点演算は遅いので、Math.PI / 180を先に計算するとその分の計算を省ける分だけ性能が良くなります。 i * Math.PI / 180の部分しか見ていませんが、Math.PI / 180が先にあるとiの結果によらずMath.PI / 180の計算ができるので、少なくともJITされたあとのコードではMath.PI / 180を計算したあとの定数値としてそこが扱われると思います。先に置かないでも、i * (Math.PI / 180)で同じ事になるでしょう。当然、ループ内での浮動小数点演算の回数が大幅に減るので、その分性能が向上します。 ただ、質問者もお分かりの通り、その場合の誤差は現状より大きくなります。 計算の精度を犠牲にしても高速化が必要ならi * (Math.PI / 180)とすると思いますが、何れにしても盲目的に高速化するのではなくちゃんと計測して効果を理解した上でその変更をするか決めるべきでしょう。例えば、こんな感じに改造して実行してみたらどれくらい高速化したかわかると思います。 import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; import java.lang.Math; public class FloatTest { /** * @param args */ public static void main(String[] args) { int r = 100; int n = 16; int x, y, x1, y1; try { BufferedImage image = new BufferedImage(r * 2 + 10, r * 2 + 10, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = image.createGraphics(); g2d.setBackground(Color.WHITE); g2d.clearRect(0, 0, r * 2 + 10, r * 2 + 10); g2d.setColor(Color.BLACK); long startTime = System.currentTimeMillis(); for (int cnt = 0; cnt < 10000; cnt++) { for (double i = 0.0; i < 360.0; i += 360.0 / n) { x1 = (int) (r * Math.cos(i * (Math.PI / 180))); y1 = (int) (r * Math.sin(i * (Math.PI / 180))); for (double j = i + 360 / n; j < 360.0; j += 360.0 / n) { x = (int) (r * Math.cos(j * (Math.PI / 180))); y = (int) (r * Math.sin(j * (Math.PI / 180))); g2d.drawLine(x1 + r + 5, y1 * (-1) + r + 5, x + r + 5, y * (-1) + r + 5); } } } long estimatedTime = System.currentTimeMillis() - startTime; System.out.println("Elapsed time:" + estimatedTime); // ImageIO.write(image, "JPEG", new File("c:\\test9.jpg")); } catch (Exception e) { e.printStackTrace(); } } } ついでに、誤差でどの程度結果が変わるかも調べてみましょう。 import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; import java.lang.Math; public class FloatTest { /** * @param args */ public static void main(String[] args) { int r = 100; int n = 16; int x, y, x1, y1; try { BufferedImage image = new BufferedImage(r * 2 + 10, r * 2 + 10, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = image.createGraphics(); g2d.setBackground(Color.WHITE); g2d.clearRect(0, 0, r * 2 + 10, r * 2 + 10); g2d.setColor(Color.BLACK); double diff2 = 0; for (double i = 0.0; i < 360.0; i += 360.0 / n) { x1 = (int) (r * Math.cos(i * Math.PI / 180)); y1 = (int) (r * Math.sin(i * Math.PI / 180)); diff2 += Math.pow( ((int) (r * Math.cos(i * (Math.PI / 180))) - x1), 2); diff2 += Math.pow( ((int) (r * Math.sin(i * (Math.PI / 180))) - y1), 2); for (double j = i + 360 / n; j < 360.0; j += 360.0 / n) { x = (int) (r * Math.cos(j * Math.PI / 180)); y = (int) (r * Math.sin(j * Math.PI / 180)); diff2 += Math.pow( ((int) (r * Math.cos(j * (Math.PI / 180))) - x), 2); diff2 += Math.pow( ((int) (r * Math.sin(j * (Math.PI / 180))) - y), 2); g2d.drawLine(x1 + r + 5, y1 * (-1) + r + 5, x + r + 5, y * (-1) + r + 5); } } System.out.println("sigma=" + Math.sqrt(diff2)); // ImageIO.write(image, "JPEG", new File("c:\\test9.jpg")); } catch (Exception e) { e.printStackTrace(); } } } 実行した結果、sigma = 0.0となるので、コードが間違っていなければどうやらx,y,x1,y1については(Math.PI / 180)を先に計算することによる誤差の影響はないようです。(int)(r * Math....)となっている以上、rが十分大きくないと誤差の影響で結果が変わることはないということなんでしょうね。 #1さんのコメントにちょっと指摘を。 > drawLine()の処理がずっと重いので、Math.PI / 180の部分を別の定数に置き換えてもトータルの実行時間には殆ど影響しないでしょう。 自分のコードが間違っていなければ、目に見えた差があるように思います。 > それと定数同士の割り算が(複数回)出てきますが、多分コンパイル時に最適化処理の一環として割り算結果を別の乗数として出力したりすると思われますので、この点からもそのままでも問題無いと思われます。 演算子順序として、*,/は左結合で、結合順序によって結果が変わるものなので、最適化しても * Math.PI / 180と* (Math.PI / 180)は同じにはならないと思います。もしそういう最適化をしたらコンパイラのバグでしょう。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

数学の法則から a * b / c = a * b * ( 1 / c ) ※ 割り算は、逆数のかけ算と同じ = a * (b * ( 1/c ) ) ※ かけ算だけのときは、計算順を変えても同じ(結合法則) = a * (b/c) ※ かけ算は、逆数の割り算と同じ ですよね? double pi180= Math.PI / 180 ; 等と先に計算した結果を変数に残しておいて Math.cos( i * pi180 ) 等と使う、ということです。 割り算が1つ減ります。 計算誤差を考えると ・ i * Math.PI / 180 の方が誤差が少ないです。(i*Math.PIで発生した誤差が、/180することで小さくなるので) ・for ( double i = 0.0; i < 360.0; i += 360.0 / n ) これは、ループの度に、 360.0/n の誤差が累積するので、あまりよくありません。 for(int i0=0;i0<n;i0++) 等と、ループ回数でのループを作って dounle i = 360.0 * (double)i0 / (double)n ; 等と、回数に対応した角度を計算すると、誤差が少なくなります。また、度数での角度を使用しないのなら、 i * Math.PI / 180 =(360.0 * (double)i0 / (double)n) * Math.PI / 180 = 2.0 * (double)i0 * Math.PI / (double)n とすることもできます。 > for( double j = i + 360 / n; j < 360.0; j += 360.0 / n ) iの最小値は0.0ですから、i+360は360以上になります。 よって、 j<360.0は常に偽であり、このループは一度も実行されないということになります。

関連するQ&A

  • RGB値の取得について(java)

    お世話になります。 Javaプログラム上で、指定した画像のRBG値を取得するプログラムを作りましたが、得られた値が思わしくありません。最終的にグレースケール化するためにRGB値を取得したいと考えています。 例えば、原画像の左上の画素のRGB値をgimpで確認すると、それぞれ200前後の値が、プログラムで返された値は50前後になってしまいます。 以下にソースを貼ります。とりあえず、100個の画素のRGB値を取得するように設定しています。まだjavaを勉強し始めて日が浅く、低レベルの質問かもしれませんが、解決策を教えていただける方、よろしくお願いいたします。 import java.io.*; import java.lang.*; import java.awt.*; import java.awt.color.ColorSpace; import java.awt.event.*; import javax.swing.*; import javax.imageio.ImageIO; import javax.media.*; import javax.media.control.*; import javax.media.format.*; import javax.media.util.*; import java.awt.image.*; import java.applet.*; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; import java.io.File; import java.io.IOException; import java.util.*; import java.text.*; public class Sample{ static BufferedImage image; public static void main(String[] args){ try { //画像ファイルのデータを読み込む image = ImageIO.read(new File("C:\\QR\\imagefile\\sa.bmp")); } catch (Exception e) { e.printStackTrace(); image = null; } int i,j; int width = image.getWidth(); int height = image.getHeight(); int gray[][] = new int[width][height]; for(i = 0;i < 1 ;i++){ for(j = 0;j < 100 ;j++){ int rgb = image.getRGB(j,i); rgb = 0-rgb; int b = rgb%256; System.out.print(" "+b); int g = (rgb/256)%256; System.out.print(" "+g); int r = rgb/256/256; System.out.print(" "+r); gray[j][i] = (int)((0.299*r + 0.587*g + 0.114*b)); } System.out.println(""); } } }

    • ベストアンサー
    • Java
  • 任意の文字列をJAVAで画像化

    表題にある通り任意の文字列をJAVAで画像化したいと思い 下記サンプルを検索して見つけたのですが作成される画像は 真っ白な画像で文字列は表示されませんでした。 任意の文字列を画像として出力するにはどうすればよいでしょうか。 import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; public class Test5 { public static void main(String[] args) { String str = "abc123"; new Test5().Create(str); System.out.println(str); } public void Create(String str) { int w=60; int h=17; try { //受け取った文字列を画像化 BufferedImage image=new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB); Graphics2D g2d=image.createGraphics(); g2d.setBackground(Color.WHITE); g2d.clearRect(0,0,w,h); g2d.setColor(Color.BLACK); g2d.drawString(str,0,0); ImageIO.write(image, "JPEG", new File("c:\\test.jpg")); } catch(Exception e) { e.printStackTrace(); } } }

    • ベストアンサー
    • Java
  • アナログ時計のつくりかた

    お世話になります。 現在アナログ時計を作成しているのですが、 時間を指す針がうまく動いてくれません。 今は、5時代なら5のところを指すだけで、 6時までの中間地点を全く指してくれない状態です。 import java.awt.*; import java.applet.*; import java.util.*; public class tokei extends Applet{ public void paint(Graphics g){ g.drawOval(0,0,150,150); Calendar cal=Calendar.getInstance(); int hr = cal.get(Calendar.HOUR); int min = cal.get(Calendar.MINUTE); int x0, x1, y0, y1, x2, y2, r1=30, r2=45; x0=75; y0=75; x1=75+(int)Math.rint(r1*Math.sin(hr/12.0*2*Math.PI)); y1=75-(int)Math.rint(r1*Math.cos(hr/12.0*2*Math.PI)); g.drawLine(x0, y0, x1, y1); x2=75+(int)Math.rint(r2*Math.sin(min/60.0*2*Math.PI)); y2=75-(int)Math.rint(r2*Math.cos(min/60.0*2*Math.PI)); g.drawLine(x0, y0, x2, y2); } } x1=75+(int)Math.rint(r1*Math.sin(hr/12.0*2*Math.PI)); y1=75-(int)Math.rint(r1*Math.cos(hr/12.0*2*Math.PI)); の部分が間違っているのだろうなと思うのですが、 どのように直せばよいのかわかりません。 恐れ入りますが、どなかた教えて頂けないでしょうか? どうぞよろしくお願いいたします。

  • 一次元配列から画像を生成するとき。。。

    お世話になります。 カラー画像をjavaプログラムで読み込み、グレースケース化して画像を生成したいのですが、最後の画像生成の部分がうまくいきません。具体的には、 Image img_gray = createImage(new MemoryImageSource(w idth,height,rgb_gray,0,width)); として、img_grayという画像ファイルに変換しようとしています。しかし、コマンドプロンプトでコンパイルしようとすると、 C:\QR>javac Sample.java Sample.java:78: static でない メソッド createImage(java.awt.image.ImageProducer) を static コンテキストから参照することはできません。 Image img_gray = createImage(new MemoryImageSource(width,height, rgb_gray,0,width)); というエラーが出てしまいます。原因が分かりません。どなたか解決策を教えていただける方おられましたらよろしくお願いします。 以下にソースを貼っておきます。 import java.io.*; import java.lang.*; import java.awt.*; import java.awt.Color; import java.awt.color.ColorSpace; import java.awt.event.*; import javax.swing.*; import javax.imageio.ImageIO; import javax.media.*; import javax.media.control.*; import javax.media.format.*; import javax.media.util.*; import java.awt.image.*; import java.applet.*; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; import java.io.File; import java.io.IOException; import java.util.*; import java.text.*; public class Sample extends JPanel{ static BufferedImage image; //static BufferedImage change_image; public static void main(String[] args) { //************************************************************************************************ try { //画像ファイルのデータを読み込む image = ImageIO.read(new File("C:\\QR\\imagefile\\sa.bmp")); } catch (Exception e) { e.printStackTrace(); image = null; } // *********************************************************************************************** //グレースケール int i,j,r,g,b,d; Color color; int width = image.getWidth(); int height = image.getHeight(); int size = width * height; int[] rgb_src=new int[size]; int[] rgb_gray=new int[size]; PixelGrabber grabber= new PixelGrabber(image,0,0,width,height,rgb_src,0,width); try{ grabber.grabPixels(); //画像imageを配列rgb_src[]に読み込む }catch(InterruptedException e){} //カラー画像をグレイ化する for(i=0;i<size;i++){ color=new Color(rgb_src[i]); r=color.getRed(); //赤の成分を取り出す g=color.getGreen(); //緑の成分を取り出す b=color.getBlue(); //青の成分を取り出す d=(int)(r*0.299+g*0.587+b*0.114); //グレイの成分を作る(NTSC方式準拠) color=new Color(d,d,d); rgb_gray[i]=color.getRGB(); } Image img_gray = createImage(new MemoryImageSource(width,height,rgb_gray,0,width)); } }

    • ベストアンサー
    • Java
  • sin曲線とcos曲線を描くプログラムについて

    お世話になります。 Javaのプログラミングを習い始めたものです。 標記の件ですが、プログラムを見てもどうしてそうなるかが さっぱりわからない部分があります。 import java.awt.*; import java.applet.*; public class Example2 extends Applet{ public void paint(Graphics g){ // 座標軸を描く g.drawLine(20, 10, 20, 130); g.drawLine(20, 70, 230, 70); // sinカーブを描く(20->220) g.setColor( Color.blue); int x0, y0, x1, y1; x1 = 20; y1 = 70; for (int i = 1; i <= 20; i++){ x0 = x1; y0 = y1; x1 = 20+(int)(i/20.0*200); y1 = 70-(int)(50.0*Math.sin(i/20.0*2*Math.PI)); g.drawLine(x0, y0, x1, y1); } // cosカーブを描く(20->220) g.setColor( Color.red); x1 = 20; y1 = 20; for (int i = 1; i <= 20; i++){ x0 = x1; y0 = y1; x1 = 20+(int)(i/20.0*200); y1 = 70-(int)(50.0*Math.cos(i/20.0*2*Math.PI)); g.drawLine(x0, y0, x1, y1); } } これで、赤と青の曲線が描かれるわけですが、 x1 = 20+(int)(i/20.0*200); y1 = 70-(int)(50.0*Math.sin(i/20.0*2*Math.PI)); の部分がさっぱりわかりません。 今まで、"int"は変数宣言でしか用いられなかったのに、 今回突然この式の中に組み込まれており困惑しています。 また、iが回数を表すのはわかりますが、それを全回数で割ったり、 x1の式の中でなぜ200を掛けるのか、 y1の式の中でなぜ2を掛け、さらに円周率まで掛けるのかが どうしても理解できません。 どなたか、ご教授願えませんでしょうか。 あるいは、参考になるサイトを教えていただければ助かります。 どうぞよろしくお願いいたします。

    • ベストアンサー
    • Java
  • javaの画像の表示のプログラムとmouselistenerのプログラ

    javaの画像の表示のプログラムとmouselistenerのプログラム(それぞれ↓にあります)をひとつに合わせたいのですがどうすればいいでしょうか? import java.awt.event.*; import javax.swing.*; class MyPanel extends JPanel implements MouseListener{ public MyPanel() { addMouseListener(this); } public void mouseClicked(MouseEvent e) { int x=e.getX(); int y=e.getY(); System.out.println("マウスがクリックされました (" + e.getX() + ", " + e.getY() + ")"); if((x<100&&x>40)&&(y<100&&y>40)){ System.out.println("範囲内"); }else{ System.out.println("aaa"); } } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } } public class MouseEventExample extends JFrame { public static void main(String[] args) { new MouseEventExample(); } MouseEventExample() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); getContentPane().add(new MyPanel()); setSize(300, 200); setVisible(true); } } ======↑のプログラムと↓のプログラムを合わせたいのです package novel; import java.awt.*; import java.awt.geom.*; import java.awt.event.*; import javax.swing.*; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; import java.io.IOException; public class Java2dTest extends JFrame{ public static void main(String[] args){ Java2dTest test = new Java2dTest(); test.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){System.exit(0);} }); test.setBounds( 0, 0, 200, 200); test.setVisible(true); } public void paint(Graphics g){ Graphics2D g2 = (Graphics2D)g; BufferedImage readImage = null; try { readImage = ImageIO.read(new File("sample.png")); } catch (Exception e) { e.printStackTrace(); readImage = null; } if (readImage != null){ g2.drawImage(readImage, 0, 0, this); } } }

  • イベント処理がうまくいきません。

    java初心者です。 スタートボタンをクリックするとトランプ52枚表示されるようにしたいのですが、 1枚も表示されず、原因もよく分からないため苦労してます。 よろしくお願い致します。 以下は、プログラムです。 import java.awt.Color; import java.awt.Dimension; import java.awt.*; import javax.swing.*; import java.io.*; import javax.imageio.*; import java.awt.Graphics; import java.awt.Font; import javax.swing.JButton; import java.awt.Container; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.event.*; public class narabi2 extends JPanel{ JButton btn1,btn2,btn3; static Image img[] = new Image[52]; public static void main(String[] args) { JFrame f = new JFrame(); f.setDefaultCloseOperation(f.EXIT_ON_CLOSE); f.setResizable(true); f.setVisible(true); new narabi2(); } public narabi2(){ btn1 = new JButton("スタート"); this.add(btn1); btn1.addActionListener(new ev()); btn2 = new JButton("ランキング"); this.add(btn2); btn2.addActionListener(new ev()); btn3 = new JButton("ログアウト"); this.add(btn3); btn3.addActionListener(new ev()); JFrame f = new JFrame(); f.setSize(900,840); f.getContentPane().setBackground(new Color(0,100,0)); f.setDefaultCloseOperation(f.EXIT_ON_CLOSE); f.setResizable(true); f.setVisible(true); f.add(this); } public void paintComponent(Graphics g){ super.paintComponent(g); btn1 = new JButton("スタート"); this.add(btn1); btn1.addActionListener(new ev()); btn2 = new JButton("ランキング"); this.add(btn2); btn2.addActionListener(new ev()); btn3 = new JButton("ログアウト"); this.add(btn3); btn3.addActionListener(new ev()); setBackground(new Color(0,100,0)); int i;               //カードを並べる処理 int x = 0,y=0; for (i = 0; i < 52; i++) { g.drawImage(img[i], x, y, null); x = x + 100; if(x>=900){ x=0; y=y+140; } } } class ev implements ActionListener{ public void actionPerformed(ActionEvent m){ if(m.getSource()==btn1) //スタート { //public static void main(String[] args) { // 画像ファイルの読み込み int i, j; int no = 0; String c[] = {"s","h","c","d"}; try { for(i = 0; i < 4; i++) { for(j = 1; j <= 13; j++) { //String filename = "cards.png"; String filename = String.format("cards/%s%02d.png", c[i], j); img[no] = ImageIO.read(new File(filename)); no++; } } } catch(Exception e) { System.out.println(e); System.exit(0); } // シャッフル Image w; for (i = 51; i >= 0; i--) { j = (int)(Math.random() * (i + 1)); w = img[i]; img[i] = img[j]; img[j] = w; } } /*public void paintComponent(Graphics g) { super.paintComponent(g); int i; int x = 0,y=0; for (i = 0; i < 52; i++) { g.drawImage(img[i], x, y, null); x = x + 100; if(x>=900){ x=0; y=y+140; } } }*/ } /*else if(m.getSource()==btn2) //ランキング { } else if(m.getSource()==btn3) //ログアウト { } }*/ } }

  • javaで画像を表示したのですが、変です。

    画像をのせたのですが、表示した画像の透明部分のところに予期しない形で画像が重なってしまいます。 また、ウィンドウのサイズを何回かスクロールしていじると元に戻ります。 文字数の関係ですべてのソースを乗せられないのですが、自作画像クラスだけ記載します。 import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JPanel; public class Layer extends JPanel { BufferedImage image; int x=0,y=0; //表示サイズ int lx=0,ly=0; //表示場所 int originalX,originalY; int startX,startY; Layer(){ } public void p(String imgpath,int lX,int lY,int X,int Y){ x=X;y=Y;lx=lX;ly=lY; image=Imagedraw(imgpath); } public void p(String imgpath,int lX,int lY){ lx=lX;ly=lY; image=Imagedraw(imgpath); x=originalX; y=originalY; setSize(x,y); } public void p(String imgpath){ image=Imagedraw(imgpath); x=originalX; y=originalY; setSize(x,y); } public BufferedImage Imagedraw(String imgpath){ BufferedImage img=null; try{ img = readImage(imgpath); }catch(Exception e){ e.printStackTrace(); } setLocation(lx,ly); setSize(x,y); return img; } public void setLocation(int lX, int lY){ lx=lX;ly=lY; super.setLocation(lx,ly); } public void paint(Graphics g){ //イメージを描画 g.drawImage(image,0,0,x,y,startX,startY,x+startX,y+startY,this); } public BufferedImage readImage(String path) throws IOException{ BufferedImage img; img = ImageIO.read(new File(path)); originalX=img.getWidth(); originalY=img.getHeight(); return img; } } どなたか原因に心当たりのある方、よろしくお願いいたします。 なお、画像はインターネット上での拾いものです。書かれた方には感謝いたします。

  • repaint()が実行されません。

    repaint()が実行されません。 もともとあるJEditorPane上に画像表示させるために、他のクラスからrepaint()をよびだしてpaint()を実行させようとしているのですが、実行されません……。 以下にプログラムを表示します。 import java.net.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; import java.io.IOException; public class Open extends JFrame {   public Open(){   }    public void paint(Graphics g){    System.out.println("paint開始");    Graphics2D g2 = (Graphics2D)g;    BufferedImage readImage = null;    try {    readImage = ImageIO.read(new File("sample.png"));    } catch (Exception e) {    e.printStackTrace();    readImage = null;    }      if (readImage != null){    g2.drawImage(readImage, 0, 0, this);    }    }    public void Fileload(){    System.out.println("再描写");    repaint();   } } 外部のクラスからFileload()を呼び出して実行すると"再描写"はコマンドプロンプト上に表示されるのですが"paint開始"は表示されません。なのでpaint()の呼び出しができていないのだと思うのですが……。 原因がわかりません……。 javaも質問も初心者なのでわかりづらいところがあるとは思いますが、どうぞよろしくお願いします。

    • ベストアンサー
    • Java
  • ボタンが表示されず困ってます・・・。

    javaで「カップル」というトランプゲームを作っているのですが、背景色を設定する所までは行きましたが、表示されるはずのボタン(スタート、ランキング、ログアウト)が表示されず困っています・・・。 import java.awt.Color; import java.awt.Dimension; import java.awt.*; import javax.swing.*; import java.io.*; import javax.imageio.*; import java.awt.Graphics; import java.awt.Font; import javax.swing.JButton; import java.awt.Container; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.event.*; public class narabi2 extends JPanel{ JButton btn1,btn2,btn3; static Image img[] = new Image[52]; public static void main(String[] args) { JFrame f = new JFrame(); f.setSize(900,840); f.getContentPane().setBackground(new Color(0,100,0)); f.setDefaultCloseOperation(f.EXIT_ON_CLOSE); f.setResizable(true); f.setVisible(true); new narabi2(); } public narabi2(){ btn1 = new JButton("スタート"); this.add(btn1); btn1.addActionListener(new ev()); btn2 = new JButton("ランキング"); this.add(btn2); btn2.addActionListener(new ev()); btn3 = new JButton("ログアウト"); this.add(btn3); btn3.addActionListener(new ev()); JFrame f = new JFrame(); f.setSize(900,840); f.getContentPane().setBackground(new Color(0,100,0)); f.setDefaultCloseOperation(f.EXIT_ON_CLOSE); f.setResizable(true); f.setVisible(true); } public void paintComponent(Graphics g){ super.paintComponent(g); int i; int x = 0,y=0; for (i = 0; i < 52; i++) { g.drawImage(img[i], x, y, null); x = x + 100; if(x>=900){ x=0; y=y+140; } } } class ev implements ActionListener{ public void actionPerformed(ActionEvent m){ if(m.getSource()==btn1) //スタート { // 画像ファイルの読み込み int i, j; int no = 0; String c[] = {"s","h","c","d"}; try { for(i = 0; i < 4; i++) { for(j = 1; j <= 13; j++) { //String filename = "cards.png"; String filename = String.format("cards/%s%02d.png", c[i], j); img[no] = ImageIO.read(new File(filename)); no++; } } } catch(Exception e) { System.out.println(e); System.exit(0); } // シャッフル Image w; for (i = 51; i >= 0; i--) { j = (int)(Math.random() * (i + 1)); w = img[i]; img[i] = img[j]; img[j] = w; } } /*else if(m.getSource()==btn2) //ランキング { } else if(m.getSource()==btn3) //ログアウト { } } }*/ btn2,3はやらなくていい所です。更にはbtn1(スタート)が押されたときに、トランプ52枚が全て表示されるようにしたいのですが、ボタンが表示されないがため確認出来ておりません。 色々とご不便をお掛けしますが例などを挙げてもらえるととても助かります。宜しくお願い致します。  

専門家に質問してみよう