繁体   English   中英

Java中的repaint()方法问题

[英]Problems with repaint() method in java

我是Java的新手,正在尝试使用Swing制作一个简单的Player vs. Computer“井字游戏”游戏。 在代码中,我使用paintComponent()方法绘制某些组件,并在播放器或计算机播放后调用repaint()方法。 问题是,游戏在我单击鼠标第三次(有时是第二次)后冻结。 GameWindow class我创建Map类的实例。

public class GameWindow extends JFrame{

    private final int sizeX = 3;
    private final int sizeY = 3;

    public GameWindow(){

        setLocation(400,150);
        setSize(406, 452);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setResizable(false);

        Map map = new Map(sizeX, sizeY);
        add(map, BorderLayout.CENTER);
        JPanel bottomPanel = new JPanel();
        bottomPanel.setLayout(new GridLayout(1, 2));
        add(bottomPanel, BorderLayout.SOUTH);

        Button newGame = new Button("Новая игра");
        newGame.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Начинаем новую игру");
            }
        });
        Button exit = new Button("Выход");
        exit.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });

        bottomPanel.add(newGame);
        bottomPanel.add(exit);

        setVisible(true);
    }
}

这是Map类中鼠标单击的侦听器:

public class Map extends JPanel {

private final int sizeX;
private final int sizeY;
private int cellWidth;
private int cellHeight;
private int cellX = -1;
private int cellY = -1;
private String lastPlayer = "nobody";

private String[][] table = new String[3][3];

public Map(int sizeX, int sizeY) {

    this.sizeX = sizeX;
    this.sizeY = sizeY;
    setBackground(Color.WHITE);

    for (int i = 0; i < table.length; i++) {

        for (int j = 0; j < table.length; j++) {

            table[i][j] = "empty";
        }
    }

    addMouseListener(new MouseAdapter() {
        @Override
        public void mouseReleased(MouseEvent e) {
            super.mouseReleased(e);

            cellX = e.getX() / cellWidth;
            cellY = e.getY() / cellHeight;

            if (!winOrDraw()) {
                boolean playerProgress = playerProgress();
                if(playerProgress) {
                    botProgress();
                }
            }
        }
    });
}

playerProgress()botProgress()方法中,我都调用repaint()方法来向屏幕添加新组件。 我真的无法确定这段代码中的问题是什么,为什么程序实际上在第6次调用repaint()方法后冻结了?

这是winOrDraw(),playerProgress()和botProgress()方法:

 private boolean winOrDraw(){

    for (int i = 0; i < table.length; i++) {

        if(table[i][0] == table[i][1] && table[i][1] == table[i][2] && !table[i][0].equals("empty")) return true;
        else if(table[0][i] == table[1][i] && table[1][i] == table[2][i] && !table[0][i].equals("empty")) return true;
        else if(table[0][0] == table[1][1] && table[1][1] == table[2][2] && !table[0][0].equals("empty")) return true;
        else if(table[2][0] == table[1][1] && table[1][1] == table[0][2] && !table[2][0].equals("empty")) return true;
    }

    int i, j = 0;
    for (i = 0; i < table.length; i++) {

        for (j = 0; j < table.length; j++) {

            if(table[i][j].equals("empty")) break;
        }
    }
    if(i == table.length && j == table.length) { lastPlayer = "nobody"; return true; }
    else return false;
}

private boolean playerProgress(){

    if(!table[cellY][cellX].equals("empty")){
        System.out.println("This cell is not empty");
        return false;
    } else {
        lastPlayer = table[cellY][cellX] = "player";
        repaint();
        return true;
    }
}

private void botProgress(){

    do{
        if(winOrDraw()){

            switch (lastPlayer) {
                case "player":

                    System.out.println("You won!");
                    System.exit(0);
                case "bot":

                    System.out.println("Bot won");
                    System.exit(0);
                default:

                    System.out.println("Draw");
                    System.exit(0);
            }
        }
        Random random = new Random();
        cellX = random.nextInt(2);
        cellY = random.nextInt(2);

        if(table[cellY][cellX].equals("empty")) {

            lastPlayer = table[cellY][cellX] = "bot";
            break;
        }
    }while (!table[cellY][cellX].equals("empty"));

    System.out.println("Bot's turn");
    repaint();
}

您将把Swing组件直接添加到JFrame-AWT容器中。 你不应该那样做。 相反,您应该这样做:

JPanel panel = new JPanel();
myFrame.setContentPane(panel);

panel.setLayout(...)
panel.add(...);
panel.validate();

这应该可以解决您的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM