2016-02-20 76 views
0

我目前正在为我的Java课程中的最终项目设计一个Pictionary游戏。它使用基本的Echo服务器将数据从发送者回送到接收者。每个GUI都有自己的DrawCanvas,但只有艺术家可以绘制,其他人都可以观看。丢失ArrayList条目的问题

所有画布中的数据被存储在的ArrayLists,一个用于线,一个用于颜色,以及一个用于线的厚度。数据发送时,它被打包成一个信封并发送到服务器。

信封类基本上是(String键,对象的数据),因此可以使用ID字符串和解包上的另一端的数据的包络线。

多个客户端可以看到艺术家绘画没有问题。艺术家画布不断发送点(通过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); 
} 

DrawCanvas

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); 
} 
+0

什么应该发生,是整个的ArrayList >应在数据的第一索引被保持。如果您查看DrawCanvas中的“sendCanvas”方法,则tempList将存储所有数据,该数据将在另一个类中使用数据作为名称被删除。 – GeoDude

+2

如果您可以发布*少*代码,而不是更多代码,则会更好。你能创建一个[mcve]吗?我们只需要看到直接导致问题的代码。看看你是否可以修改其余部分,即使最终程序没有做任何有用的事情。重要的是,你有一个小程序可以做你不期望的事情。 –

+0

@JohnKugelman我修剪了那里的代码,以显示重要的方法。我认为别的什么都不应该影响结果,除非序列化和反序列化数据可能会产生一些影响。 – GeoDude

回答

0

我设法使我的工作方案。它没有提供答案,为什么一些数据没有被传输,但只是接受它作为事实并且围绕它进行工作。

正如你可以看到下面,我改变了sendCanvas()方法来发送的每行以自己的信封。

public void sendCanvas(int id){ 
    for (int i = 0; i < lines.size(); i++){ 
     System.out.println("SENDING CANVAS " + i); 
     ArrayList<Object> temp = new ArrayList<Object>(); 
     temp.add(lines.get(i)); 
     temp.add(colorList.get(i)); 
     temp.add(thicknessList.get(i)); 
     temp.add(id); 
     try { 
      chat.sendToServer(new Envelope("draw", temp)); 
     } catch (IOException e1) { 
      System.out.println("Error sending canvas"); 
     } 
    } 

而不是让DrawCanvas与loadCanvas()重建它,我更新了现有的addLine()方法,例如:

public void addLine(ArrayList<Point> line, Color c, int t){ 
    lines.add(line); 
    colorList.add(c); 
    thicknessList.add(t); 
    repaint(); 
} 

我知道这可能不是解决这一问题的最佳途径,但我的时间表很紧凑,而且工作。