Reputation: 1
I want to send a Image object over a network in java.
Im getting this error.
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: sun.awt.image.OffScreenImage
The java Image object doesn't implement Serializable. Is there a way to get around this?
Ive already tried making a subclass of image and implement it but Then I got errors when using the createImage method. Thanks for any help.
EDIT*
Ok here is the code but there is kinda a lot. The idea of the program is for it to be a pictionary game. Someone can draw using basic tools and it will send it over a network and draw that image on other clients screen.
This is my basic draw area where the user and draw using a line tool. On mouse Released it will try and send the Image object over to the server.
class PadDraw extends JComponent {
Image image;
Graphics2D graphics2D;
int currentX, currentY, oldX, oldY;
int lineSize = 1;
public PadDraw() {
setDoubleBuffered(false);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
oldX = e.getX();
oldY = e.getY();
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
currentX = e.getX();
currentY = e.getY();
//graphics2D.drawLine(oldX, oldY, currentX, currentY); //this is where it does the drawing
//It seems to draw a line between the old coordinate point and the new coordinate point rather than drawing it as points
//Test to see if I can get a drawoval to work rather than a line
//graphics2D.fillOval(currentX-1, currentY-1, 2, 2);
//if this works it should draw an oval at the cursor position rather than drawing a line
//technically it works, but without a line it causes gaps
//I may have found it. Testing the setStroke method
graphics2D.setStroke(new BasicStroke(lineSize));
graphics2D.drawLine(oldX, oldY, currentX, currentY);
repaint();
oldX = currentX;
oldY = currentY;
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
try {
clientOutputStream.writeObject(image);
} catch (IOException ex) {
Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
@Override
public void paintComponent(Graphics g) {
if (image == null) {
image = (Image) createImage(getSize().width, getSize().height);
graphics2D = (Graphics2D) image.getGraphics();
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
clear();
}
g.drawImage(image, 0, 0, null);
}
public void updateImage(Image image){
this.image = image;
repaint();
}
public void clear() {
graphics2D.setPaint(Color.white);
graphics2D.fillRect(0, 0, getSize().width, getSize().height);
//graphics2D.setPaint(Color.BLACK);
lineSize = 1;
repaint();
}
public void fill(){
Color c = findColor();
graphics2D.setPaint(c);
graphics2D.fillRect(0, 0, getSize().width, getSize().height);
repaint();
}
public void changeColor(Color theColor) {
graphics2D.setPaint(theColor);
repaint();
}
public Color findColor() {
return graphics2D.getColor();
}
public void changeSize(int size) {
lineSize = size;
}
}
This is my threaded class for the image on the server.
private static class Handler2 extends Thread {
private Socket socket1;
private ObjectInputStream serverInputStream;
private ObjectOutputStream serverOutputStream;
public Handler2(Socket sock1) {
socket1 = sock1;
}
@Override
public void run() {
Image image = null;
try {
serverInputStream = new ObjectInputStream(socket1.getInputStream());
serverOutputStream = new ObjectOutputStream(socket1.getOutputStream());
oos.add(serverOutputStream);
while (true) {
image = (Image)serverInputStream.readObject();
for (ObjectOutputStream ooss : oos) {
ooss.writeObject(image);
}
}
} catch (IOException e) {
System.out.println(e);
} catch (ClassNotFoundException ex) {
Logger.getLogger(ChatServer.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if (serverOutputStream != null) {
oos.remove(serverOutputStream);
}
try {
socket1.close();
} catch (IOException e) {
System.out.println(e);
}
}
}
}
And back in the client I have a method for getting the image back from the server.
public void run2() throws IOException, ClassNotFoundException, InterruptedException {
// Make connection and initialize streams
serverAddress = getServerAddress();
Socket socket2 = new Socket(serverAddress, 9999);
//String theIP = getIP();
//Socket socket2 = new Socket(theIP, 9999);
// Process all messages from server, according to the protocol.
clientOutputStream = new ObjectOutputStream(socket2.getOutputStream());
clientInputStream = new ObjectInputStream(socket2.getInputStream());
while (true) {
Image ni = (Image)clientInputStream.readObject();
drawPad.updateImage(ni);
}
}
I know my code is kinda bad. I split thinks up a lot to test individual parts. As fare as the network code. It should work. The only problem I believe is that its not serializable.
Upvotes: 0
Views: 438
Reputation: 133567
Simple answer: no. sun.awt.image.OffScreenImage
is not meant to be directly serialized so you can't just add the Serializable
interface on a child class to make it serializable.
You have to find a work around, I'm not sure what is this image about but, for example, if it's from a set of known images then you can just send a key to it over the network so that you can recover it on the otherside. If you need to pass directly the image data then you'll have to encapsulate it in another object and rebuild the OffScreenImage on the other side.
You can extend the class and make it serializable with some work but since it seems to be a class tighly coupled with the operating system it will need some thinking.
Upvotes: 0
Reputation: 533492
The java Image object doesn't implement Serializable. Is there a way to get around this?
You can Serialize it yourself. You can wrap it with a class which is Externalizable, or you can write the data in the image without using writeObject.
Upvotes: 2