0

我正在使用套接字通过 LAN 为两名玩家制作 Connect 4 游戏。当服务器玩家(玩家一)做出选择时,他看不到自己的选择,只有其他玩家看到。当其他玩家做出选择时,玩家 1 会看到他自己的第一个选择和用户的第一个选择。本质上,玩家直到下一轮才能看到他当前的选择。当我用 System.out.println 替换 setIcon 部分时,它会打印表示已到达代码的行。

为什么会这样,我该如何解决?如果我取出代码“yourWait();”,它似乎可以工作,但用户不会阅读其他玩家的选择。感谢您的任何帮助!

    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.*;
    import java.net.*;
    import javax.swing.*;

    public class GameBoard extends JPanel implements ActionListener
    {
        JLabel title;
        boolean isHost;

        public Button[] columnpieces = new Button[7];
        int piecesInColumn[] = {0,0,0,0,0,0,0};
        JLabel[][] pieces = new JLabel[7][6];
        int colorOfPiece = 0;

        final JLabel GRID = new JLabel(new ImageIcon("GRID.gif"));
        final ImageIcon RED = new ImageIcon("RED.jpg");
        final ImageIcon BLACK = new ImageIcon("BLACK.jpg");

        JPanel one, two;

        ServerSocket serverSocket = null;
        Socket clientSocket = null;
        BufferedReader reader;
        PrintWriter writer;

        public GameBoard()
        {
            super();
            setBounds(0,0,1000, 700);
            setBackground(Color.yellow);
            setLayout(null);

            title = new JLabel("Connect 4");
            title.setBounds(0,5, 1000, 90);
            title.setFont(new Font("Georgia", Font.BOLD, 100));
            title.setForeground(Color.blue);
            title.setHorizontalAlignment(JLabel.CENTER);
            add(title);

            GRID.setBounds(200, 150, 600, 500);
            add(GRID);

            for (int a = 0; a < columnpieces.length; a ++)
            {
                columnpieces[a] = new Button("Place");
                columnpieces[a].addActionListener(this);
                columnpieces[a].setBounds(209 + 84 * a, 100, 70, 50);
                columnpieces[a].setBackground(Color.white);
                columnpieces[a].setFont(new Font("Arial", Font.BOLD, 20));
                add(columnpieces[a]);

                for (int b = 0; b < pieces[0].length; b ++)
                {
                    pieces[a][b] = new JLabel();
                    pieces[a][b].setBounds(208 + 83 * a,555 - 77 *b, 75,75);
                    add(pieces[a][b]);
                }
            }
        }

        public void setHost(String name) throws IOException
        {
            isHost = true;
            try {
                System.out.println(InetAddress.getLocalHost().getHostAddress());
            } catch (UnknownHostException e2) {
                // TODO Auto-generated catch block
                e2.printStackTrace();
            }
            try {
                serverSocket=new ServerSocket(706);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            Socket clientSocket = null;
            try {
                clientSocket = serverSocket.accept();
            } catch (IOException e1) {
                System.err.println("Accept failed.");
                System.exit(1);
            }
            try {
                writer=new PrintWriter(clientSocket.getOutputStream(),true);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            try {
                reader=new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            } catch (IOException e1) {
                e1.printStackTrace();
            }     
           yourTurn();
        }

        public void setClient(String name) throws IOException
        {
            isHost = false;
                try {
                    clientSocket=new Socket(JOptionPane.showInputDialog("Enter host address.", "192.168.1.137"),706);
                    writer=new PrintWriter(clientSocket.getOutputStream(),true);
                    reader=new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                } catch (UnknownHostException e) {
                    System.err.println("Don't know about host.");
                    System.exit(1);
                } catch (IOException e) {
                    System.err.println("Couldn't get I/O for the connection");
                    System.exit(1);
            }
            yourWait();
        }

        @Override
        public void actionPerformed(ActionEvent e) 
        {
            if (e.getSource() == columnpieces[0])
                updateFromClick(0);
            if (e.getSource() == columnpieces[1])
                updateFromClick(1);
            if (e.getSource() == columnpieces[2])
                updateFromClick(2);
            if (e.getSource() == columnpieces[3])
                updateFromClick(3);
            if (e.getSource() == columnpieces[4])
                updateFromClick(4);
            if (e.getSource() == columnpieces[5])
                updateFromClick(5);
            if (e.getSource() == columnpieces[6])
                updateFromClick(6);
        }

        void setButtonEnables(boolean enabled)
        {
            for (int a = 0; a < columnpieces.length; a ++)
            {
                if(piecesInColumn[a] == 6 || !enabled)
                    columnpieces[a].setEnabled(false);
                else
                    columnpieces[a].setEnabled(true);
            }
        }

        private void addPiece(int column)
        {
            int b = piecesInColumn[column];

            if(colorOfPiece % 2 == 0)
                pieces[column][b].setIcon(BLACK);
            else if (colorOfPiece % 2 == 1)
                pieces[column][b].setIcon(RED);
        }

        private void updateFromClick(int column)
        {
            addPiece(column);
            colorOfPiece +=1;
            piecesInColumn[column] +=1;
            writer.println(column);
            yourWait();
        }

        private void updateFromRecieved(int column)
        {
            addPiece(column);
            colorOfPiece +=1;
            piecesInColumn[column] +=1;
            yourTurn();
        }

        public void yourTurn()
        {
                setButtonEnables(true);
        }

        public void yourWait()
        {
                setButtonEnables(false);
                try {
                    updateFromRecieved(Integer.parseInt(reader.readLine()));
                } catch (NumberFormatException e) {
                    System.err.println("Message is not Integer.");
                } catch (IOException e) {
                    System.err.println("Message can not be read.");
                }
        }
    }
4

1 回答 1

0

问题是您阻塞了 UI 线程。

你最终调用这个:

updateFromRecieved(Integer.parseInt(reader.readLine()));

响应您的点击。这样做的问题是 UI 在完成之前无法重新绘制屏幕reader.readLine()。这显然是在对手发出他的动作之前。

要解决此问题,您应该考虑使用线程来使网络代码远离 UI 线程。这几乎从来都不是一个好主意。

于 2013-06-18T11:42:41.443 回答