0

i want to run the javaFX class (MainApp.java) contains a googlemap using GMapsFX library (http://rterp.github.io/GMapsFX/) from java swing app.

It runs after click on menu item in jframe - executes MainApp.main(args);

The map starts but freezes the rest of the application

How i can run this class to prevent the freeze?

Below it's MainApp.java class

package com.lynden.gmapsexampleapp;

import com.lynden.gmapsfx.GoogleMapView;
import com.lynden.gmapsfx.MapComponentInitializedListener;
import com.lynden.gmapsfx.javascript.object.GoogleMap;
import com.lynden.gmapsfx.javascript.object.LatLong;
import com.lynden.gmapsfx.javascript.object.MapOptions;
import com.lynden.gmapsfx.javascript.object.MapType;
import com.lynden.gmapsfx.javascript.object.Marker;
import com.lynden.gmapsfx.javascript.object.MarkerOptions;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Scene;
import javafx.stage.Stage;


public class MainApp extends Application implements MapComponentInitializedListener {

GoogleMapView mapView;
GoogleMap map;

@Override
public void start(Stage stage) throws Exception {

    //Create the JavaFX component and set this as a listener so we know when 
    //the map has been initialized, at which point we can then begin manipulating it.
    mapView = new GoogleMapView();
    mapView.addMapInializedListener(this);

    Scene scene = new Scene(mapView);

    stage.setTitle("JavaFX and Google Maps");
    stage.setScene(scene);
    stage.show();
}


@Override
public void mapInitialized() {
    //Set the initial properties of the map.
    MapOptions mapOptions = new MapOptions();

    mapOptions.center(new LatLong(47.6097, -122.3331))
            .mapType(MapType.ROADMAP)
            .overviewMapControl(false)
            .panControl(false)
            .rotateControl(false)
            .scaleControl(false)
            .streetViewControl(false)
            .zoomControl(false)
            .zoom(12);

    map = mapView.createMap(mapOptions);

    //Add a marker to the map
    MarkerOptions markerOptions = new MarkerOptions();

    markerOptions.position( new LatLong(47.6, -122.3) )
                .visible(Boolean.TRUE)
                .title("My Marker");

    Marker marker = new Marker( markerOptions );

    map.addMarker(marker);

}

public static void main(String[] args) {
    launch(args);
}
}

I have no idea how to nest the whole class in JavaFX thread. I have something like this:

public class NewFXSwingMain extends JApplet {

private static final int JFXPANEL_WIDTH_INT = 300;
private static final int JFXPANEL_HEIGHT_INT = 250;
private static JFXPanel fxContainer;

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            try {
                UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
            } catch (Exception e) {
            }

            JFrame frame = new JFrame("JavaFX 2 in Swing");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            JApplet applet = new NewFXSwingMain();
            applet.init();

            frame.setContentPane(applet.getContentPane());

            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);

            applet.start();
        }
    });
}

@Override
public void init() {
    fxContainer = new JFXPanel();
    fxContainer.setPreferredSize(new Dimension(JFXPANEL_WIDTH_INT, JFXPANEL_HEIGHT_INT));
    add(fxContainer, BorderLayout.CENTER);
    // create JavaFX scene
    Platform.runLater(new Runnable() {

        @Override
        public void run() {
            createScene();
        }
    });
}

private void createScene() {
    Button btn = new Button();
    btn.setText("Say 'Hello World'");
    btn.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Hello World!");
        }
    });
    StackPane root = new StackPane();
    root.getChildren().add(btn);
    fxContainer.setScene(new Scene(root));
}    
}

And now what?

kowalptk
  • 9
  • 3

2 Answers2

1

You cannot launch a JavaFX Application from Swing.

The reason is that JavaFX is tightly tied into your system, it uses threads for OpenGL access and includes a lot of native code for performance.

The proper solution is to open a swing window, and embed a JavaFX widget there.

For more details on JavaFX and Swing, see:

http://docs.oracle.com/javase/8/javafx/interoperability-tutorial/swing-fx-interoperability.htm#CHDIEEJE

To embed JavaFX into Swing, use javafx.embed.swing.JFXPanel.

Has QUIT--Anony-Mousse
  • 76,138
  • 12
  • 138
  • 194
0

In the hope of helping others who have this problem:

import com.lynden.gmapsfx.GoogleMapView;
import com.lynden.gmapsfx.javascript.object.GoogleMap;
import com.lynden.gmapsfx.javascript.object.LatLong;
import com.lynden.gmapsfx.javascript.object.MapOptions;
import com.lynden.gmapsfx.javascript.object.MapTypeIdEnum;
import java.awt.Dimension;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javax.swing.JFrame;

public class SwingGoogleMaps {

    private final JFrame frame;
    private final JFXPanel jfxPanel;
    private Scene scene;
    private GoogleMapView mapComponent;
    private GoogleMap map;

    public SwingGoogleMaps() {

        frame = new JFrame("Hello Swing GMapsFX");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        jfxPanel = new JFXPanel();
        jfxPanel.setPreferredSize(new Dimension(600, 600));

        Platform.runLater(() -> {
            mapComponent = new GoogleMapView();
            mapComponent.addMapInializedListener(() -> {

                LatLong center = new LatLong(-25.343924, 131.033114);

                MapOptions options = new MapOptions()
                        .center(center)
                        .mapMarker(true)
                        .zoom(12)
                        .overviewMapControl(false)
                        .panControl(false)
                        .rotateControl(false)
                        .scaleControl(false)
                        .streetViewControl(false)
                        .zoomControl(false)
                        .mapType(MapTypeIdEnum.SATELLITE);

                map = mapComponent.createMap(options);

            });

            mapComponent.setPrefSize(600, 600);
            scene = new Scene(mapComponent);

            jfxPanel.setScene(scene);
        });

        frame.getContentPane().add(jfxPanel);
        frame.pack();
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(() -> {
            new SwingGoogleMaps();
        });
    }

}
Geoff
  • 568
  • 4
  • 11