JAVA通过网络发送Scribble

时间:2013-11-09 03:59:07

标签: java sockets serialization objectoutputstream

我正在为学校做一个项目,我正在使用套接字制作一个字典游戏。为了绘制图像,我找到了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)

1 个答案:

答案 0 :(得分:1)

尝试写入某些字段时会出现问题。 ScribbleCanvas的其中一个字段不可序列化。

我查看了所有字段,并且我注意到哪个字段包含一个不可序列化的对象。这是听众。您需要使侦听器类可序列化。