2

私はswingを使用して複数のjavafxを表示しTableview、それぞれがswingに埋め込まれています(ありがとう JFXPanelTabbedPane

私は、oracle docで説明されているよく知られたパターンをscalaの方法で使用します:

implicit def fun2Run[T](x: ⇒ T) = new Runnable {
    def run = x
  }

  def myTabbedScene():Scene = {
    val root = new StackPane
    root.getChildren.add(new Label("Hello world!"))
    new Scene(root, 300, 300)
  }

  def initFxPanel(fxPanel: JFXPanel, s: ⇒ Scene) = {
    fxPanel.setScene(s)
  }

  def initSwingGui(panel: PluginPanel) = {
    val fxPanel = new JFXPanel()
   // code to add panel to JPanel
    panel.peer.add(fxPanel)
    Platform runLater initFxPanel(fxPanel,myTabbedScene())
  }

  val jfxSwingPanel = new PluginPanel("wrap 2") {
    var jtemp = new JPanel()
    contents += jtemp
  }

  SwingUtilities invokeLater initSwingGui(jfxSwingPanel)

このコードは、ユーザーが新しいスイングタブを開くたびに実行されます(シーンの方法のみが異なります)が、この場合、これがスレッドを管理するための最良の方法であるかどうかはわかりません:-/

タブを閉じたり開いたりすると、アプリケーションに一貫性のない状態が発生し、表示中にエラーが発生します。

私のユースケースの例と、いくつかの質問がリンクされています:

  • 最初のタブJ1を開くと、runlaterが呼び出され、シーンがタブに問題なく表示されます。

  • 2番目のタブJ2を開くと、javafxスレッドで新しいrunlaterが呼び出されます。

  • タブJ1に切り替えますが、タブの表示はどのように更新されますか?これを可能にするために、暗黙のrunnableアクションがメインスレッドに対して起動されますか?javafxはどのようにして更新するのに適したタブを認識しましたか?アクションを起動するボタンがある場合runlater()、ディスパッチするjavafxメインスレッドでアクションを起動しますか?

アップデート:

私はこの点で読者を助けることができるコードソースを見つけます、あなたはrevalidate()または/そしてrepaint()あなたを含むあなたのスイングパネル(ここ_contentpanejfxPanel

   SwingUtilities.invokeLater(new Runnable() { 
    public void run() { 
    _contentPane.add(_jfxPanel); 
    _contentPane.revalidate(); 
    _contentPane.repaint(); }});
  • 最初のタブJ1を閉じます。javafxは関連付けられているjavafxリソースを自動的に閉じます/ガベージしますか?

他にも一般的な質問が複数あります:

  • javafxアプリケーションのメインスレッドは、スイングで異なるjfxpanelから到着したときに、この複数のrunlater()呼び出しをどのように管理しますか?

  • ユーザーがタブを閉じるときに、jfxpanelに関連付けられているリソースを(exit()Platformメソッドでメインのjavafxスレッドを閉じることなく)適切に閉じるにはどうすればよいですか?JFXPanelを破棄すると、表示に使用されるjavafxリソースが解放されますか?

  • タスクを使用してスレッドを管理することは、私の問題に対する答えになる可能性がありますか?

私の質問はおそらく素朴ですが、私はGUIの構築から始め、javafxがさまざまな埋め込みパネルのシーンを管理する方法を理解するのに問題があります。

4

1 に答える 1

3

スイングで異なるjfxpanelから到着した場合、javafxアプリケーションスレッドはこの複数のrunlater()呼び出しをどのように管理しますか?

Platform.runLater javadocから:

将来の不特定の時間に、JavaFXアプリケーションスレッドで指定されたRunnableを実行します。このメソッドは、任意のスレッドから呼び出すことができ、Runnableをイベントキューにポストし、すぐに呼び出し元に戻ります。Runnablesは、投稿された順序で実行されます。runLaterメソッドに渡されたRunnableは、後続のrunLaterの呼び出しに渡されたRunnableの前に実行されます。

さらに遠く:

ユーザーがタブを閉じるときにjfxpanelを実行するスレッドを(メインのjavafxスレッドを閉じることなく)適切に閉じるにはどうすればよいですか?

参照しているスレッドが不明です。一般に、JavaFXとSwingを統合する場合、関係するスレッドはSwingディスパッチスレッドとJavaFXアプリケーションスレッドの2つだけです。どちらも、それぞれの基盤となるフレームワークによって管理される必要があり、明示的に閉じる必要はありません。これらのスレッドのいずれかで実行されるべきではない何か(CPUを大量に消費するタスクやリモートI / Oなど)を実行しようとしている場合を除いて、他のスレッドは必要ありません-サンプルコードからは表示されませんケースになります。

タスクを使用してスレッドを管理することは、私の問題に対する答えになる可能性がありますか?

あなたがそのようなことに対する特別な必要性を持っていない限り、そのような解決策はそれを改善するよりもあなたの状況をさらに複雑にするでしょう。

最初のタブJ1を閉じます。javafxは関連付けられているjavafxリソースを自動的に閉じます/ガベージしますか?

関連するjfxpanel内のリソースへの参照を保持しない場合、Java仮想マシンはjfxpanelとそれに関連するリソースをガベージコレクションできます。これは単なる標準のJavaガベージコレクションテクノロジーであり、ここでは特別なことは何もありません。

タブJ1に切り替えますが、タブの表示はどのように更新されますか?これを可能にするために、暗黙の実行可能アクションがメインスレッドに対して起動されますか?

悪い考えのように聞こえます(Java用語のメインスレッドは、Javaのメイン関数を起動するために使用されるスレッドであり、GUIプログラミングにはまったく関与していません)。Platform.runLater()JavaFXアプリケーションスレッドで実行されるように、を介して実行可能な更新要求を送信することをお勧めします。

javafxはどのようにして更新するのに適したタブを認識しましたか?

各スイングタブにはJavaFXJFXPanelがあり、各スイングタブはどのJFXPanelを持っているかを認識しているため、Platform.runLaterを呼び出して特定のパネルを更新するときに、使用するJFXPanelへの(最終)参照を渡します。概念を説明するために、言語を一切使用しない疑似コードを次に示します。

on swing tab change event
  final JFXPanel curPanel = tab.getJFXPanel()
  Platform.runLater() {
    // update curPanel here...
  }

アクションを起動するボタンがある場合、ディスパッチするjavafxメインスレッドでrunlater()アクションを起動しますか?

本質的に、ここではあなたが正しいと思います。いくつかの用語を明確にするために質問を書き直します。たとえば、それがスイングボタンであり、スイングボタンでアクションを実行すると、を呼び出してからPlatform.runLater、のコードを呼び出します。 runLater呼び出しは、最終的にJavaFXアプリケーションスレッドで実行されます。


その他の質問私はScalaに精通していないため、合理的な答えを提供することができません。

正直なところ、GUI構築を始めたばかりの場合、私の一方的なアドバイスは、ScalaではなくJavaを使用し、SwingまたはJavaFXのいずれかに固執することですが、GUI構築プロセスに本当に慣れるまで、すべてを混ぜ合わせないでください。統合中に遭遇する可能性のある罠や落とし穴が多すぎて、ほとんど支援できない可能性があります。

于 2013-01-21T22:28:33.257 に答える