我正在为一个学校的项目工作,我正在使用套接字制作一款益智游戏。对于图像绘制,我找到了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,同时发送JPanelScribbleCanvas

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)

最佳答案

当它尝试写入一些字段时,会发生此问题。 ScribbleCanvas的字段之一不可序列化。

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

07-28 08:06