2016-04-26 8 views
0

入力ストリームと出力ストリームに問題が発生しました。ソケット入力ストリームをbyte []に​​変換したり、ソケット出力ストリームをintに変換したりしません。どのようにプログラムが実際にサーバーにbyte []配列を送るのですか?ここで更新されたコードです:GraphicsContextが明示的にSerializableないようクライアントからサーバーへ、次に他のすべてのクライアントに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

* EDIT * ---他のクライアントがGraphicsContextに持つものにGraphicsContextを追加する必要はありません。GraphicsContextを他のものに置き換えるだけです。 – seeuuaye08

答えて

0

直接GraphicsContextを送信するには、可能ではありません。あなたの意図を達成する典型的な方法を以下に示します。

A.ユーザーの操作を「コマンド」として記憶し、サーバー/他のクライアントに送信します。コマンドはクライアント側で実行され、同じレンダリングビューを持ちます。実装例として、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()を呼び出すことにより、JavaFXのImageGraphicsContextのスナップショットを実行します。次にSwingFXUtilsを使用してBufferedImageに変換し、最後にImageIOByteArrayOutputStreamを使用してbyte[]に変換します。アレイbyte[]はネットワーク経由でシリアル化できます。接続の反対側では、同じ操作を逆の順序で実行する必要があります。リンクはそれを行うのに十分な情報を提供します。

+0

フィードバックに感謝します。私は最初にここに投稿した後、snapshot()とByteArrayStreamsを調べていました。私はすぐにこの試みをしよう。 – seeuuaye08

+0

私は今どこにいるのかを示すコードを編集しました。私が持っている問題は、編集に記載されています。 – seeuuaye08

関連する問題