今天闲的无聊,想写个五子棋的游戏,设想是用一个JPanel放置棋盘和棋子,把这个JPanel放置在一个JFrame中,但是发现每次在移动棋子的时候,棋盘也会跟着移动~~看了半天源代码,还是没看出问题~,各位帮帮忙把。- -!
源代码:MyPanel.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.Image;public class MyPanel extends JPanel
{
private final static int PANEL_SIZE=420;
private final static int ELEMENT_SIZE=28;
private final static int ROW_NUM=15;
private final static int COL_NUM=15;

private Image background;
private Image black;
private Image white;
private Image site;

private int alignment_x=0;
private int alignment_y=0;

private int state[][]=
{
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
},
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
},
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
},
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
},
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
},
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
},
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
},
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
},
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
},
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
},
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
},
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
},
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
},
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
},
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
},
};

public MyPanel()
{
this.setPreferredSize(new Dimension(420,420));
}

public void paint(Graphics g)
{
loadImage(g);
judgeState(g);
g.drawImage(site,this.getX()*MyPanel.ELEMENT_SIZE,this.getY()*MyPanel.ELEMENT_SIZE,22,22,this);
}

public void loadImage(Graphics g)
{
ImageIcon icon=new ImageIcon("resource\\background.jpg");
background=icon.getImage();

icon=new ImageIcon("resource\\black.png");
black=icon.getImage();

icon=new ImageIcon("resource\\white.png");
white=icon.getImage();

icon=new ImageIcon("resource\\site.jpg");
site=icon.getImage();

g.drawImage(background,0,0,420,420,this);
}

public void judgeState(Graphics g)
{
int i=0;
int j=0;
while(i<=14)
{
while(j<=14)
{
if(state[i][j]==1)
{
g.drawImage(black,i*MyPanel.ELEMENT_SIZE,j*MyPanel.ELEMENT_SIZE,22,22,this);
}
if(state[i][j]==2)
{
g.drawImage(white,i*MyPanel.ELEMENT_SIZE,j*MyPanel.ELEMENT_SIZE,22,22,this);
}
j++;
}
i++;
j=0;
}
}

public int getX()
{
return alignment_x;
}
public int getY()
{
return alignment_y;
}

public void setAlignment(int x,int y)
{
alignment_x=x;
alignment_y=y;
}

public int getState(int x,int y)
{
return state[x][y];
}

public void setState(int x,int y,int value)
{
state[x][y]=value;
}
}
Chess.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;public class Chess extends JFrame implements KeyListener
{
private MyPanel p=new MyPanel();

public Chess()
{
this.setLayout(new BorderLayout());
this.add(p,BorderLayout.CENTER);
this.setTitle("五子棋");
this.addKeyListener(this);
this.pack();
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public static void main(String args[])
{
new Chess();
}

public void keyTyped(KeyEvent e)
{
}
public void keyPressed(KeyEvent e)
{
switch(e.getKeyCode())
{
case 38:
if(p.getY()>0)
{
p.setAlignment(p.getX(),(p.getY()-1));
     p.repaint();
}
break;

case 40:
if(p.getY()<14)
{
p.setAlignment(p.getX(),(p.getY()+1));
p.repaint();
}
break;

case 39:
if(p.getX()<14)
{
p.setAlignment((p.getX()+1),p.getY());
p.repaint();
}
break;

case 37:
if(p.getX()>0)
{
p.setAlignment((p.getX()-1),p.getY());
p.repaint();
}
break;

case 10:
if((p.getState(p.getX(),p.getY())==1)||(p.getState(p.getX(),p.getY())==2))
{
;
}
else
{
p.setState(p.getX(),p.getY(),1);
p.repaint();
if(win())
{
JOptionPane.showMessageDialog(this,"胜利","赢了",JOptionPane.INFORMATION_MESSAGE,null);
initState();
}
else
{
pcGo();
}
}
break;
}
}
public void keyReleased(KeyEvent e)
{
}

public void pcGo()
{
int i,j;
i=(int)(Math.random()*14);
j=(int)(Math.random()*14);
while(p.getState(i,j)!=0)
{
i=(int)(Math.random()*14);
    j=(int)(Math.random()*14);
}
p.setState(i,j,2);
p.repaint();
if(win())
{
JOptionPane.showMessageDialog(this,"输了","输了",JOptionPane.INFORMATION_MESSAGE,null);
initState();
}

}

public boolean win()
{
return false;
}

public void initState()
{
int i=0;
int j=0;
while(i<=14)
{
while(j<=14)
{
p.setState(i,j,0);
j++;
}
i++;
j=0;
}
}
}

解决方案 »

  1.   

    代码在我这的测试结果是,只要窗口大小不发生改变,棋盘就不会动.如果窗口大小发生改变的话,棋盘会偏移,偏移量和你按方向键的次数有关。而再下一个棋子的话,棋盘又会回到初始位置。窗口大小发生改变是系统调用repaint(),系统repaint的话棋盘会偏移下棋子的话是手动reppaint(),棋盘回到初始位置。。,我也不知道这两者有什么区别....晚上回来再研究一下。是在不行LZ把窗口设置成不能改变大小的。。
      

  2.   

    在自己机器上实验是:不管窗口大小是不是改变大小,只要摁了方向键,棋盘就会跟着移动~~~,在别人的机器上也还是一样~~……,而且好像是以前的图像在JPanel上还有残留一样,不是每次调用paint的时候,都会清除以前的图像吗 ?
      

  3.   

    经过不断的添删改查终于找到原因。原来是LZ,MyPanel类中的getX(),与getY()与Component类的重名了,把两个java文件中的所有这两个方法改个名字棋盘就不会移动了。具体内部原因我也不太清楚.
      

  4.   

    查了半天也没查出getX()这个方法的问题。这个方法会导致panel的坐标变化?可是看了源代码,没发现什么问题。
    使用JComponent这些swing插件的时候
    一般都重写这个方法,这样就能保证擦除背景  
     @Override
    protected void paintComponent(Graphics g)
    {
    // TODO Auto-generated method stub
    super.paintComponent(g);
    }
      

  5.   

    感谢Apeipo同学~~这么仔细得帮忙差错~。谢谢了。。
    竟然是重写了其他类的方法