別のアプリケーションとして起動すると正常に動作する単純なネットワーク チェス ゲームがあります。しかし、別のアプリケーションのボタンから開始すると、チェス サーバーのクライアントがチェス サーバーに接続しようとすると、ゲームがハングします。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();
}
}
});
}
});
そして、これは別のアプリケーションとして開始されたクラスです (上記とまったく同じコードを使用しますが、ここではメイン メソッドにあります。
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);
}
}
}
問題が発生する可能性はありますか
static Socket s;
はいの場合、どうすれば最も痛みのないものを修正できますか?
メインメソッドと別のメソッドでオブジェクトを作成することに違いはありますか?