1

私はソケットを使って絵のゲームを作る学校のプロジェクトに取り組んでいます。画像の描画のために、このコードを見つけました。フィギュアなど全ての機能は必要ないのでバージョン3を使いたいです。

これで、私のソケットは正しくセットアップされましたが、残念ながら、ScribbleCanvas使用されている (上記のリンクから) はシリアル化できません (または、そのように見えます)。そのようにする方法はありますか、またはそれを送信する別の方法はありObjectOutputStreamますか? ローカルでのみ動作するはずであり、現在ローカルホストでテストしているため、速度は実際には問題になりません。最も効率的な方法ではないはずです。

編集: エラーのあるプログラムの簡単なモックアップを作成しました。おそらく他の場所で間違いを犯しています。

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

これはプログラムの簡素化されたバージョンですが、動作します。で 1 回、 で 1回実行するisHost = true;と、それらは接続されますが、isHost = false;次のエラーが発生します。java.io.NotSerializableException: scribble3.ScribbleCanvasListenerJPanelScribbleCanvas

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)orを参照していoos.writeObject(myScribble)ます。

4

1 に答える 1

1

問題は、いくつかのフィールドを書き込もうとしたときに発生します。のフィールドの 1 つがScribbleCanvasシリアル化できません。

すべてのフィールドを調べたところ、シリアル化できないオブジェクトが含まれているフィールドがあることに気付きました。聞き手です。リスナー クラスをシリアライズ可能にする必要があります。

于 2013-11-09T19:56:06.040 に答える