문제

I'm working on a project for school where I'm using sockets to make a pictionary game. For the drawing of images I found this code. I want to use version 3, since I don't need all the functionality such as figures.

Now, my sockets have been set up correctly, but unfortunately the ScribbleCanvas used (from the link above) isn't serializable (or that's what it looks like). Is there any way to make it like that, or an other way to send it over an ObjectOutputStream? Speed shouldn't really be an issue since it's only supposed to work locally, currently testing on localhost so it shouldn't be the most efficiënt way.

edit: I've made a quick mockup of the program where the error is, perhaps I'm making some mistakes elsewhere.

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;
            }
        }
    }
}

This is a stripped down version of the program, but it works. If you run it once with isHost = true; and once with isHost = false;, they have a connection, but then I get the following error: java.io.NotSerializableException: scribble3.ScribbleCanvasListener, both with sending the JPanel as well as the 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)

With line 102 referring to oos.writeObject(myCanvas) or oos.writeObject(myScribble).

도움이 되었습니까?

해결책

The problem occurs when it tries to write some fields. One of the fields of the ScribbleCanvas is not serializable.

I've looked at all the fields, and I've noticed which one contains an object that is not serializable. It's the listener. You need to make the listener class serializable.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top