質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

1299閲覧

java GUIについて

Puhu

総合スコア31

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

1クリップ

投稿2016/01/12 17:16

編集2016/01/13 10:41

javaでGUIを用いたアプリケーションを開発しています。
現在開発しているものは、PaintComponentの中で描画処理をし、それを数m秒単位で再描画させるものなのですが
PaintComponentの中での処理が多いのか、動作が思い通りに動きません。

例としては画面更新が非常に速く行われてしまい、なにが描画されているのかわからなくなる、等です。

**(調べたところ、AWTよりSwingのが動作が軽いことが解りましたが、SwingにはPaintComponentがないようなので、このままAWTで描画処理を作成することになりそうです。)
**
↑は間違いでした、paintComponentはSwingに含まれているものでした。失礼いたしました。

javaのGUIプログラムを組むうえで、動作が重くならないためにきをつけるべきことや、私はこうしてるよ、などのことがあればぜひ教えて頂きたいです。

補足
コメントありがとうございます。現在作成しているのは音楽ゲームで、常にノーツ(譜面のこと)や、判定時のエフェクトを描画させています。

java

1public void paintComponent(Graphics g) { 2 super.paintComponent(g); 3 //Graphics2D g2 = (Graphics2D)g; 4 //GradientPaint gp = new GradientPaint(vimani.type,10,Color.black,vimani.type,90,Color.cyan); 5 6 // レーン 7 g.setColor(new Color(153,51,51,255)); 8 g.fillRect(220,10, 30, 650); 9 g.fillRect(255,10, 30, 650); 10 g.fillRect(290,10, 30, 650); 11 g.fillRect(325,10, 30, 650); 12 13 g.setColor(new Color(255,255,255,255)); 14 g.fillRect(250,10, 5, 650); 15 g.fillRect(285,10, 5, 650); 16 g.fillRect(320,10, 5, 650); 17 18 g.setColor(new Color(255,180,0,255)); 19 g.fillRect(220,590,135,20); 20 //ノート 21 22 //押されたキーと対応するレーンを光らせる。 23 24 if(vimani.keytypeflg == true){//単押しのみの時はこっち 25 Graphics2D g2 = (Graphics2D)g; 26 GradientPaint gp = new GradientPaint(vimani.type,10,Color.black,vimani.type,90,Color.cyan); 27 g2.setPaint(gp); 28 g2.fillRect(vimani.type,10,30,580); 29 vimani.fuzecount++; 30 if(vimani.fuzecount == 5){ 31 vimani.keytypeflg = false; 32 vimani.fuzecount = 0; 33 } 34 } 35 if(vimani.keytypeflg2 == true){//同時押があったら 36 Graphics2D g3 = (Graphics2D)g; 37 GradientPaint gp2 = new GradientPaint(vimani.type2,10,Color.black,vimani.type2,90,Color.cyan); 38 g3.setPaint(gp2); 39 g3.fillRect(vimani.type2,10,30,580); 40 vimani.fuzecount2++; 41 if(vimani.fuzecount2 == 5){ 42 vimani.keytypeflg2 = false; 43 vimani.fuzecount2 = 0; 44 } 45 } 46 47 g.setColor(new Color(102,255,204,255));//ノーツの色 48 for(int i=vimani.one+1;i<vimani.y1ic;i++){ 49 if(vimani.y1[i] <640){ 50 g.fillRoundRect(220, vimani.y1[i], 30, 20, 5, 10); 51 vimani.y1[i]+=vimani.speed; 52 }else{ 53 if(vimani.playercombo > vimani.playerhighcombo){ 54 vimani.playerhighcombo = vimani.playercombo; 55 } 56 vimani.playercombo = 0; 57 vimani.y1[i] = 990; 58 vimani.one = i; 59 } 60 } 61 for(int i=vimani.two+1;i<vimani.y2ic;i++){ 62 if(vimani.y2[i] <640){ 63 g.fillRoundRect(255, vimani.y2[i], 30, 20, 5, 10); 64 vimani.y2[i]+=vimani.speed; 65 }else{ 66 if(vimani.playercombo > vimani.playerhighcombo){ 67 vimani.playerhighcombo = vimani.playercombo; 68 } 69 vimani.playercombo = 0; 70 vimani.y2[i] = 990; 71 vimani.two = i; 72 } 73 } 74 for(int i=vimani.three+1;i<vimani.y3ic;i++){ 75 if(vimani.y3[i] <640){ 76 g.fillRoundRect(290, vimani.y3[i], 30, 20, 5, 10); 77 vimani.y3[i]+=vimani.speed; 78 }else{ 79 if(vimani.playercombo > vimani.playerhighcombo){ 80 vimani.playerhighcombo = vimani.playercombo; 81 } 82 vimani.playercombo = 0; 83 vimani.y3[i] = 990; 84 vimani.three = i; 85 } 86 } 87 for(int i=vimani.four+1;i<vimani.y4ic;i++){ 88 if(vimani.y4[i] <640){ 89 g.fillRoundRect(325, vimani.y4[i], 30, 20, 5, 10); 90 vimani.y4[i]+=vimani.speed; 91 }else{ 92 if(vimani.playercombo > vimani.playerhighcombo){ 93 vimani.playerhighcombo = vimani.playercombo; 94 } 95 vimani.playercombo = 0; 96 vimani.y4[i] = 990; 97 vimani.four=i; 98 } 99 } 100 101 if(vimani.keyhitflg == true){ //判定があった時 102 try { 103 //URL url = this.getClass().getResource("./hantei/"+vimani.hantei+".png"); 104 Graphics2D g2d = (Graphics2D) g; 105 BufferedImage image = ImageIO.read(getClass().getResource("hantei/"+vimani.hantei+".png")); 106 107 g2d.drawImage(image,vimani.type-30,540,100,40,this); 108 109 } catch (IOException e) { 110 e.printStackTrace(); 111 } 112 vimani.mikucount++; 113 if(vimani.mikucount == 10){ 114 vimani.keyhitflg = false; 115 vimani.mikucount = 0; 116 } 117 } 118 if(vimani.keyhitflg2 == true){ //判定があった時 119 try { 120 Graphics2D g2e = (Graphics2D) g; 121 BufferedImage image2 = ImageIO.read(getClass().getResource("hantei/"+vimani.hantei+".png")); 122 123 g2e.drawImage(image2,vimani.type2-30,540,100,40,this); 124 125 } catch (IOException e) { 126 e.printStackTrace(); 127 } 128 vimani.mikucount2++; 129 if(vimani.mikucount2 == 10){ 130 vimani.keyhitflg2 = false; 131 vimani.mikucount2 = 0; 132 } 133 } 134 135 136 137 }

譜面の降ってくるレーンを表示し続け、その上に譜面データから読み込んだタイミングでノーツを4つのレーンに降らせ、キーが譜面にあったタイミングで押されたら、判定"good","great","pergect"等のpngの画像を押されたキーに対応したレーンに表示させています。
javaのGUIで音ゲー等の常に画面が更新されるものを作ろうとした際に、paintComponentで描画設定をして、repaint();すると良いよ、と見かけたことがあったのでそれを参考にしてプログラムしています。
知識不足、記述不足の質問失礼いたしました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/01/13 00:58

残念ながら、質問文からはPuhuさんのプログラムに起こっている問題が全く類推できません。唯一の具体的な情報"SwingにはPaintComponentがない"(つまりAWTにはある?)のPaintComponentすら何を指しているのかわかりません(AWTにはそのようなクラスは無い)。 この段階でアドバイスできるのは、http://www.oracle.com/technetwork/java/painting-140037.html (日本語訳: http://homepage1.nifty.com/algafield/paint.html )の"AWT Painting Guidelines"節などを読んでみてください、ということくらいでしょうか。
eripong

2016/01/13 03:21

抜粋でも良いので、具体的にコードを提示してください。また、「PaintComponentの中での処理が多い」のであれば、どの様な処理を書いているかも教えてください。その際、実在する、正確なクラス名を使用してください。yukihaneさんもコメントされているとおり、具体的な情報が少なすぎます。
Puhu

2016/01/13 10:36

>yukihane様 ありがとうございます、読んでみます! paintComponentはjava.awt.*;をimportすることで使えるものだとばかり思っていたのですが、知識不足で間違った発言をしてしまったのだと思います。すみません。 >eripong様 他のメソッド等で変数の値を変え、それをもとにループ回数や表示させる画像ファイルを変えたり、フラグが上がったり下りたりしていて、これだけでは分らないかもしれない、と思いましたがpaintComponent(Graphics g)内の処理を追記させていただきました、失礼いたしました。
guest

回答2

0

ベストアンサー

気付いた点と改善案を挙げます。
おそらく1.が期待通り動作しない原因なのではと思います。

1.画面の描画と状態の更新を同時に行っている。
状態の更新と画面の描画が混ざっているように見えるので、分けた方が良いと思います。
paintComponentの呼び出しは、明示的にrepaintした場合以外にも発生するので、
ここで状態を変更したりすると、意図しない形で状態が変わってしまうと思います。
状態変更の例は以下の様な箇所です。

lang

1vimani.y1[i]+=vimani.speed;
  • 状態の更新は、タイマーを使って定期的に行うものと、キー入力時に行うものがあると思いますが、
    定期的に行う方では最後にrepaintを呼ぶようにすべきと思います。
  • 画面の描画(paintComponent)では、状態を見て、描画を行うだけにするとよいかと思います。

2.画像ファイルの読み込みを描画の度に実施している。

lang

1ImageIO.read(getClass().getResource("hantei/"+vimani.hantei+".png"));

という処理がpaintComponent内に記述されていますが、
毎回読むと処理時間がかかるので、起動時にまとめて読み込んでおき、
paintComponentでは読み込んだ結果を描画するだけにすると
よいかと思います。

3.同じような記述が繰り返し書かれている。
メソッドに切り出す、別クラスにするなどして共通化した方が良いと思います。処理時間や動作には直接影響しないのですが、変更時には共通化されていた方が楽なためです。

投稿2016/01/13 12:20

eripong

総合スコア1546

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Puhu

2016/01/13 12:55

ご回答ありがとうございます! 確かにrepaint();が意図しない形で発生して、譜面の落下が高速になってしまったり等は十分に考えられます! 指摘いただいた箇所すべてを完璧に直すとまでは出来なくとも、改善してみようと思います! 非常にためになるご回答ありがとうございました!
guest

0

脊髄反射な回答で恐縮です。

「PaintComponentの中の処理が多くて、数m秒単位で再描画させるのが無理」なら、
PaintComponentの中の処理を減らすか、再描画の間隔を広げればいいんでは。

投稿2016/01/13 03:13

matobaa

総合スコア2493

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Puhu

2016/01/13 10:32

ご回答ありがとうございます! 私は今音楽ゲームを作成していまして、譜面を降らしたりする関係上 描画処理を減らすのも、感覚を広げるのもゲーム性を低下させてしまうと思うので厳しいと思います。 プログラミング初心者で、java、GUIの知識もあまりないままいきなり音楽ゲームを作成したため憶測だけで物を言っているところがあります。 単純に画像や図形の表示位置の変更、画面の更新だけならpaintComponentを使ってrepaint();させなくても出来る。 ということでしたら、私の知識不足です。すみません。
Puhu

2016/01/13 13:40

PaintComponentの処理を減らす、その意味が解りました;  不必要な処理を省くことに成功しました、ありがとうございます!
matobaa

2016/01/13 14:43

おお、いい方向に向かっているようで良かったです。頑張ってください!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問