在JPanel上绘制并向多个客户端广播

3
我有一个多用户聊天室共享白板应用程序,在其中我使用Jpanel在特定客户端上进行绘制,然后通过Java Socket编程通过服务器广播到其他客户端。我的问题是,我希望绘图功能能够实时工作,也就是说,一旦在一个客户端的JPanel上完成绘图,其他客户端就应该立即看到。我在JPanel的mouseReleased事件中编写了该函数,但只有在该客户端的JPanel上触发mouseReleased事件后,其他客户端才能看到它。是否有人可以建议我如何让操作更好(实时)?
        @Override
        public void mouseReleased(MouseEvent e) {           
            lineObject =  new LineMessage(); 
            lineObject.setImageMessage(DrawPanel.linelist);
            ChatApplication_Client.Action_Paint(lineObject);

        }

ChatApplication_Client.java

  public void run(){
    System.out.println("Listening for messages from server . . . ");                       
    try{
                    while(!receivingdone){
                        object = myInputStream.readObject();

                       if(object instanceof LineMessage)
                        {
                            lineObject = (LineMessage) object;
                            WhiteBoardMessageReceive(lineObject);
                        }
                     } 

        }

// 这个方法负责重新绘制并在客户端广播

  private void WhiteBoardMessageReceive(LineMessage lineObject)
   {
                ArrayList<Line> linelist = (ArrayList) 
                lineObject.getImageMessage();                          
                ChatClient_GUI.TA_ChatWindow.append(lineObject.Name+": "
                                +lineObject.Text + "\n" + "At [" 
                                    +DateUtils.now()+ "] " + "\n");
                    drawPanel.drawit(linelist);
   }

//下面的方法是在鼠标释放事件上从GUI中调用的。
  public static void Action_Paint(LineMessage lineObject)
   {

       try
       {
        myOutputStream.reset();
        myOutputStream.writeObject(lineObject);
        myOutputStream.flush();
       }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
        }
   }

LineMessage.java

class LineMessage implements Serializable 
   {
    ArrayList<Line> message;
    Line line = new Line();
    String Name =line.getName() ;
    String Text ;
    public void setImageMessage(Object message) {
            this.message = (ArrayList) message;
    }

    public Object getImageMessage() {
    return message;
    }
}
class Line extends ChatMessage implements Serializable {
int startx, starty, endx, endy;
    public Line() {
    }
    public Line(int sx, int sy, int ex, int ey)
    {
    setStartX(sx);
    setStartY(sy);
    setEndX(ex);
    setEndY(ey);
    }
        public void setStartX(int sx) {

        startx = sx;
        }
        public void setStartY(int sy) {
        starty = sy;
        }
        public void setEndX(int ex) {
        endx = ex;
        }
        public void setEndY(int ey) {
        endy = ey;
        }
        public int getStartX() {
        return startx;
        }
        public int getStartY() {
        return starty;
        }
        public int getEndX() {
        return endx;
        }
        public int getEndY() {
        return endy;
        }
}

1
我们需要比这更多的代码。特别是ChatApplication_Client类,还有LineMessage类也可能很有用。 - Jonny Henly
MouseMotionListener.mouseDragged - ControlAltDel
为了更快地获得帮助,请发布一个[MCVE]或简短,自包含,正确的示例 - Andrew Thompson
绘制... 并将其广播到多个客户端。参见《如何将Java 2D Shape对象序列化为XML?》(https://dev59.com/fYTba4cB1Zd3GeqP8p5H)。 - Andrew Thompson
1个回答

0
    List<Point> pointList = new ArrayList<>();
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(300, 500);

    JPanel panel = new JPanel(){
        @Override
        public void paint(Graphics g) {
            super.paint(g);
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, getWidth(), getHeight());

            g.setColor(Color.BLACK);
            Point l = null;
            for(Point p : pointList){
                if(l != null && p != null)
                    g.drawLine(l.x, l.y, p.x, p.y);
                l = p;
            }
        }
    };
    frame.setContentPane(panel);

    panel.addMouseMotionListener(new MouseMotionListener() {
        boolean isDrawing = false;
        @Override
        public void mouseDragged(MouseEvent e) {
            pointList.add(e.getPoint());
            isDrawing = true;
            panel.repaint();
        }

        @Override
        public void mouseMoved(MouseEvent e) {
            if(isDrawing)
                pointList.add(null); //null is a placeholder to mean line is finished
            isDrawing = false;
        }
    });


    frame.setVisible(true);

也许可以在代码旁边添加一些解释。 - Jonny Henly
我已经在DrawPanel类中编写了一段代码,您建议我在哪里进行更改? - ANUSHREE SAHA
DrawPanel类在哪里?你应该像上面展示的那样使用MouseMotionListener。每当鼠标移动时,如果鼠标按钮按下,则调用mouseDragged,如果鼠标按钮松开,则调用mouseMoved。尝试运行上面的代码,看看能否从中弄清楚它是如何工作的。如果仍然有问题,我在这里可以帮忙。 - John E.
它不起作用,即使我使用MouseMotionListener编写它,它也不会显示。 - ANUSHREE SAHA
你能给我看一下有问题的代码吗?那个带有MouseMotionListener的代码? - John E.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接