【发布时间】:2013-11-09 03:59:06
【问题描述】:
我正在为学校做一个项目,我正在使用插座制作一个图画游戏。对于图像的绘制,我找到了this 代码。我想使用版本 3,因为我不需要数字等所有功能。
现在,我的套接字已正确设置,但不幸的是,使用的 ScribbleCanvas(来自上面的链接)不可序列化(或者看起来就是这样)。有没有办法让它像这样,或者通过ObjectOutputStream发送它?速度应该不是真正的问题,因为它只应该在本地工作,目前在 localhost 上进行测试,所以它不应该是最有效的方式。
编辑:我已经对错误所在的程序做了一个快速模型,也许我在其他地方犯了一些错误。
import java.awt.BorderLayout;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JPanel;
import scribble3.ScribbleCanvas;
public class Main extends JFrame{
/* Scribble */
public static ScribbleCanvas myCanvas;
public static JPanel scribblePanel;
/* TCP */
public static ServerSocket hostServer;
public static Socket socket;
public static OutputStream os;
public static InputStream is;
public static ObjectInputStream ois;
public static ObjectOutputStream oos;
/* Panels & Frames */
public static JFrame mainFrame;
public static JPanel menuPanel;
public static JPanel mainPane;
/* Ohter */
public static boolean isHost = true; // is this instance a host or not?
public final static int DISCONNECTED = 0;
public final static int CONNECTING = 1;
public final static int CONNECTED = 2;
public static int connectionStatus = CONNECTING;
public static void initGUI(){
menuPanel = new JPanel();
//menuPanel = getMenu(); // some menu items
scribblePanel = new JPanel(new BorderLayout());
myCanvas = new ScribbleCanvas();
scribblePanel.add(myCanvas);
mainPane = new JPanel(new BorderLayout());
mainPane.add(menuPanel, BorderLayout.WEST);
mainPane.add(scribblePanel, BorderLayout.CENTER);
mainFrame = new JFrame("Pictionary");
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setBounds(200, 200, 800, 500);
mainFrame.setContentPane(mainPane);
mainFrame.setVisible(true);
}
public static void main(String[] args) {
initGUI();
while(true){
switch(connectionStatus){
case DISCONNECTED:
break;
case CONNECTING:
try{
if(isHost){ // You are a host
hostServer = new ServerSocket(5454);
socket = hostServer.accept();
}else{ // You're not a host
socket = new Socket("localhost", 5454);
}
os = socket.getOutputStream();
oos = new ObjectOutputStream(os);
is = socket.getInputStream();
ois = new ObjectInputStream(is);
oos.flush();
connectionStatus = CONNECTED;
}catch(IOException e){
connectionStatus = DISCONNECTED;
}
break;
case CONNECTED:
if(isHost){
try {
oos.writeObject(scribblePanel);
//oos.writeObject(myCanvas);
} catch (IOException e) {
e.printStackTrace();
}
}else{
try {
scribblePanel = (JPanel) ois.readObject();
//myCanvas = (ScribbleCanvas) ois.readObject();
mainFrame.repaint();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
break;
}
}
}
}
这是该程序的精简版,但它可以工作。如果您使用isHost = true; 运行一次,然后使用isHost = false; 运行一次,它们有一个连接,但随后我收到以下错误:java.io.NotSerializableException: scribble3.ScribbleCanvasListener,同时发送JPanel 和ScribbleCanvas。
java.io.NotSerializableException: scribble3.ScribbleCanvasListener
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at domain.Main.main(Main.java:102)
第 102 行引用 oos.writeObject(myCanvas) 或 oos.writeObject(myScribble)。
【问题讨论】:
-
不可序列化?这很奇怪......根据另一个 StackOverflow 问题,所有 JComponents 都是可序列化的。从那篇文章来看,您使用的是哪个版本的课程?
-
@RobinGreen:查看我所做的编辑。我尝试仅发送
ScribbleCanvas元素以及它所在的JPanel元素,但都给出了相同的错误。 -
NotSerializableException 的完整堆栈跟踪是什么?
-
@RobinGreen:我想我已经添加了你的要求。
标签: java sockets serialization objectoutputstream