代码仅在我使用断点时起作用 - 可能是线程问题

时间:2016-01-08 04:48:15

标签: java swing input

我知道这可能是一个时间问题,但老实说,我没有足够的经验来解决具体问题,并找出解决方法。 基本上,它是一个Connect Four游戏,我现在正在学习事件监听器等基础知识。

package siena;
import java.awt.*;

import javax.imageio.ImageIO;
import javax.swing.*;

public class ConnectFour {
    public static int buttonPushed = -1;

    public static void main (String[] args) throws java.lang.Exception {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gs = ge.getDefaultScreenDevice();
        GraphicsConfiguration gc = gs.getDefaultConfiguration();
        JFrame board = new JFrame("Connect Four", gc);
        board.setResizable(false);
        board.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        GridBagLayout gridbag = new GridBagLayout();
        board.setLayout(gridbag);
        GridBagConstraints c = new GridBagConstraints();
        c.gridwidth = 3;
        JButton ng = new JButton("New Game");
        c.anchor = c.NORTH;
        c.fill = c.HORIZONTAL;
        c.insets = new Insets(5, 5, 5, 5);
        board.add(ng, c);
        c.gridx = 1;
        JButton eg = new JButton("Close");
        c.gridy = 1;
        c.gridwidth = 1;
        final JButton add[] = new JButton[7];
        ButtonClicker clickers[] = new ButtonClicker[9];
        for (int i = 0; i < clickers.length; i++) {
            clickers[i] = new ButtonClicker(i);
        }
        ng.addActionListener(clickers[0]);
        eg.addActionListener(clickers[8]);
        for(int i = 0; i < 7; i++) {
            add[i] = new JButton("Drop token");
            add[i].addActionListener(clickers[i + 1]);
            c.gridx = i;
            board.add(add[i], c);
        }
        JLabel slot[][] = new JLabel[7][6];
        int slotStat[][] = new int[7][6];
        c.ipadx = 0;
        c.ipady = 0;
        c.gridx = 0;
        c.gridy = 2;
        ImageIcon[] img = {new ImageIcon(ImageIO.read(new java.io.File("src/siena/gray.png"))), new ImageIcon(ImageIO.read(new java.io.File("src/siena/red.png"))), new ImageIcon(ImageIO.read(new java.io.File("src/siena/yellow.png")))};
        JLabel n = new JLabel(img[0]);
        for (int x = 0; x < 7; x++) {
            for (int y = 0; y < 6; y++) {
                slot[x][y] = new JLabel(n.getIcon());
                slotStat[x][y] = 0;
                board.add(slot[x][y], c);
                c.gridy++;
            }
            c.gridx++;
            c.gridy = 2;
        }
        c.gridx = 0;
        c.gridy = 8;
        c.gridwidth = 7;
        c.anchor = c.CENTER;
        Label info = new Label("It is the RED player's turn.");
        info.setAlignment(info.CENTER);
        board.add(info, c);
        board.pack();
        board.setVisible(true);
        boolean isRedTurn = true;
        int redCheck = 0;
        int yellowCheck = 0;
        while(buttonPushed != 9){
            while(buttonPushed == -1);
                switch(buttonPushed) {
                    case 0: 
                        for (int x = 0; x < 7; x++) {
                            for (int y = 0; y < 6; y++) {
                                slotStat[x][y] = 0;
                                slot[x][y].setIcon(img[0]);
                                isRedTurn = true;
                            }
                        }
                        buttonPushed = -1;
                        break;
                    case 1: case 2: case 3: case 4: case 5: case 6: case 7:
                        if (slotStat[buttonPushed - 1][0] != 0) {
                            info.setText("That column is full!");
                            info.wait(100, 50000);
                            buttonPushed = -1;
                            break;
                        } else {
                            for (int y = 0; y < 6; y++) {
                                if (y != 5 && slotStat[buttonPushed - 1][y + 1] == 0) {
                                    //if we're not at the bottom and the slot below this one is empty
                                    if (isRedTurn) slot[buttonPushed - 1][y].setIcon(img[1]);
                                    else slot[buttonPushed - 1][y].setIcon(img[2]);
                                    Thread.sleep(200);
                                    slot[buttonPushed - 1][y].setIcon(img[0]);
                                } else {
                                    //if we're at the bottom or the slot below this one is full
                                if (isRedTurn) {
                                    slotStat[buttonPushed][y] = 1;
                                    slot[buttonPushed][y].setIcon(img[1]);
                                    redCheck++;
                                } else {
                                    slotStat[buttonPushed][y] = 2;
                                    slot[buttonPushed][y].setIcon(img[2]);
                                    yellowCheck++;
                                }
                                isRedTurn = !isRedTurn;                 
                            }
                        }
                    }
                    buttonPushed = -1;
                break;
            }
        }       
    }
}

ButtonPushed类只是扩展ActionListener的东西,所以我可以找出按下了什么按钮,它有一个“id”int属性,按下按钮被传递给连接四件中的buttonPushed int

1 个答案:

答案 0 :(得分:1)

因此,总结一下这些评论,我使用的是一种在线性(非基于事件)程序中使用的结构。虽然循环在等待输入时不起作用,而不是使用一个大的静态主方法和稍微修改的ActionListener类,我应该使用输入事件来调用内部方法来修改内部数据,然后更新外部GUI (基于内部数据在其自己的类中,并使用自己的类方法)。

如果有人需要看一个例子,这是我迄今为止的工作。我仍然需要编辑其中一些(即程序如何结束,我需要添加一个win检测器),但GUI功能完备。

ConnectFour类:http://pastebin.com/yeGALQn7

ButtonClicker类:​​http://pastebin.com/Y2y0SfW9

CFBoard课程:http://pastebin.com/g9qqBmry

哦,而且,对于好奇的阅读,我有理由相信它只在调试模式下工作的原因是断点阻止输入与通过while()循环遍历的main()冲突因此,使其完全由事件驱动意味着这些冲突不再存在。

感谢大家的帮助,特别是@HovercraftFullOfEels!