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

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

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

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

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

Q&A

解決済

1回答

1940閲覧

java repaintで描画位置がずれてしまう

h.yano1120

総合スコア9

Java

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

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

1グッド

0クリップ

投稿2020/08/20 11:42

前提・実現したいこと

javaのGUIでチェスを作成しています。

発生している問題

マウスクリック後にrepaintで再描画すると、チェスの盤面の位置がずれてしまいます。
イメージ説明

該当のソースコード

java

1import javax.swing.*; 2 3import java.io.*; 4import javax.imageio.*; 5import java.awt.*; 6import java.awt.event.*; 7 8 9public class Board extends JPanel { 10 11 static final int s = 50; // マスのサイズ(固定) 12 static final int WIDTH = 800; // 画面サイズ(幅) 13 static final int HEIGHT = 850; // 画面サイズ(高さ) 14 final int PAWN = 1; //プレイヤー1のポーン(1 or 2) 15 Image img[] = new Image[12]; // 画像オブジェクト 16 17 int mx; // マウスがクリックされた位置(x 座標) 18 int my; // マウスがクリックされた位置(y 座標) 19 int status = 0; 20 // 盤面 21 int ban[][] = new int[8][8]; 22 23 Board() { 24 setPreferredSize(new Dimension(WIDTH,HEIGHT)); 25 addMouseListener(new MouseProc()); 26 } 27 28 public void paintComponent(Graphics g) { 29 try { 30 img[0] = ImageIO.read(new File("ポーン.jpg")); 31 img[1] = ImageIO.read(new File("ルーク.jpg")); 32 img[2] = ImageIO.read(new File("ビショップ.jpg")); 33 img[3] = ImageIO.read(new File("ナイト.jpg")); 34 img[4] = ImageIO.read(new File("キング.jpg")); 35 img[5] = ImageIO.read(new File("クイーン.jpg")); 36 img[6] = ImageIO.read(new File("ポーン2.jpg")); 37 img[7] = ImageIO.read(new File("ルーク2.jpg")); 38 img[8] = ImageIO.read(new File("ビショップ2.jpg")); 39 img[9] = ImageIO.read(new File("ナイト2.jpg")); 40 img[10] = ImageIO.read(new File("キング2.jpg")); 41 img[11] = ImageIO.read(new File("クイーン2.jpg")); 42 43 g.drawRect(50, 100, 500, 550); 44 g.setColor(Color.white); 45 g.fillRect(100, 150, 400, 450); 46 g.setColor(Color.black); 47 g.drawRect(100, 150, 400, 450); 48 for(int i=0; i<8; i++) { 49 g.drawLine(100, 200+s*i, 500, 200+s*i); 50 g.drawLine(150+s*i, 150, 150+s*i, 600); 51 } 52 // ポーンの配置 53 for(int i=0; i<8; i++) { 54 g.drawImage(img[6], 110+s*i, 205, 30, 40, null); 55 g.drawImage(img[0], 110+s*i, 505, 30, 40, null); 56 } 57 // ルークの配置 58 g.drawImage(img[7], 110, 155, 30, 40, null); 59 g.drawImage(img[7], 110+s*7, 155, 30, 40, null); 60 g.drawImage(img[1], 110, 555, 30, 40, null); 61 g.drawImage(img[1], 110+s*7, 555, 30, 40, null); 62 // ナイトの配置 63 g.drawImage(img[9], 110+s, 155, 30, 40, null); 64 g.drawImage(img[9], 110+s*6, 155, 30, 40, null); 65 g.drawImage(img[3], 110+s, 555, 30, 40, null); 66 g.drawImage(img[3], 110+s*6, 555, 30, 40, null); 67 // ビショップの配置 68 g.drawImage(img[8], 110+s*2, 155, 30, 40, null); 69 g.drawImage(img[8], 110+s*5, 155, 30, 40, null); 70 g.drawImage(img[2], 110+s*2, 555, 30, 40, null); 71 g.drawImage(img[2], 110+s*5, 555, 30, 40, null); 72 // キングの配置 73 g.drawImage(img[10], 110+s*4, 155, 30, 40, null); 74 g.drawImage(img[4], 110+s*4, 555, 30, 40, null); 75 // クイーンの配置 76 g.drawImage(img[11], 110+s*3, 155, 30, 40, null); 77 g.drawImage(img[5], 110+s*3, 555, 30, 40, null); 78 79 if(status == 1) { 80 g.setColor(Color.PINK); 81 g.drawRect(100, 150, 50, 50); 82 } 83 84 } catch (IOException e) { 85 // TODO 自動生成された catch ブロック 86 e.printStackTrace(); 87 } 88 } 89 // クリックされた時の処理用のクラス 90 class MouseProc extends MouseAdapter{ 91 public void mouseClicked(MouseEvent e) { 92 // 位置を取得 93 mx = e.getX(); 94 my = e.getY(); 95 // 盤面の内部かどうか判定 96 if(mx > 100 && mx < 500 && my >150 && my < 600) { 97 status = 1; 98 } 99 // 再描画要求 100 repaint(); 101 } 102 103 } 104 105 public static void main(String[] args) { 106 JFrame f = new JFrame(); 107 f.getContentPane().setLayout(new FlowLayout()); 108 f.getContentPane().add(new Board()); 109 f.pack(); 110 f.setResizable(false); 111 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 112 f.setVisible(true); 113 } 114 115}

試したこと

Googleにて同様の問題がないか探してみたのですが見つかりませんでした。

補足情報(FW/ツールのバージョンなど)

EclipseのPhoton ver4.8.0を使用しています。

TN8001👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

paintComponentメソッド頭でsuperを呼んでください。

Java

1@Override 2public void paintComponent(Graphics g) { 3 super.paintComponent(g); 4 5// 以下省略 6 7}

理屈
JPanel#paintComponent(Graphics g)backgroundカラーで塗りつぶすのが規定動作です。
それを飛ばすと前回の描画が残ることになります。
残ったとしても同じ位置に描くのだから問題ないはずですが、レイアウトの最中に?何度か呼ばれることがあるようです(このあたり詳細わかりません)
System.out.println("paintComponent");等を入れるとわかります。

手元では起動するだけで2回呼ばれました。
その際JPanel自体の位置が、微妙に違ってしまっているということだと思います。

起動時に2重になっていないので、ちょっと違うかな?^^;
setBounds(0,0,600,600);等と、0,0起点にするとずれないのでレイアウト関連ではあると思います。

投稿2020/08/20 13:15

編集2020/08/20 13:34
TN8001

総合スコア9862

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

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

h.yano1120

2020/08/20 14:12

ありがとうございます、解決いたしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問