3

シナリオ: トップレベルのコンテナーは、ボタンの破棄をトリガーする fx ボタンを含む、いくつかの fx コンテンツを持つ Swing JDialog です。ボタンが作成され、適切な eventHandler で手動で構成されている場合、破棄は期待どおりに機能します (ダイアログは非表示になります)。ボタンが fxml を介して作成/構成されている場合、ダイアログは破棄されません。以下の例には、手動で構成されたボタンと fxml のロード/バインドされたボタンの両方が含まれており、異なる動作を確認できます。

質問:

  • 例に何か問題がありますか?
  • 期待されるswing/fxの相互作用に違いはありますか(手動とfxml)?
  • fxmlから動作させるには?

コード:

package fxml;

import java.io.IOException;

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.FlowPane;

import javax.swing.JDialog;
import javax.swing.SwingUtilities;

public class DisposeExample {
    @FXML
    Button closeButton;

    Button fxButton;

    private JDialog dialog;

    /**
     * The action handler method used by fx buttons.
     */
    public void onAction(final ActionEvent ac) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                System.out.println("onAction: " +ac);
                dialog.dispose();
            }
        });
    }

    protected Button createFxButton() {
        Button fxButton = new Button("close from fx");
        fxButton.setOnAction(new javafx.event.EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                onAction(event);
            }
        });
        return fxButton;
    }

    public void initFX() {
        final JFXPanel fxPanel = new JFXPanel();
        dialog.add(fxPanel);

        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                FlowPane parent = null;
                try {
                    parent = FXMLLoader.load(DisposeExample.class.getResource(
                            "DisposeController.fxml"));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                fxButton = createFxButton();
                parent.getChildren().add(fxButton);
                Scene scene = new Scene(parent);
                fxPanel.setScene(scene);
            }
        });
    }

    public DisposeExample() {
        dialog = new JDialog();
        dialog.setTitle("Simple Swing Dialog");
        initFX();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JDialog example = new DisposeExample().dialog;
                example.setSize(400, 400);
                example.setVisible(true);
            }
        });
    }
}

fxml コンテンツ:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<FlowPane id="Content" fx:id="windowPanel" 
    xmlns:fx="http://javafx.com/fxml" fx:controller="fxml.DisposeExample">
    <children>
        <Button fx:id="closeButton" onAction="#onAction" 
            prefHeight="35.0" prefWidth="300.0" text="Close (fxml controller)">
        </Button>
    </children>
</FlowPane>

ところで:今年の初めから、未回答の同様の質問があります。

編集

何か奇妙なことが起こっています: 数分間実行した後、OutOfMemoryError がスローされます - より深い何かが作成を停止しません..何?

java.lang.OutOfMemoryError: Java heap space
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2521)
at java.lang.Class.privateGetPublicMethods(Class.java:2641)
at java.lang.Class.privateGetPublicMethods(Class.java:2657)
at java.lang.Class.privateGetPublicMethods(Class.java:2657)
at java.lang.Class.privateGetPublicMethods(Class.java:2657)
at java.lang.Class.privateGetPublicMethods(Class.java:2657)
at java.lang.Class.privateGetPublicMethods(Class.java:2657)
at java.lang.Class.getMethods(Class.java:1457)
at sun.reflect.misc.MethodUtil.getMethods(MethodUtil.java:99)
at com.sun.javafx.fxml.BeanAdapter.updateMethodCache(BeanAdapter.java:265)
at com.sun.javafx.fxml.BeanAdapter.setBean(BeanAdapter.java:250)
at com.sun.javafx.fxml.BeanAdapter.<init>(BeanAdapter.java:213)
at javafx.fxml.FXMLLoader$Element.getValueAdapter(FXMLLoader.java:157)
at javafx.fxml.FXMLLoader$Element.getProperties(FXMLLoader.java:165)
at javafx.fxml.FXMLLoader$ValueElement.processValue(FXMLLoader.java:647)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:570)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2314)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2131)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2028)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2744)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2723)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2709)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2696)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2685)
at fxml.DisposeExample$3.run(DisposeExample.java:65)
at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:179)
at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:176)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:176)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)

編集

fyi: 8u113 と同じ動作なので、fx-jira に問題を報告しました。私は不治の楽観主義者です :-)

4

3 に答える 3

2

バグ警告 - FXML ファイルからコントローラを削除し、代わりにコードに設定してください。

FXMLLoader fxmlLoader = new FXMLLoader(DisposeExample.class.getResource("DisposeController.fxml"));
fxmlLoader.setController(DisposeExample.this);
parent = (FlowPane)fxmlLoader.load();

残念ながら、これはこれらの寒い日に FX-CPU の加熱も破壊します ;-)

于 2013-11-10T17:25:03.533 に答える