私はベアボーンGUI以外のプログラムを書いたことがないので、私はチェスアプリケーションを書くための個人的なプロジェクトに着手しました。JButtonのpaintComponent()をオーバーライドすると予期しない結果が発生する
このプロジェクトの私の目標の1つは、ボードをウィンドウに合わせてリサイズすることでしたが、これはあまり問題なく処理できました。しかし、このプロセスでは、私の作品(JButtons上のアイコンとして表されていた)がボードの残りの部分で再スケールされなかったという問題が発生しました。
代わりにImageクラスで表現することにし、paintComponentをオーバーロードするScalingJButtonというカスタムクラスを作成しました。これは実際にはかなりうまくいった... the last piece to be drawn。残りの部分は描画されず、結果としてプログラムが壊れてしまいます。
public class ScalingJButton extends JButton{
private Image image;
ScalingJButton(){
this.image = null;
}
ScalingJButton (Image image){
this.image = image;
}
public void setImage(Image image){
this.image = image;
}
public Image getImage(){
return image;
}
@Override
public void paintComponent(Graphics g){
//super.paintComponent(g);
int x = getX();
int y = getY();
int width = getWidth();
int height = getHeight();
if (image != null) {
g.drawImage(image, x, y, width, height, this);
}
}}
また、ここではScalingJButtonsをインスタンス化するための責任のコードは(VisualBoardはJPanelのを拡張するクラスであり、これはコンストラクタである)である。ここに私のScalingJButtonクラスです。レイアウトは、関連するかもしれないので
public VisualBoard(){
white = Color.WHITE;
black = Color.GRAY;
loadPieceImages();
setLayout(new GridLayout(8, 8));
for (int i = 0; i < 8; i++){
for (int j = 0; j < 8; j++){
squares[i][j] = new ScalingJButton();
if ((i + j) % 2 != 0) {
squares[i][j].setBackground(white);
}
else{
squares[i][j].setBackground(black);
}
add(squares[i][j]);
}
}
initializeStandardBoard();
}
は最後に、ここではボードのオートスケールを行うコードは次のとおりです。
public class Chess {
public static void main (String[] args){
final VisualBoard board = new VisualBoard();
final JPanel container = new JPanel(new GridBagLayout());
container.add(board);
container.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
drawResizedBoard(board, container);
}
});
JFrame frame = new JFrame("Chess");
frame.setSize(1000,1000);
frame.add(container);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static void drawResizedBoard(JPanel innerPanel, JPanel container) {
int w = (int)Math.round(container.getWidth()*0.9);
int h = (int)Math.round(container.getHeight()*0.9);
int size = Math.min(w, h);
innerPanel.setPreferredSize(new Dimension(size, size));
container.revalidate();
}}
私は大規模なデバッグを行っているが、それのほとんどはどこにもつながりません。注目すべきは、drawImageが呼び出されたときに、ScalingJButtonの "image"変数が正しい画像を保持していることです。別の興味深い点は、その中にあるピースの四角形が描かれる最後の四角形であり、どのような順番でボードに四角形を追加するかによって、異なるピースが描画されることです(ピースの読み込みに問題はありません)。
奇妙なことに、私がpaintComponentのsuperを使わないと、描画された部分の上にマウスを置くと、マウスの上にマウスを置くと、他の四角がその部分で塗りつぶされます。
私は完全に迷っていて、何をすべきかわからないので、どんな助けでも大歓迎です!
ありがとうございました!私はすでにStretchIconを使用することに自信していましたが(確かに悪い考えではありません)、あなたの投稿を読んだ後、私は自分のカスタムクラスに戻り、それがうまくいくことを発見しました。私は、g.drawImage()が右上隅を基準にしてScalingJButtonの位置から描画すると仮定しましたが、実際にはScalingJButton自体を基準に描画していました。そのような愚かな誤解の上で悲しんでいるすべてのこと! – TheRussianPatzer