はてぃーぽったーの備忘録

某授業まとめ+競プロの感想記事

javafx+sceneBuilderでハマったこととソケット通信でハマったこと

今回私は某大学の某実験において五目並べGUIアプリを作成しました。一月半という長い間格闘していたわけですが、その中でドツボにハマって時間を溶かした事案を書き連ねていきます。

 

①ObjectInputStreamのインスタンスはObjectOutputStreamのインスタンスを生成した後に生成する

https://stackoverflow.com/questions/14110986/new-objectinputstream-blocks

これはstackoverflowで原因を見つけました。これを見つけ出すのに1日溶けました。南無。原因としてはリンク先に書いてある通りなんですが、ざっくり言うと

・ObjectInputStreamはインスタンス化の際にInputStream(相手側から見たOutputStream)のヘッダ情報を読み取ろうとする

・ObjectOutputStreamを先に生成しないとそのヘッダ情報得るまで待ち続ける

これによりプログラムの実行が止まります。new ObjectInputStream(socket.getInputStream());の前でプログラム止まるんだけど…な人はこれを疑ってみてください。

PrintWriter, BufferedStreamReaderを使う以上はこれは起きないのかも?自分の場合はCUIで原型を作った際にint型配列のオブジェクトの授受をしたかったためObjectOutputStream / ObjectInputStreamを使いましたが, GUI作成の際はあまり必要としなかったので,ここで詰まる人はそんなに多くないのかも。

②コントローラクラスの外側からコントローラクラス内部のメソッドを呼び出してGUI画面に変更を加えようとしても失敗する

これは仕様みたいです。安全性が云々。解決策はPlatform.runLaterでググると出てきます。

③workerスレッド(プログラムのメインな処理を行うスレッド)とapplicationスレッドをちゃんと分けてるはずなのにずっとworkerスレッドに制御が行って画面が操作できない

メインな処理が一度きりならjavafx.concurrent.Task、複数回やるならjavafx.concurrent.Serviceを使いましょう。

④コントローラ内のメソッドってどう呼び出したらいいんだろう

SceneManager(シーン遷移の監督役)内に各シーンのコントローラのインスタンスを保持しておいて、そこにアクセスすればいいかと。

思い出し次第追記していきます。