【发布时间】:2016-02-20 02:46:51
【问题描述】:
我目前正在为我在 Java 课程中的期末项目设计一个字典游戏。它使用一个基本的 Echo Server 将数据从发送者发送到接收者。每个 GUI 都有自己的 DrawCanvas,但只有艺术家可以绘画,其他人都在观看。
画布的所有数据都存储在 ArrayLists 中,一个用于线条,一个用于颜色,一个用于线条粗细。在发送数据时,将其打包成一个 Envelope 并发送到服务器。
Envelope 类本质上是(字符串键,对象数据),因此您可以使用字符串标识信封并在另一端解包数据。
多个客户可以毫无问题地观看艺术家的绘画。艺术家画布不断向其他客户端发送点(通过 sendStartPoint() 和 sendPoint()),这些客户端在另一端重新构建到画布中。但是,如果客户端在绘制后加入,则需要使用所有画布数据更新它们,否则他们将只能看到加入后添加的内容。为此,使用了 sendCanvas() 和 loadCanvas() 方法。
我遇到的问题是,即使 sendCanvas() 正在发送所有数据,客户端也只接收绘制的第一行的数据。
除了下面发布的 DrawCanvas 类中的内容之外,这是唯一的其他数据处理方式——信封未打包。
如果有帮助,我可以发布更多其他课程的代码。
仅信封的其他处理
if (e.getKey().equals("draw")){
ArrayList<Object> data = (ArrayList<Object>)e.getData();
ArrayList<ArrayList<Point>> lines = (ArrayList<ArrayList<Point>>)data.get(0);
ArrayList<Color> colors = (ArrayList<Color>)data.get(1);
ArrayList<Integer> thickness = (ArrayList<Integer>)data.get(2);
clientUI.draw(lines, colors, thickness);
}
画布
private ArrayList<ArrayList<Point>> lines = new ArrayList<ArrayList<Point>>();
private ArrayList<Color> colorList = new ArrayList<Color>();
private ArrayList<Integer> thicknessList = new ArrayList<Integer>();
private Color color = Color.BLACK;
private int thickness = 3;
private ChatClient chat;
MouseAdapter ma;
{ // Mouse Listener Block
ma = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
addLine();
lines.get(lines.size() - 1).add(e.getPoint());
//sendCanvas();
sendStartPoint();
repaint();
}// end mousePressed
public void mouseReleased(MouseEvent e) {
lines.get(lines.size() - 1).add(e.getPoint());
//sendCanvas();
sendPoint();
repaint();
}// end mouseReleased
public void mouseDragged(MouseEvent e) {
lines.get(lines.size() - 1).add(e.getPoint());
//sendCanvas();
sendPoint();
repaint();
}// end mouseDragged
};
} // End Mouse Listener Block
// Stores all the data required to build entire canvas
public void loadCanvas(ArrayList<ArrayList<Point>> newLines, ArrayList<Color> newColors, ArrayList<Integer> newThickness){
System.out.println("RECEIVED CANVAS");
this.lines = newLines;
this.colorList = newColors;
this.thicknessList = newThickness;
repaint();
}
// Sends all of the data required to build entire canvas
public void sendCanvas(int id){
System.out.println("SENDING CANVAS");
ArrayList<Object> temp = new ArrayList<Object>();
temp.add(lines);
temp.add(colorList);
temp.add(thicknessList);
temp.add(id);
try {
chat.sendToServer(new Envelope("draw", temp));
} catch (IOException e1) {
System.out.println("Error sending canvas");
}
}
// Adds new blank line to hold points, updates attributes
public void addLine(){
lines.add(new ArrayList<Point>());
colorList.add(color);
thicknessList.add(thickness);
}
【问题讨论】:
-
应该发生的是,整个 ArrayList
> 应该保存在数据的第一个索引中。如果您查看 DrawCanvas 中的“sendCanvas”方法,ArrayList -
最好能发布less 代码,而不是更多代码。你能创建一个minimal reproducible example 吗?我们只需要查看直接导致问题的代码。看看你能不能把剩下的剪掉,即使最终程序没有做任何有用的事情。重要的是你有一个小程序可以做你意想不到的事情。
-
@JohnKugelman 我删减了那里的代码以仅显示重要的方法。我认为其他任何事情都不会影响结果,除非序列化和反序列化数据可能会产生一些影响。
-
@GeoDude,您在“最小”部分取得了一些进展,但您似乎并没有完全掌握“完整”和“可验证”部分。我们不想要您的代码的精简版本;我们想要演示相同问题的尽可能小的程序。
-
感谢您的编辑,这是一个明确的改进。详细说明 John B. 的观点,如果这个 bug 与发送和接收数据有关,那么你能去掉所有与 GUI 相关的代码吗?不要画任何东西,不要响应鼠标点击。如果您当前单击几个按钮来引发错误,请删除这些按钮并编写一个
main()方法来硬编码这些单击的结果。请阅读the page I linked,它详细介绍了如何创建一个好的 MCVE。
标签: java serialization arraylist