第一次发帖,小弟请教高手们
我做了一个用swing写的井字棋游戏
基本功能是实现了,但现在有个问题一直没解决,
在游戏运行的时候窗口经常会一片空白,什么都没有,只有多运行几次或者改变下窗口的大小后才会出来,原因未知
在游戏正常运行是,窗口最大化再恢复窗口后里面的内容还是能保留的,但我一旦点击鼠标开始点游戏里的格子后,再进行窗口最大化再恢复窗口后,里面的图像全部消失
请问这是为什么呀?
照理说我把绘画方法都写在paint方法里了,该弄repaint的地方也弄了,可结果还是这样子源代码如下:import java.awt.*;
import java.awt.event.*;
import javax.swing.*;/**
 * @备注 paint方法不能继承自JFrame类,而必须继承自JPanel类
 * 因为JPanel继承自Component类,paint方法调用时会同时调用paintComponent方法,其作用是不停地进行重绘
 * 如果在JFrame调用paint方法的话会出现窗口覆盖上去时会被擦除的问题
 */
public class Main extends JFrame{
private static final long serialVersionUID = 1L;

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

public Main(){
this.setTitle("井字棋");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(500, 500);
int width=Toolkit.getDefaultToolkit().getScreenSize().width;
int height=Toolkit.getDefaultToolkit().getScreenSize().height;
this.setLocation((width-500)/2, (height-500)/2);
// this.setResizable(false);
this.setVisible(true);

Container contentPane=getContentPane();
        contentPane.add(new Game());
}
}class Game extends JPanel {
private static final long serialVersionUID = 2L;

int x = 0, y = 0;
int a = 0;
int x1 = 0, y1 = 0, x2 = 0, y2 = 0, x3 = 0, y3 = 0, x4 = 0, y4 = 0;
boolean fa = true, huatu = true, yin = true;
int a1 = 0, a2 = 0, a3 = 0, a4 = 0, a5 = 0, a6 = 0, a7 = 0, a8 = 0, a9 = 0;
int s[] = new int[10], jj[] = new int[10];
JButton hongdui, landui;
JLabel jl;
JPanel jp1;
JToolBar bar;

public Game() {
hongdui = new JButton("红队先下");
hongdui.setMargin(new Insets(0,0,0,0));
hongdui.setFont(new Font("宋体",Font.PLAIN,16));
landui = new JButton("蓝队先下");
landui.setMargin(new Insets(0,0,0,0));
landui.setFont(new Font("宋体",Font.PLAIN,16));
jp1=new JPanel();
this.setLayout(new BorderLayout());
jp1.add(hongdui);
jp1.add(landui);
this.add(jp1,BorderLayout.NORTH);
bar=new JToolBar();
bar.setFloatable(false);
jl = new JLabel("欢迎进入井字棋游戏!");
jl.setFont(new Font("楷体_GB2312",Font.PLAIN,16));
bar.add(jl);
this.add(bar,BorderLayout.SOUTH);

addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent event) {
x = event.getPoint().x;
y = event.getPoint().y;
int a = play(x, y);
if (yin) {
jl.setForeground(Color.RED);
jl.setText("游戏开始前,请选择谁先下");
}
else {
if (a == 0 || s[a] == 1) {
jl.setForeground(Color.RED);
jl.setText("位置错误,请另选位置下棋");
}
else {
fa = false;
if (a == 1)
a1 = 1;
if (a == 2)
a2 = 1;
if (a == 3)
a3 = 1;
if (a == 4)
a4 = 1;
if (a == 5)
a5 = 1;
if (a == 6)
a6 = 1;
if (a == 7)
a7 = 1;
if (a == 8)
a8 = 1;
if (a == 9)
a9 = 1;
repaint();
}
}
}
}); hongdui.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
for (int i = 0; i < s.length; i++) {
s[i] = 0;
jj[i] = 0;
}
fa = true;
repaint();
yin = false;
huatu = true;
jl.setForeground(Color.black);
jl.setText("红队先下");
}
}); landui.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
for (int i = 0; i < s.length; i++) {
s[i] = 0;
jj[i] = 0;
}
fa = true;
repaint();
yin = false;
huatu = false;
jl.setForeground(Color.black);
jl.setText("蓝队先下");
}
});
} public void paint(Graphics g) {
if (fa) {
super.paint(g);
int x = 100, y = 100, c = 300, k = 300;
for (int i = 0; i < 300; i += 100)
g.drawRect(x, y + i, c, k - i);
for (int i = 0; i < 300; i += 100)
g.drawRect(x + i, y, c - i, k);
}
else {
jl.setForeground(Color.black);
if (huatu) {
g.setColor(Color.red);
if (a1 == 1) {
g.drawLine(120, 120, 180, 180);
g.drawLine(180, 120, 120, 180);
a1 = 0;
jj[1] = 1;
s[1] = 1;
}
if (a2 == 1) {
g.drawLine(220, 120, 280, 180);
g.drawLine(280, 120, 220, 180);
a2 = 0;
jj[2] = 1;
s[2] = 1;
} if (a3 == 1) {
g.drawLine(320, 120, 380, 180);
g.drawLine(380, 120, 320, 180);
a3 = 0;
jj[3] = 1;
s[3] = 1;
}
if (a4 == 1) {
g.drawLine(120, 220, 180, 280);
g.drawLine(180, 220, 120, 280);
a4 = 0;
jj[4] = 1;
s[4] = 1;
}
if (a5 == 1) {
g.drawLine(220, 220, 280, 280);
g.drawLine(280, 220, 220, 280);
a5 = 0;
jj[5] = 1;
s[5] = 1;
}
if (a6 == 1) {
g.drawLine(320, 220, 380, 280);
g.drawLine(380, 220, 320, 280);
a6 = 0;
jj[6] = 1;
s[6] = 1;
}
if (a7 == 1) {
g.drawLine(120, 320, 180, 380);
g.drawLine(180, 320, 120, 380);
a7 = 0;
jj[7] = 1;
s[7] = 1;
}
if (a8 == 1) {
g.drawLine(220, 320, 280, 380);
g.drawLine(280, 320, 220, 380);
a8 = 0;
jj[8] = 1;
s[8] = 1;
}
if (a9 == 1) {
g.drawLine(320, 320, 380, 380);
g.drawLine(380, 320, 320, 380);
a9 = 0;
jj[9] = 1;
s[9] = 1;
}
huatu = false;
jl.setText("蓝队下棋");
}
else {
g.setColor(Color.blue);
if (a1 == 1) {
g.drawOval(125, 125, 50, 50);
a1 = 0;
jj[1] = 2;
s[1] = 1;
}
if (a2 == 1) {
g.drawOval(225, 125, 50, 50);
a2 = 0;
jj[2] = 2;
s[2] = 1;
}
if (a3 == 1) {
g.drawOval(325, 125, 50, 50);
a3 = 0;
jj[3] = 2;
s[3] = 1;
}
if (a4 == 1) {
g.drawOval(125, 225, 50, 50);
a4 = 0;
jj[4] = 2;
s[4] = 1;
}
if (a5 == 1) {
g.drawOval(225, 225, 50, 50);
a5 = 0;
jj[5] = 2;
s[5] = 1;
}
if (a6 == 1) {
g.drawOval(325, 225, 50, 50);
a6 = 0;
jj[6] = 2;
s[6] = 1;
}
if (a7 == 1) {
g.drawOval(125, 325, 50, 50);
a7 = 0;
jj[7] = 2;
s[7] = 1;
}
if (a8 == 1) {
g.drawOval(225, 325, 50, 50);
a8 = 0;
jj[8] = 2;
s[8] = 1;
}
if (a9 == 1) {
g.drawOval(325, 325, 50, 50);
a9 = 0;
jj[9] = 2;
s[9] = 1;
}
huatu = true;
jl.setText("红队下棋");
}
message();
}
} public int play(int x, int y) {
if (x >= 100 && x < 200 && y >= 100 && y < 200)
a = 1;
else if (x >= 200 && x < 300 && y >= 100 && y < 200)
a = 2;
else if (x >= 300 && x < 400 && y >= 100 && y < 200)
a = 3;
else if (x >= 100 && x < 200 && y >= 200 && y < 300)
a = 4;
else if (x >= 200 && x < 300 && y >= 200 && y < 300)
a = 5;
else if (x >= 300 && x < 400 && y >= 200 && y < 300)
a = 6;
else if (x >= 100 && x < 200 && y >= 300 && y < 400)
a = 7;
else if (x >= 200 && x < 300 && y >= 300 && y < 400)
a = 8;
else if (x >= 300 && x < 400 && y >= 300 && y < 400)
a = 9;
else
a = 0;
return a;
} public void message() {
if (jj[1] == 1 && jj[2] == 1 && jj[3] == 1) {
jl.setForeground(Color.RED);
jl.setText("红方获胜,连接线1,2,3");
yin = true;
return;
}
if (jj[4] == 1 && jj[5] == 1 && jj[6] == 1) {
jl.setForeground(Color.RED);
jl.setText("红方获胜,连接线4,5,6");
yin = true;
return;
}
if (jj[7] == 1 && jj[8] == 1 && jj[9] == 1) {
jl.setForeground(Color.RED);
jl.setText("红方获胜,连接线7,8,9");
yin = true;
return;
}
if (jj[1] == 1 && jj[5] == 1 && jj[9] == 1) {
jl.setForeground(Color.RED);
jl.setText("红方获获胜,连接线1,5,9");
yin = true;
return;
}
if (jj[3] == 1 && jj[5] == 1 && jj[7] == 1) {
jl.setForeground(Color.RED);
jl.setText("红方获胜,连接线3,5,7");
yin = true;
return;
}
if (jj[1] == 1 && jj[4] == 1 && jj[7] == 1) {
jl.setForeground(Color.RED);
jl.setText("红方获胜,连接线1,4,7");
yin = true;
return;
}
if (jj[2] == 1 && jj[5] == 1 && jj[8] == 1) {
jl.setForeground(Color.RED);
jl.setText("红方获胜,连接线2,5,8");
yin = true;
return;
}
if (jj[3] == 1 && jj[6] == 1 && jj[9] == 1) {
jl.setForeground(Color.RED);
jl.setText("红方获胜,连接线3,6,9");
yin = true;
return;
} if (jj[1] == 2 && jj[2] == 2 && jj[3] == 2) {
jl.setForeground(Color.RED);
jl.setText("蓝方获胜,连接线1,2,3");
yin = true;
return;
}
if (jj[4] == 2 && jj[5] == 2 && jj[6] == 2) {
jl.setForeground(Color.RED);
jl.setText("蓝方获胜,连接线4,5,6");
yin = true;
return;
}
if (jj[7] == 2 && jj[8] == 2 && jj[9] == 2) {
jl.setForeground(Color.RED);
jl.setText("蓝方获胜,连接线7,8,9");
yin = true;
return;
}
if (jj[1] == 2 && jj[5] == 2 && jj[9] == 2) {
jl.setForeground(Color.RED);
jl.setText("蓝方获胜,连接线1,5,9");
yin = true;
return;
}
if (jj[3] == 2 && jj[5] == 2 && jj[7] == 2) {
jl.setForeground(Color.RED);
jl.setText("蓝方获胜,连接线3,5,7");
yin = true;
return;
}
if (jj[1] == 2 && jj[4] == 2 && jj[7] == 2) {
jl.setForeground(Color.RED);
jl.setText("蓝方获胜,连接线1,4,7");
yin = true;
return;
}
if (jj[2] == 2 && jj[5] == 2 && jj[8] == 2) {
jl.setForeground(Color.RED);
jl.setText("蓝方获胜,连接线2,5,8");
yin = true;
return;
}
if (jj[3] == 2 && jj[6] == 2 && jj[9] == 2) {
jl.setForeground(Color.RED);
jl.setText("蓝方获胜,连接线3,6,9");
yin = true;
return;
}
if (s[1] == 1 && s[2] == 1 && s[3] == 1 && s[4] == 1 && s[5] == 1 && s[6] == 1 && s[7] == 1 && s[8] == 1 && s[9] == 1) {
jl.setForeground(Color.RED);
jl.setText("双方都没获胜,游戏结束");
yin = true;
return;
}
}
}

解决方案 »

  1.   

    main方法中将
            this.setVisible(true);
    放到最后,也就是 contentPane.add(new Game());后面。
      

  2.   

    第二个问题,每次进行最小化等操作时,都会调用repaint方法,该方法调用update方法,update方法又调用paint方法,所以把你程序中的数据,保存起来,重写paint方法, 在该方法中去画。这样就OK了!
      

  3.   

    paint里面的逻辑有问题。
    记住paint必须(要假设为)是全部擦掉重绘,不是补绘。所有那么多if/else和状态切换是没有必要的。
    比方说,           super.paint(g);
                int x = 100, y = 100, c = 300, k = 300;
                for (int i = 0; i < 300; i += 100)
                    g.drawRect(x, y + i, c, k - i);
                for (int i = 0; i < 300; i += 100)
                    g.drawRect(x + i, y, c - i, k);这一段是画格子的,根本不能放if里面,放外面,只要paint方法调用,都重新画格子。paint方法中其他类似问题请一一调整。
      

  4.   

    用huatu变量记忆是红队还是蓝队不能奏效。因为并不是你调repaint的时候paint才会被调用,你没调repaint的时候paint也可能会被调用,paint何时被调用是不可控的。用值去记忆可以的,如0表示空格子、1表示蓝子、2表示红子。改动会比较多。
      

  5.   

    明白了,看来原因是对paint的工作原理没搞清楚
      

  6.   

    对  paint的运行和调用世间搞明白  就行了