Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将GraphicsContext从客户端发送到服务器,然后发送到所有其他客户端?_Java_Networking_Javafx - Fatal编程技术网

Java 如何将GraphicsContext从客户端发送到服务器,然后发送到所有其他客户端?

Java 如何将GraphicsContext从客户端发送到服务器,然后发送到所有其他客户端?,java,networking,javafx,Java,Networking,Javafx,我现在遇到了输入和输出流的问题。它不会将套接字输入流转换为byte[]或将套接字输出流转换为int。如何让程序实际将byte[]数组发送到服务器?以下是更新的代码: import java.io.*; import java.net.*; import javafx.application.Application; import javafx.event.EventHandler; import javafx.scene.input.MouseEvent; import javafx.scene

我现在遇到了输入和输出流的问题。它不会将套接字输入流转换为byte[]或将套接字输出流转换为int。如何让程序实际将byte[]数组发送到服务器?以下是更新的代码:

import java.io.*;
import java.net.*;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.input.MouseEvent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import java.awt.image.BufferedImage;
import java.io.File;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.*;
import javax.imageio.ImageIO;

public class PaintClient extends Application {
  //GUI components
  private TextField tfRed = new TextField("");
  private TextField tfGreen = new TextField("");
  private TextField tfBlue = new TextField("");
  private Button btSetColor = new Button("Set Color");
  private Button btReset = new Button("Reset");
  private Button btSend = new Button("Send");
  //Networking components
  private Socket socket;
  private ByteArrayOutputStream byteOut;
  private ByteArrayInputStream byteIn;

  @Override
  public void start(Stage primaryStage) {

    tfRed.setPrefWidth(80);
    tfGreen.setPrefWidth(80);
    tfBlue.setPrefWidth(80);

    GridPane gridPane = new GridPane();
    gridPane.add(new Label("Color"), 0, 0);
    gridPane.add(tfRed, 1, 0);
    gridPane.add(tfGreen, 2, 0);
    gridPane.add(tfBlue, 3, 0);
    gridPane.add(btSetColor, 4, 0);
    gridPane.add(btReset, 2, 1);
    gridPane.add(btSend, 3, 1);

    Canvas canvas = new Canvas(365,375);
    final GraphicsContext gc = canvas.getGraphicsContext2D();
    initDraw(gc);

    BorderPane bPane = new BorderPane();
    bPane.setTop(gridPane);
    bPane.setCenter(canvas);

    Scene scene = new Scene(bPane, 375, 450);
    primaryStage.setTitle("Drawing Canvas");
    primaryStage.setScene(scene);
    primaryStage.show();

    canvas.addEventHandler(MouseEvent.MOUSE_PRESSED,
        new EventHandler<MouseEvent>(){

        @Override
        public void handle(MouseEvent event) {
            gc.beginPath();
            gc.moveTo(event.getX(), event.getY());
            gc.stroke();
        }
    });
    canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED,
        new EventHandler<MouseEvent>(){

        @Override
        public void handle(MouseEvent event) {
            gc.lineTo(event.getX(), event.getY());
            gc.stroke();
        }
    });


    //Networking
    try {
        socket = new Socket("localhost", 8000);
        byteIn = new ByteArrayInputStream(socket.getInputStream());
        byteOut = new ByteArrayOutputStream(socket.getOutputStream());
        new Thread(() -> run()).start();
    }
    catch (IOException ex) {
        ex.printStackTrace();
    }
  }

  public void run(){
     while(true) {
        /*try {

        } catch (IOException ex) {
            ex.printStackTrace();
        }*/
     }
  }

  public void process (Canvas canvas) {
     try {
        WritableImage image = canvas.snapshot(null, null);
        BufferedImage bImage = SwingFXUtils.fromFXImage(image, null);
        ImageIO.write(bImage, "jpg", byteOut);
        byteOut.flush();
        byte[] byteImage = byteOut.toByteArray();
        byteOut.close();
        byteOut.write(byteImage);
      } catch (IOException ex) {
          System.err.println(ex);
     }
  }

  public static void main(String[] args) {
    Application.launch(args);
  }

  private void initDraw(GraphicsContext gc) {
        double canvasWidth = gc.getCanvas().getWidth();
        double canvasHeight = gc.getCanvas().getHeight();

        //Event handler when set color button is clicked
        btSetColor.setOnAction(e -> {
            if(!(tfRed.getText().trim().isEmpty()) && !(tfGreen.getText().trim().isEmpty()) &&
                !(tfBlue.getText().trim().isEmpty())) {
                int red = Integer.parseInt(tfRed.getText());
                int green = Integer.parseInt(tfGreen.getText());
                int blue = Integer.parseInt(tfBlue.getText());
                gc.setStroke(Color.rgb(red, green, blue));
            }
        });

        gc.setLineWidth(5);
        gc.fill();
        gc.strokeRect(
            0,              //x of the upper left corner of the drawing area
            0,              //y of the upper left corner of the drawing area
            canvasWidth,    //width of the drawing area
            canvasHeight);  //height of the drawing area
        gc.setLineWidth(1);

        //Event handler when reset button is clicked
        btReset.setOnAction(e -> {
            gc.clearRect(5, 5, 355, 365);
        });
  }
}
import java.io.*;
导入java.net。*;
导入javafx.application.application;
导入javafx.event.EventHandler;
导入javafx.scene.input.MouseEvent;
导入javafx.scene.scene;
导入javafx.scene.control.Label;
导入javafx.scene.control.TextArea;
导入javafx.scene.control.TextField;
导入javafx.scene.control.Button;
导入javafx.scene.layout.BorderPane;
导入javafx.scene.layout.GridPane;
导入javafx.scene.canvas.canvas;
导入javafx.scene.canvas.GraphicsContext;
导入javafx.scene.paint.Color;
导入javafx.stage.stage;
导入java.awt.image.buffereImage;
导入java.io.File;
导入javafx.embed.swing.SwingFXUtils;
导入javafx.scene.image.*;
导入javax.imageio.imageio;
公共类客户端扩展应用程序{
//GUI组件
私有文本字段tfRed=新文本字段(“”);
私有文本字段tfGreen=新文本字段(“”);
私有文本字段tfBlue=新文本字段(“”);
私有按钮btSetColor=新按钮(“设置颜色”);
专用按钮btReset=新按钮(“重置”);
私人按钮btSend=新按钮(“发送”);
//网络组件
专用插座;
私有ByteArrayOutputStream字节输出;
拜特莱因普特斯特林·拜泰因私人酒店;
@凌驾
公共无效开始(阶段primaryStage){
tfRed.setPrefWidth(80);
tfGreen.setPrefWidth(80);
tfBlue.setPrefWidth(80);
GridPane GridPane=新建GridPane();
添加(新标签(“颜色”),0,0);
添加(tfRed,1,0);
添加(tfGreen,2,0);
添加(tfBlue,3,0);
添加(btSetColor,4,0);
添加(btReset,2,1);
添加(btSend,3,1);
画布=新画布(365375);
final GraphicsContext gc=canvas.getGraphicsContext2D();
initDraw(gc);
BorderPane bPane=新的BorderPane();
bPane.setTop(网格窗格);
设置中心(画布);
场景=新场景(bPane,375,450);
primaryStage.setTitle(“绘图画布”);
初级阶段。场景(场景);
primaryStage.show();
canvas.addEventHandler(MouseEvent.MOUSE_按下,
新的EventHandler(){
@凌驾
公共无效句柄(MouseeEvent事件){
gc.beginPath();
gc.moveTo(event.getX(),event.getY());
gc.stroke();
}
});
canvas.addEventHandler(MouseEvent.MOUSE_拖动,
新的EventHandler(){
@凌驾
公共无效句柄(MouseeEvent事件){
gc.lineTo(event.getX(),event.getY());
gc.stroke();
}
});
//联网
试一试{
套接字=新套接字(“localhost”,8000);
byteIn=newbytearrayinputstream(socket.getInputStream());
byteOut=newbytearrayoutputstream(socket.getOutputStream());
新线程(()->run()).start();
}
捕获(IOEX异常){
例如printStackTrace();
}
}
公开募捐{
while(true){
/*试一试{
}捕获(IOEX异常){
例如printStackTrace();
}*/
}
}
公共作废流程(画布){
试一试{
WritableImage image=canvas.snapshot(null,null);
BuffereImage bImage=SwingFXUtils.fromFXImage(图像,null);
ImageIO.write(双图像,“jpg”,字节输出);
byteOut.flush();
字节[]字节图像=字节输出。toByteArray();
byteOut.close();
byteOut.write(byteImage);
}捕获(IOEX异常){
系统错误打印项次(ex);
}
}
公共静态void main(字符串[]args){
应用程序启动(args);
}
私有void initDraw(GraphicsContext gc){
double canvasWidth=gc.getCanvas().getWidth();
double canvasHeight=gc.getCanvas().getHeight();
//单击“设置颜色”按钮时的事件处理程序
btSetColor.setOnAction(e->{
如果(!(tfRed.getText().trim().isEmpty())和(!(tfGreen.getText().trim().isEmpty())&&
!(tfBlue.getText().trim().isEmpty()){
int red=Integer.parseInt(tfRed.getText());
int green=Integer.parseInt(tfGreen.getText());
int blue=Integer.parseInt(tfBlue.getText());
gc.setStroke(Color.rgb(红、绿、蓝));
}
});
gc.设置线宽(5);
gc.fill();
气相色谱法(
0,//绘图区域左上角的x
0,//绘图区域左上角的y
画布宽度,//绘图区域的宽度
画布高度);//绘图区域的高度
gc.设置线宽(1);
//单击重置按钮时的事件处理程序
btReset.setOnAction(e->{
gc.clearRect(5,5355365);
});
}
}

无法直接发送
图形上下文
,因为
图形上下文
不可显式地
序列化
。下面给出了实现目标的典型方法

A.将用户操作记为“命令”,并将其发送到服务器/其他客户端。命令将在客户端执行,您将拥有相同的渲染视图。作为实现示例,您可以使用自己的API包装
GraphicsContext
API来创建这些命令

public void fillOvalX(double x, double y, double w, double h) {
    // a possible approach
    commands.put(new DrawCommand(Type.FILL_OVAL, x, y, w, h));
    g.fillOval(x, y, w, h);
}
B.通过调用将
图形上下文
快照到JavaFX
图像
。然后使用将其转换为
BufferedImage
,最后使用
byte[]
ByteArrayOutputStream
。然后可以通过网络对数组
字节[]
进行序列化。在连接的另一端,您需要以相反的顺序执行相同的操作。这些链接提供了足够的