2016-04-26 173 views
0

我现在遇到输入和输出流的问题。它不会将套接字输入流转换为byte []或将套接字输出流转换为int。如何让程序实际发送byte []数组到服务器?下面是更新后的代码:如何将GraphicsContext从客户端发送到服务器,然后发送到所有其他客户端?

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

*编辑* ---我不需要将GraphicsContext添加到任何其他客户端的GraphicsContexts中,只需要将GraphicsContext替换为其他类型。 – seeuuaye08

回答

0

直接发送GraphicsContext是不可能的,因为GraphicsContext是没有明确Serializable。下面给出了实现你打算的典型方法。答:请记住用户操作为“命令”并将它们发送给服务器/其他客户端。这些命令将在客户端执行,并且您将拥有相同的呈现视图。作为实现的例子,您可以用您自己的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.通过调用snapshot()执行GraphicsContext的快照到一个JavaFX Image。然后使用SwingFXUtils将其转换为BufferedImage,最后使用ImageIOByteArrayOutputStream将其转换为byte[]。然后可以通过网络将数组byte[]序列化。在连接的另一端,您需要按相反的顺序执行相同的操作。这些链接提供了足够的信息来做到这一点。

+0

非常感谢您的反馈。在我最初在这里发布后,我正在研究snapshot()和ByteArrayStreams。我会很快尝试。 – seeuuaye08

+0

我编辑了代码以显示现在卡在哪里。编辑中说明了我的问题。 – seeuuaye08

相关问题