📄 j_fir_client.java
字号:
//客户端类
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.*;
import java.awt.*;
import java.io.*;
public class J_FIR_Client extends JFrame
{
////////////////////////////////////////////////////////////////////////////////////
private final int MAX_CLIENT_NUM = 50; //最大客户连接数
private final int LINE_NUM = 15; //棋盘纵横线条数
private int m_clientNumber = 0; //当前连接数
private int n; //客户端程序所存步数(0算1步)
private int q; //读取棋盘程序所存步数的临时变量
private int userNum; // 找到空闲在线用户的个数
private int buttonNum = -1; //按钮数
private int ColorInHand = -1; //黑棋为1,白棋为2
private int countTurns; // 比ColorInHand少时轮到本方下,否则对方下
private int tempN; // 用于更新n的临时变量
private int[] x = new int[LINE_NUM*LINE_NUM]; //棋子的横坐标
private int[] y = new int[LINE_NUM*LINE_NUM]; //棋子的纵坐标
private final boolean [] Entered = { false }; //已进入对局室(邀请成功或接收邀请)
private boolean isReady; //用于确定本方此回合是否下了至少一步棋
private boolean isConnected; //是否连网
private boolean Invited; //是否受邀
private boolean LookingForOnliners; //是否在查找在线空闲用户
private boolean readyToPlay; //是否准备或正在下棋
private boolean InvitationAccepted; //邀请是否被接受
private boolean RequestReplied; //邀请是否被答复
private boolean SideDecided; //是否选择了黑白
private boolean GameOver; //是否下完棋
private boolean ReplayOptionDecided; //是否决定了(重下与否)
private boolean ReplaySelected; //true表示决定了重下
private boolean MessageExist; //是否存在未弹的确定框
private boolean ChoiceExist; //是否存在未弹的选择框
private boolean GameLoaded = false; //是否打开了棋局文件
private boolean StopReplay = true; //是否结束复盘
private String host = "localhost"; //主机名
private int port = 5000; //端口号
private String PopContent; //弹出窗口的主要内容
private String myName; //本方的用户名
private String m_Message; //传递信息的一个临时变量
private String userName[] = new String[MAX_CLIENT_NUM]; //用户姓名列表
//下面的字符串的意思大体可以从其内容看出,不详细介绍了,用作传输数据的筛选
private String EXIT_NAME = "_EXIT_EXIT_";
private String PLAYING_COMMAND = "_This_is_the_playing_command_";
private String NAME_COMMAND = "_This_is_my_name...Hello_World!_";
private String NAME_LIST = "_%_ANOTHER_";
private String NAME_LIST_RESPONSE = "_These_are_the_players_online_:-)_";
private String OPPONENT_COMMAND = "_May_I_play_with_you?_";
private String FIND_REQUEST = "_Please_show_me_who_are_online_";
private String REQUEST_REJECTED = "_Sorry_I_am_busy_now!_";
private String REQUEST_ACCEPTED = "_OK_I_accept_your_invitation!_";
private String SIDE_DECISION = "_Do_you_like_black_or_white?_";
private String SIDE_COLOR = "_Use_this_Color:_";
private String YOUR_TURN = "_It_is_your_turn_now!_";
private String PLAY_REQUEST = "_Let's_play_!!!_";
private String WELCOME_INFO = "_Welcom_to_the_world_of_Five_In_Row!_";
private String WINNER_DECIDED = "_Winner_comes_out!_";
private String I_WANT_TO_GO = "_I_WANNA_GO_NOW._SEE_YOU~_";
private String PLAY_AGAIN = "_HAVE_ANOTHER_GAME,OK?_";
private String EXIT_SERVER = "_I'd_like_to_exit_the_server._";
private String REPLAYING_GAME = "_I'm_watching_the_replay._Don't_disturb_me._";
private String EXIT_REPLAY = "_Now_I_have_exited_the_replay_mode._I'm_back._";
private String DROP_LINE = "_Your_opponent_has_dropped_out_of_the_line._you_win!_";
private String CONTINUE_REQUEST = "_May_I_continue_this_game_with_you?_";
private String STEP_NUM = "_There_are_so_many_steps_in_my_file._";
private String STEP_CONTENT = "_The_position_of_chessmen_in_each_step_is:_";
private String DATA_RECEIVING_COMPLETED = "_I_have_received_all_saved_data_now._";
private String I_REGRET = "_I_regret_my_last_step._";
private String REGRET_AS_YOU_LIKE = "_You_may_get_back_your_last_step._";
private String NO_REGRET = "_You_cannot_regret_anyway._";
private final String[] Opponent = { EXIT_NAME }; //对手姓名。因内部类要用故如此定义
private FileDialog fsave,fload; //文件保存及打开
private Container c;
private ObjectInputStream m_input; //输入流
private ObjectOutputStream m_output; // 输出流
private JTextField m_enter; //聊天输入框
private JTextArea m_display; //信息显示框
private JMenuBar m_menu; //菜单栏
private J_FIR_Board m_board; //棋盘类
private JPanel[] p = new JPanel[3]; //面板
private JButton[] b = new JButton[MAX_CLIENT_NUM]; //按钮,用于显示在线用户
private JMenu[] m = {new JMenu("文件(F)"),new JMenu("操作(O)"),new JMenu("网络(W)"),new JMenu("帮助(H)") }; //主菜单
private char [][] mC = {{'F','E','W','H'},{'L','S','Z','X',},{'N','B','U','R'},{'C','K','E'},{'G','A'}}; //快捷键
private JMenuItem [][] mI =
{
{new JMenuItem("打开(L)"),new JMenuItem("存盘(S)"),new JMenuItem("关闭已打开的棋局(Z)"),new JMenuItem("退出程序(X)") },
{new JMenuItem("开局(单机)(N)"),new JMenuItem("悔棋(B)"),new JMenuItem("认输(U)"),new JMenuItem("复盘(R)") },
{new JMenuItem("连接到服务器(C)"),new JMenuItem("看看谁在线(K)"),new JMenuItem("退出服务器(E)")},
{new JMenuItem("游戏控制(G)"),new JMenuItem("关于(A)") }
}; //子菜单
////////////////////////////////////////////////////////////////////////////////////
public J_FIR_Client() //构造函数,主要进行面板设置及菜单监听器的添加
{
super("五子棋游戏客户端");
c = getContentPane();
c.setLayout(null);
int i,j;
for (i = 0;i<p.length;i++) p[i] = new JPanel();
p[0].setLayout(null);
p[1].setLayout(new BorderLayout());
m_enter = new JTextField("",12);
m_menu = new JMenuBar();
setJMenuBar(m_menu);
fload=new FileDialog(this,"打开",FileDialog.LOAD);
fsave=new FileDialog(this,"保存",FileDialog.SAVE);
for (i=0;i<m.length; i++) {
m_menu.add(m[i]);
m[i].setMnemonic(mC[0][i]);
for (j=0;j<mI[i].length; j++)
{
m[i].add(mI[i][j]);
mI[i][j].setMnemonic(mC[i+1][j]);
mI[i][j].setAccelerator(KeyStroke.getKeyStroke("ctrl " + mC[i+1][j]));
mI[i][j].addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
JMenuItem mItem = (JMenuItem)e.getSource();
String s = mItem.getText();
if (s.equals("打开(L)")) {
fload.setVisible(true);
String name=fload.getFile();
if(name!=null) {
mb_displayAppend("您选择打开文件"+name);
m_Load(name);
} else {
PopContent = new String("请输入文件名!");
MessageExist = true;
}
} else
if (s.equals("存盘(S)")) {
m_Save();
} else
if (s.equals("关闭已打开的棋局(Z)")) {
if (!StopReplay) {
PopContent = "请先退出复盘模式。";
MessageExist = true;
} else {
GameLoaded = false;
n = -1;
m_board.updateBoard(x,y,-1);
mb_displayAppend("棋局已关闭。");
}
} else
if (s.equals("退出程序(X)")) {
PopContent = "您确定要退出程序吗?";
ChoiceExist = true;
} else
if (s.equals("开局(单机)(N)")) {
if (isConnected) {
PopContent = "您现已连接到服务器,不支持单机模式.";
MessageExist = true;
} else {
n = -1;
m_board.updateBoard(x,y,-1);
m_board.setSingle(true);
}
} else
if (s.equals("悔棋(B)")) {
if (!isConnected) {
PopContent = "当前没有正在和人下的棋。";
MessageExist = true;
} else {
try
{
m_output.writeObject(I_REGRET);
}
catch (Exception ee)
{
System.out.println("出现异常:"+ee);
ee.printStackTrace();
}
}
} else
if (s.equals("认输(U)")) {
if (!readyToPlay) {
PopContent = "您并没有在下棋呀?";
MessageExist = true;
} else {
PopContent = "您真的要认输吗?";
ChoiceExist = true;
}
} else
if (s.equals("复盘(R)")) {
if (!GameLoaded) {
PopContent = new String("请先打开一个棋局文件。");
MessageExist = true;
} else {
PopContent = new String("进入复盘模式。");
MessageExist = true;
}
} else
if (s.equals("连接到服务器(C)")) {
if (isConnected) {
PopContent = new String("您已连接至服务器。");
MessageExist = true;
} else {
PopContent = "请输入服务器主机名";
ChoiceExist = true;
// isConnected = true;
}
} else
if (s.equals("看看谁在线(K)")) {
if (!isConnected) {
PopContent = new String("您尚未登陆,请先连接到服务器。");
MessageExist = true;
} else
if (readyToPlay) {
PopContent = new String("您尚未离开对局室,无法察看广场人员情况。");
MessageExist = true;
} else {
try
{
m_output.writeObject(FIND_REQUEST);
}
catch (Exception ee)
{
System.out.println("出现异常:"+ee);
ee.printStackTrace();
}
}
} else
if (s.equals("退出服务器(E)")) {
if (!isConnected) {
PopContent = new String("您尚未连接到服务器。");
MessageExist = true;
} else {
try
{
m_output.writeObject(EXIT_SERVER);
mb_displayAppend("您已向服务器发送断开连接申请,请等待回应...");
isConnected = false;
LookingForOnliners = false;
GameOver = true;
}
catch (Exception ee)
{
System.out.println("出现异常:"+ee);
ee.printStackTrace();
}
}
} else
if (s.equals("游戏控制(G)")) {
PopContent = "游戏控制";
MessageExist = true;
} else
if (s.equals("关于(A)")) {
PopContent = "介绍";
MessageExist = true;
}
}
}
);
}
}
m_enter.setEnabled(true);
m_enter.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent Event)
{
try
{
String s = Event.getActionCommand();
m_output.writeObject(s);
m_output.flush();
mb_displayAppend(myName+"说:"+s);
m_enter.setText("");
}
catch (Exception e)
{
System.err.println("发生异常:"+e);
e.printStackTrace();
}
}
}
);
c.add(m_menu);
m_menu.setBounds(new Rectangle(0,0,300,25));
m_board = new J_FIR_Board();
p[0].add(m_board);
m_board.setBounds(new Rectangle(0,30,480,490));
p[2].setLayout(new BoxLayout(p[2],BoxLayout.Y_AXIS));
ScrollPane sp = new ScrollPane(); //!!!!!!!
sp.setBounds(new Rectangle(0,530,480,150));
sp.add(p[2]);
p[0].add(sp);
m_display = new JTextArea("",30,12);
p[1].add(new JScrollPane(m_display),BorderLayout.CENTER);
p[1].add(m_enter,BorderLayout.SOUTH);
c.add(p[0]);
p[0].setBounds(new Rectangle(0,30,480,750));
c.add(p[1]);
p[1].setBounds(new Rectangle(480,30,200,600));
}
class Pop extends Thread //弹窗口线程,监测是否有窗口要弹
{
public Pop()
{
start();
}
public void run()
{
while (true) {
if (MessageExist) {
PopMessage();
MessageExist = false;
} else
if (ChoiceExist) {
PopChoice();
ChoiceExist = false;
}
}
}
}
public void PopMessage() //弹确定框
{
if (PopContent.equals("介绍")) {
J_FIR_Introduction intro = new J_FIR_Introduction();
intro.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
intro.setSize(600,600);
intro.setLocation(100,100);
intro.setVisible(true);
while (intro.u_Choice[0]==-1)
;
intro.dispose();
return;
} else
if (PopContent.equals("游戏控制")) {
J_FIR_Help intro = new J_FIR_Help();
intro.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
intro.setSize(600,600);
intro.setLocation(100,100);
intro.setVisible(true);
while (intro.u_Choice[0]==-1)
;
intro.dispose();
return;
}
J_FIR_Message jfm = new J_FIR_Message(PopContent);
//jfm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfm.setSize(320,200);
jfm.setLocation(400,450);
jfm.setVisible(true);
while (jfm.u_Choice[0]==-1)
;
jfm.dispose();
if (PopContent.equals("进入复盘模式。")) m_Replay();
}
public void PopChoice() //弹选择框
{
try
{
String Posi = "确定";
String Nega = "取消";
if (PopContent.equals("对方想悔棋,您是否同意?")) {
Posi = "同意";
Nega = "拒绝";
}
if (PopContent.equals("请输入服务器主机名")) {
J_FIR_Host jfh = new J_FIR_Host();
jfh.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfh.setSize(370,200);
jfh.setLocation(420,420);
jfh.setVisible(true);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -