1

ボードゲームで奇妙なエラーが発生しています。ボードは、JPanelのサブクラスであるGameTilesを備えた2D配列で構成されています。サイズ(600,500)を使用すると、すべて問題なく動作しますが、サイズを変更すると、左上隅に奇妙なエラーが表示されます。

エラーの画像(左上隅を参照) ボードエラー

さらに奇妙なのは、新しいプロジェクトを作成したときに、試してみるだけで完璧に機能したことです。絵のコードはまったく同じで、エラーは発生していません。この問題を引き起こしているのは他の何かでしょうか?

問題が修正されました

Anser:JPanelのgetXメソッドとgetYメソッドを誤ってオーバーライドしました。名前を変更したところ、完全に機能するようになりました。

Reversi.java

package org.reversi;

import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import org.reversi.gui.GameFrame;

public class Reversi {
public static void main(String[] args) {
    try {
                 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (UnsupportedLookAndFeelException e) {
        e.printStackTrace();
    }

    java.awt.EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            GameFrame frame = new GameFrame("Reversi");
            frame.setSize(600,500);
            frame.setLocationRelativeTo(null);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }
    });
}
}

GameBoard.java

package org.reversi.gui;

import java.awt.Graphics;
import java.awt.GridLayout;

import javax.swing.JPanel;

public class GameBoard extends JPanel{
private GameTile[][] gameBoard = new GameTile[8][8];

public GameBoard() {
    initiateLayout();
}

private void initiateLayout() {
    setLayout(new GridLayout(8, 8));

    for(int row = 0 ; row < 8 ; row++) {
        for(int col = 0 ; col < 8 ; col++) {
            gameBoard[row][col] = new GameTile(col,row);
            add(gameBoard[row][col]);
        }
    }
}

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    for(int row = 0 ; row < 8 ; row++) 
        for(int col = 0 ; col < 8 ; col++)              
            gameBoard[row][col].repaint();
}
}

GameFrame.java

package org.reversi.gui;

import javax.swing.JFrame;

public class GameFrame extends JFrame {
private GameBoard gameBoard;

/**
 * Creates a new frame.
 * @param gameTitle the title of the frame
 */
public GameFrame(String gameTitle) {
    setTitle(gameTitle);
    gameBoard = new GameBoard();
    add(gameBoard);
}
}

GameTile.java

package org.reversi.gui;

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 GameTile extends JPanel {
private BufferedImage image;
private int x;
private int y;

public GameTile(int x, int y) {
    this.x = x;
    this.y = y;
    try {
        this.image = ImageIO.read(new File("tile.png"));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
}

public int getX() {
    return x;
}

public int getY() {
    return y;
}
}

画像へのリンク(tile.pngという名前にする必要があります):http://i.imgur.com/ejmCtui.png

4

1 に答える 1

3

あなたのコメントによると:

これは問題でした、それを指摘してくれてありがとう。ボード上で移動するときに座標を使用しています。これを答えにする方法があれば、それは素晴らしいことです

あなたがやったGameTile.java

public int getX() {
    return x;
}

public int getY() {
    return y;
}

これにより、実際には をオーバーライドし、 に影響JPanelする座標を返します。これは、注釈を追加することで確認できます(注意: コンパイラ エラーはスローされないため、拡張クラスのメソッドを正しくオーバーライドしています)。getXgetYLayout@Override

@Override
public int getX() {
    return x;
}

@Override
public int getY() {
    return y;
}

@Xeonが言ったように、座標を設定するべきではありませんLayoutManager

解決策:(プラス追加)

  • これらのゲッターを削除するか、適切に名前を変更してください。

  • Graphic Dimension pack() JFrame`setSizeを可視に設定する前に、ただしコンポーネントを追加した後JFrameでオーバーライドgetPreferredSizeを呼び出さないでください。JPanel which is drawn to vias object and return the corrects (in your case the image dimensions) and than call [][4] on

  • setLocationRelativeTo(...)への呼び出しを afterに再配置する必要がありますpack()

  • GUI の終了後もメソッドの実行を続行できるJFrame.DISPOSE_ON_CLOSEように使用することをお勧めします。main(String[] args)

  • また、不必要に延長しJFrameないでください。

  • GameTileクラスで同じ画像を繰り返しロードするのではなく、画像を一度ロードしGameTileて受け入れるためのパラメーターを追加しますBufferedImage(インターネットURLを使用してテストしているときに、作成されるたびに新しい画像を読み取るため、これを理解しましたGameTile

必要な変更が加えられたクラスは次のとおりです。

リバーシ.java:

public class Reversi {

    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }

        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new GameFrame("Reversi");
            }
        });
    }
}

GameBoard.java :

public class GameBoard extends JPanel {

    private GameTile[][] gameBoard = new GameTile[8][8];

    public GameBoard() {
        initiateLayout();
    }

    private void initiateLayout() {
        setLayout(new GridLayout(8, 8));

        BufferedImage image = null;
        try {
            image = ImageIO.read(new URL("http://i.imgur.com/ejmCtui.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        for (int row = 0; row < 8; row++) {
            for (int col = 0; col < 8; col++) {
                gameBoard[row][col] = new GameTile(image, col, row);
                add(gameBoard[row][col]);
            }
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (int row = 0; row < 8; row++) {
            for (int col = 0; col < 8; col++) {
                gameBoard[row][col].repaint();
            }
        }
    }
}

ゲームタイル.java:

public class GameTile extends JPanel {

    private BufferedImage image;
    private int x;
    private int y;

    public GameTile(BufferedImage image, int x, int y) {
        this.image = image;
        this.x = x;
        this.y = y;
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(image.getWidth(), image.getHeight());
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
    }
}

GameFrame.java:

public class GameFrame {

   private GameBoard gameBoard;

    /**
     * Creates a new frame.
     *
     * @param gameTitle the title of the frame
     */
    public GameFrame(String gameTitle) {
        JFrame frame = new JFrame(gameTitle);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        gameBoard = new GameBoard();
        frame.add(gameBoard);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

これは以下を生成します:

ここに画像の説明を入力

于 2013-01-31T19:58:01.053 に答える