您好我正在处理简单的客户端服务器应用程序,其中客户端可以使用文本绘制图片和聊天,我在按下按钮时发送文本,并且我想以相同的方式发送名为ColorPointSize的对象List列表中的点,颜色和点的大小,然后在面板上绘制。我可以像通过PrintWriter发送字符串一样简单的方式,或者我将它们转换为String(),然后以某种方式将其转换回ColorPointSize或使用序列化,但我真的不知道如何做到这一点我&# 39;对于Java来说,我感到很困惑。
以下是代码的一些部分: 将消息发送到服务器
private void sendButtonActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
String nothing = "";
if ((inputTextArea.getText()).equals(nothing)) {
inputTextArea.setText("");
inputTextArea.requestFocus();
} else {
try {
writer.println(username + ":" + inputTextArea.getText() + ":" + "Chat");
// here i want to send also an object of type shall i do it via changing toString() and then somehow converting it or what ???
Date now = new Date();
String temp=inputTextArea.getText();
s_archiwum="\n"+s_archiwum+"\n"+now+" "+temp+"\n";
writer.flush(); // flushes the buffer
} catch (Exception ex) {
chatTextArea.append("Message was not sent. \n");
}
inputTextArea.setText("");
inputTextArea.requestFocus();
}
inputTextArea.setText("");
inputTextArea.requestFocus();
}
将已连接用户的名称添加到在线用户列表我想以类似的方式添加ColorPointSize。
public void userAdd(String data) {
String message, add = ": :Connect", done = "Server: :Done", name = data;
outputPane.append("Before " + name + " added. \n");
onlineUsers.add(name);
outputPane.append("After " + name + " added. \n");
String[] tempList = new String[(onlineUsers.size())];
onlineUsers.toArray(tempList);
for (String token : tempList) {
message = (token + add);
tellEveryone(message);
}
tellEveryone(done);
}
绘图方法:( cps是ColorPointSize类型的对象列表)
private void drawRoundRectangles(Graphics2D g2d) {
int x, y, x2, y2;
synchronized (cps) {
for (ColorPointSize p : cps) {
g2d.setColor(p.color);
x = (int) p.getX();
y = (int) p.getY();
x2 = (int) p.getX() - 1;
y2 = (int) p.getY() - 1;
g2d.drawLine(x, y, x2, y2);
g2d.fillRoundRect(x, y, p.size, p.size, p.size, p.size);
g2d.drawLine(x, y, x2, y2); // connectin' points wit' line
}
}
}
ColorPointSize类(以防万一)
package paintalk;
import java.awt.Color;
import java.awt.Point;
public class ColorPointSize {
public Color color;
public Point point;
public int size;
public ColorPointSize(Color c, Point p, int s) {
this.color = c;
this.point = p;
this.size = s;
}
ColorPointSize(Point p) {
this.point = p;
}
double getX() {
return point.getX();
}
double getY() {
return point.getY();
}
}
答案 0 :(得分:0)
这一切归结为序列化和反序列化数据,你可能已经创建了PrintWriter
来写某种OutputStream
(甚至可能是System.out
,这只是一个方便的OutputStream
)。
包java.io
实际上提供了一组简洁的类:java.io.ObjectInputStream
和java.io.ObjectOutputStream
。您可以将它们作为一对使用来发送任意Java对象,只要它们将“implements Serializable”添加到它们的类定义中 - 实现“Serializable”实际上并没有添加任何方法,它只是用作Java的特殊标记。允许将对象煮沸到低级字节,只要对象中的每个项目也使用“implements Serializable”定义,它就可以正常工作。通过命名Test.java并运行“java Test”来尝试以下示例;我使用“implements Serializable”修改了你的ColorPointSize类,但它没有改变:
import java.io.*;
import java.awt.Color;
import java.awt.Point;
class ColorPointSize implements Serializable {
public Color color;
public Point point;
public int size;
public ColorPointSize(Color c, Point p, int s){
this.color=c;
this.point=p;
this.size=s;
}
ColorPointSize(Point p){
this.point=p;
}
double getX(){
return point.getX();
}
double getY(){
return point.getY();
}
}
public class Test {
public static void main(String[] args) throws Exception {
ColorPointSize foo = new ColorPointSize(
new Color(123, 222, 111), new Point(42, 24), 50);
System.out.println(foo.color);
System.out.println(foo.point);
System.out.println(foo.size);
ObjectOutputStream fout = new ObjectOutputStream(
new FileOutputStream(new File("foo.dat")));
fout.writeUnshared(foo);
fout.close();
ObjectInputStream fin = new ObjectInputStream(
new FileInputStream(new File("foo.dat")));
ColorPointSize bar = (ColorPointSize) fin.readUnshared();
fin.close();
System.out.println(bar.color);
System.out.println(bar.point);
System.out.println(bar.size);
}
}
如果运行该示例,您将看到此示例成功将ColorPointSize实例的所有内部成员写入文件,然后将其重新读入,恢复其所有设置。请注意,如果您尝试在ColorPointSize类中放置一些基本上不是Serializable的东西,例如Socket对象,那么这将不起作用。
现在,不是像示例中那样将ObjectOutputStream包装在FileOutputStream周围,而是可以将其包装在任何其他类型的OutputStream周围,例如网络套接字提供的类型,如果编写Client /您可能会使用它服务器应用程序。
通常,编写原始对象可能很方便,但它可能并不总是最有效的方法。同样,有时您的课程不能直接序列化,您需要更好的控制。一个常见的模式是简单地向类添加方法以进行序列化和反序列化,如下所示:
class ColorPointSize {
public Color color;
public Point point;
public int size;
public void deserializeFrom(DataInputStream in) {
this.color = new Color(in.readInt(), in.readInt(), in.readInt());
this.point = new Point(in.readInt(), in.readInt());
this.size = in.readInt();
}
public void serializeTo(DataOutputStream out) {
out.writeInt(color.getRed());
out.writeInt(color.getGreen());
out.writeInt(color.getBlue());
out.writeInt(point.getX());
out.writeInt(point.getY());
out.writeInt(size);
}
}
或更有效率:
class ColorPointSize {
public Color color;
public Point point;
public int size;
public void deserializeFrom(DataInputStream in) {
this.color = new Color(in.readInt());
this.point = new Point(in.readInt(), in.readInt());
this.size = in.readInt();
}
public void serializeTo(DataOutputStream out) {
out.writeInt(color.getRGB());
out.writeInt(point.getX());
out.writeInt(point.getY());
out.writeInt(size);
}
}
然后,您可以在输入端使用new DataOutputStream(new FileOutputStream("foo.dat"))
代替new ObjectOutputStream
,同样使用new DataInputStream
。一般情况下,您需要将每个通信通道的输入和输出端都视为一对,然后您可以选择以某种方式将数据保存到流中的任何策略,以便轻松恢复另一端。在上面的示例中,如果您希望序列化格式是人类可读的,那么您可以轻松地使用“toString()”方法的某些组合。