gpt4 book ai didi

java - 如何发送对象,就像我可以使用 PrintWriter 发送字符串一样

转载 作者:太空宇宙 更新时间:2023-11-04 14:46:32 25 4
gpt4 key购买 nike

您好,我正在开发简单的客户端服务器应用程序,其中客户端可以绘制图片并使用文本聊天,我在按下按钮时发送文本,并且我想以相同的方式发送名为 ColorPointSize 的对象列表,它引用列表然后在面板上绘制点的颜色和大小。我可以像通过 PrintWriter 发送字符串一样简单吗?还是应该将它们转换为 String(),然后以某种方式将其转换回 ColorPointSize 或使用序列化,但我真的不知道该怎么做,我是初学者对于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();
}

}

最佳答案

这一切都归结为序列化和反序列化数据,您可能已经创建了 PrintWriter 来写入某种 OutputStream (甚至可能是 System. out,这只是一种方便的 OutputStream)。

java.io实际上提供了一组简洁的类:java.io.ObjectInputStreamjava.io.ObjectOutputStream。您可以将它们成对使用来发送任意 Java 对象,只要它们在类定义中添加“实现可序列化”即可——实现“可序列化”实际上并不添加任何方法,它只是用作 Java 的特殊标记允许将对象简化为其低级字节,并且只要对象中的每个项目也使用“implements Serialized”定义即可工作。通过将其命名为 Test.java 并运行“java Test”来尝试以下示例;我用“实现可序列化”修改了您的 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 类中(例如 Socket 对象),则此方法将不起作用。

现在,您可以将其包装在任何其他类型的 OutputStream 上,例如由网络套接字提供的输出流,而不是像示例中那样将 ObjectOutputStream 包装在 FileOutputStream 上,如果编写 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 > 在输入侧。一般来说,您需要将每个通信 channel 的输入和输出端视为一对,然后您可以真正选择您想要的任何策略,以某种可以轻松恢复的方式将数据保存到流中另一端。在上面的示例中,如果您希望序列化格式易于人类阅读,您可以轻松地使用“toString()”方法的某些组合。

关于java - 如何发送对象,就像我可以使用 PrintWriter 发送字符串一样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24329824/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com