だから私は学校のプロジェクトとしてボイド シミュレーション プログラムを書いています。私のプログラムは、他のグループと群がらないこれらのボイドの複数の異なるグループをサポートしています。それらはすべて、新しい部族が作成されたときにプログラムのメイン GUI に BoxPanel を追加することによって行う異なる設定を持ち、それらの BoxPanel には設定があります。グループ設定で新しいフレームを開くボタン。
これは、プログラムを起動して、コード内に事前定義された部族をすべて追加すると、完全に機能します。ここで、GUI の新しい部分を作成して、これらの Boid の新しいグループを作成し、シミュレーションの実行中にそれらを追加できるようにしました。ここで問題が発生します。
何らかの奇妙な理由で、適切な設定でシミュレーションにグループを正常に追加しますが、BoxPanels をメイン GUI に追加しません。シミュレーションの横にある設定バー全体が完全に消えます。私はこれをテストし、計算スレッドの先頭に部族を追加すると同じことを行うので、これは複数のスレッドとスイングの問題のようです。これを引き起こしているもの、またはこれを修正する方法はありますか? 私はこれに完全に困惑しています。
tl;dr: トライブを追加するための以下のコードは、スレッドを開始していないときは正常に機能しますが、スレッドの開始後に使用しようとすると、optionPanel が空に見えます。
メイン GUI に BoxPanels を追加するコードは次のとおりです。
def addTribe(tribe: Tribe) = {
tribeFrames += new TribeSettingFrame(tribe)
tribeBoxPanels += new TribeBoxPanel(tribe)
this.refcontents
}
private def refcontents = {
top.optionPanel.contents.clear()
top.optionPanel.contents += new BoxPanel(Orientation.Vertical) {
tribeBoxPanels.foreach(contents += _.tribeBoxPanel)
}
top.optionPanel.contents += new BoxPanel(Orientation.Horizontal) {
contents += top.addTribeButton
}
top.optionPanel.contents += new BoxPanel(Orientation.Horizontal) {
contents += top.vectorDebugButton
}
}
new Thread(BoidSimulation).start()
ああ、内容のサイズを印刷して本当に必要な内容を追加するかどうかをテストしましたが、すべてがうまく一致しますが、描画されません。
編集:いくつか掘り下げた後、実際にはスレッドからスイングを更新することのようです。多くの場所で SwingWorker の使用が提案されていますが、私が収集した情報から、それは継続的なシミュレーションであり、フレームごとに新しい SwingWorker を作成し続ける必要があるため、私のプログラムには適合しないと思います。
EDIT2:次のようにスレッドからメソッドを呼び出してみました:
SwingUtilities.invokeLater(new Runnable() {
override def run() {
GUI2D.addTribe(tribe)
}
});
違いはありませんでした。これは、TribeBoxPanel と TribeSettingFrame の使い方に問題があると思い始めています。これらは、必要な BoxPanel または Frame を返すメソッドを 1 つだけ含むオブジェクトです。この実装は悪いですか?もしそうなら、動的な BoxPanels と Frames を作成するより良い方法は何ですか?