我有一个简单的网络象棋游戏,当我将它作为一个单独的应用程序启动时它运行良好。但是当我从另一个应用程序的按钮启动它时,当国际象棋服务器的客户端尝试连接到国际象棋服务器时,游戏会挂起。当在 main(...) 方法中创建 ChessStart 对象时,程序似乎可以工作。但是当它在 actionPerformed() 中进行时,会发生一些事情。
这是从按钮启动的方式
chessButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
ChessStart frame = new ChessStart();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
});
这是作为一个单独的应用程序启动的类(我使用与上面完全相同的代码,但这里是在 main 方法中。
public class ChessStart extends JFrame implements Runnable {
private static final long serialVersionUID = 7926472295620076147L;
private JPanel contentPane;
static Socket s;
ObjectOutputStream oops;
ObjectInputStream oips;
ChessGameDemo1 chess;
Thread tred, serThread;
boolean title;
private JTextField serversIPField;
ServerSocket serSocket;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
ChessStart frame = new ChessStart();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public ChessStart() {
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent arg0) {
try {
oops.close();
oips.close();
s.close();
serSocket.close();
System.exit(0);
} catch (Exception e) {System.exit(1);}
}
});
chess=new ChessGameDemo1();
chess.setTitle("Click one of the buttons!");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle(" NikiFin Chess");
setBounds(100, 100, 497, 196);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
tred=new Thread(this);
JButton startServerButton = new JButton("Start server");
startServerButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
chess.setTitle("Waiting for connection....");
title=true;
try {
serThread=new Thread(new ServerThread(chess, tred));
serThread.start();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Exception from accept socket: " + e);
System.exit(1);
}
}
});
startServerButton.setBackground(SystemColor.menu);
startServerButton.setForeground(Color.BLACK);
startServerButton.setFont(new Font("Tahoma", Font.PLAIN, 12));
startServerButton.setBounds(10, 5, 143, 29);
contentPane.add(startServerButton);
JButton connectToServerButton = new JButton("Connect to server");
connectToServerButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
title=true;
String ip1=serversIPField.getText();
String ip=removeIntervals(ip1);
s = new Socket(ip,7777);
ChessGameDemo1.color="black";
oips = new ObjectInputStream(s.getInputStream());
chess.myFigures = ((ArrayList<Figure>)oips.readObject());
chess.changePosition();
chess.repaint();
oops = new ObjectOutputStream(s.getOutputStream());
oops.writeObject(chess.myFigures);
chess.setTitle("The other part's turn");
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Exception from connect to server socket: " + ex);
System.exit(1);
}
chess.ready=true;
dispose();
tred.start();
}
});
connectToServerButton.setFont(new Font("Tahoma", Font.PLAIN, 12));
connectToServerButton.setBounds(10, 40, 143, 29);
contentPane.add(connectToServerButton);
serversIPField = new JTextField();
serversIPField.setBounds(360, 43, 113, 24);
contentPane.add(serversIPField);
serversIPField.setColumns(10);
JLabel lblNewLabel = new JLabel("To join a game, play black. Server IP:");
lblNewLabel.setBounds(161, 45, 195, 21);
contentPane.add(lblNewLabel);
JLabel lblNewLabel_1 = new JLabel("To start a new game wainting for a partner, play white.");
lblNewLabel_1.setBounds(161, 8, 310, 22);
contentPane.add(lblNewLabel_1);
JTextArea txtrToPlayThe = new JTextArea();
txtrToPlayThe.setFont(new Font("Tahoma", Font.PLAIN, 13));
txtrToPlayThe.setText("To play the server must be started first. The other part must know the server's \r\nIP address. To get it can be used the button Whois. Mark the name of the \r\nuser started the server and klick Whois button. This will give you the server's \r\nIP address. Enter it in the blank field and click Connect to server. Have fun!");
txtrToPlayThe.setBackground(SystemColor.control);
txtrToPlayThe.setBounds(5, 80, 475, 69);
contentPane.add(txtrToPlayThe);
BufferedImage img = null;
try {
img = ImageIO.read(getClass().getResource("/chess.png"));
} catch (Exception e) {
e.printStackTrace();
try {
e.printStackTrace();
} catch (Exception ex) {}
}
setIconImage(img);
}
public void run() {
while(true) {
try {
oips = new ObjectInputStream(s.getInputStream());
chess.myFigures = ((ArrayList<Figure>)oips.readObject());
chess.changePosition();
chess.setTitle("Now is your turn!");
chess.ready = true;
if(title) {
chess.setTitle("Ready!");
title=false;
}
chess.repaint();
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Exception in input stream: " + ex);
ex.printStackTrace();
System.exit(1);
}
try {
while (chess.ready)
Thread.sleep(100);
oops = new ObjectOutputStream(s.getOutputStream());
oops.writeObject(chess.myFigures);
chess.setTitle("The other part's turn");
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Exception in output stream: " + ex);
System.exit(1);
}
}
}
这是套接字线程
public class ServerThread implements Runnable {
ChessGameDemo1 chess;
ServerSocket serSocket;
Socket s;
Thread tread;
ObjectOutputStream oops;
ObjectInputStream oips;
public ServerThread(ChessGameDemo1 ches, Thread tred) {
chess=ches;
tread=tred;
}
public void run() {
try {
serSocket=new ServerSocket(7777);
ChessStart.s = serSocket.accept();
ChessGameDemo1.color="white";
chess.setTitle("White to play!");
oops = new ObjectOutputStream(ChessStart.s.getOutputStream());
oops.writeObject(chess.myFigures);
tread.start();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}
问题是否可能来自
静态套接字;
如果是的话,我该如何解决最无痛的问题?
在主要方法和另一种方法中制作对象有什么区别吗?