JavaFX and JMonkey

Hi !

(I hope I am in the right cathegory, and sorry for my english, I’m french. )

After some research on the web, and on the forum.

I want to know if it’s possible to embed JME into a JavaFX Pane ? Or if a feature is planned for the project ?

I’ve found some codes and trying to integrate my jme render inside a JPanel and inside a SwingNode.
But nothing seems to works, (old posts)
I haven’t any render.

I share with you my actual work:

Code Main Class

`public class Main extends Application {

private FXMLLoader loader;
private Stage primaryStage;
private AnchorPane root;

private MineImationApp mineImationApp = new MineImationApp();
private MineImation mineImation = new MineImation();

@Override
public void start(Stage primaryStage) {
	this.primaryStage = primaryStage;
	this.primaryStage.setTitle("MineImation");
	try {
		this.mineImation.preInit(mineImationApp, loader, primaryStage);
		this.initializeOverview();
		this.mineImation.postInit(mineImationApp, loader, primaryStage);
		Scene scene = new Scene(this.root);
		this.primaryStage.setScene(scene);
		this.primaryStage.show();
	}
	catch (Exception e) {
		e.printStackTrace();
	}
}

/**
 * Shows the person overview inside the root layout.
 */
private void initializeOverview() {
	try {
		this.loader = new FXMLLoader();
		this.loader.setLocation(Main.class.getResource("/MineImationOverview.fxml"));
		this.root = (AnchorPane) this.loader.load();
	}
	catch (IOException e) {
		e.printStackTrace();
	}
}

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

}`

Code MineImation Class

`public class MineImation implements IApplication {

private JPanel renderPanel = new JPanel();

@Override
public void preInit(MineImationApp appIn, FXMLLoader loader, Stage primaryStage) {

	renderPanel.setBackground(Color.DARK_GRAY);

	primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
		public void handle(WindowEvent e) {
			appIn.stop(true);
		}
	});

	primaryStage.setOnHidden(new EventHandler<WindowEvent>() {
		public void handle(WindowEvent e) {
			appIn.enqueue(new Function<SimpleApplication, Boolean>() {
				public Boolean apply(SimpleApplication t) {
					t.loseFocus();
					return Boolean.valueOf(true);
				}
			});
		}
	});

	primaryStage.setOnShowing(new EventHandler<WindowEvent>() {
		public void handle(WindowEvent e) {
			appIn.enqueue(new Function<SimpleApplication, Boolean>() {
				public Boolean apply(SimpleApplication t) {
					t.gainFocus();
					return Boolean.valueOf(true);
				}
			});
		}
	});

	appIn.enqueue(new Function<SimpleApplication, Boolean>() {
		public Boolean apply(SimpleApplication t) {
			t.getStateManager().attach(new AppStateMain());
			t.getStateManager().attach(new ModifiedFlyCamAppState());
			t.getStateManager().attach(new ScreenshotAppState(OSHelper.getWorkingDirectory() + "/screenshots/", "mineimation-"));

			JmeCanvasContext ctx = (JmeCanvasContext) appIn.getContext();
			ctx.setSystemListener(appIn);

			renderPanel.add(ctx.getCanvas());

			return true;
		}
	});

}

@Override
public void init(MineImationApp appIn, FXMLLoader loader, Stage primaryStage) {}

@Override
public void postInit(MineImationApp appIn, FXMLLoader loader, Stage primaryStage) {
	final SwingNode swingNode = new SwingNode();
	BorderPane borderPane = (BorderPane) getComponent(loader, "borderPane_modelBuilder");

	swingNode.setContent(this.renderPanel);

	borderPane.setCenter(swingNode);
}

public Object getComponent(FXMLLoader loader, String keyIn) {
	return loader.getNamespace().get(keyIn);
}

}`

The IApplication interface if for preInit(), init() an postInit() states.

So, I don’t know if I made a bad code or if it’s just JME who doesn’t support JavaFX.
Thanks for help by advance !

you need this:

2 Likes

That’s ok, you are forgiven.

6 Likes

Okay, I’ve tried the SaBr’s solution, but it’s too laggy.
And I don’t know why.
So I’m going to abandon this idea.

Thanks anyway !

1 Like

could you provide more details, please? for example, could you provide a short video of this problem, please?

Of course !

Console output for my computer configuration:

oct. 01, 2018 4:54:50 PM javafx.fxml.FXMLLoader$ValueElement processValue
AVERTISSEMENT: Loading FXML document with JavaFX API of version 10.0.1 by JavaFX runtime of version 8.0.151
oct. 01, 2018 4:54:53 PM com.jme3.system.JmeDesktopSystem initialize
INFOS: Running on jMonkeyEngine 3.2-stable
** * Branch: HEAD**
** * Git Hash: f85624a**
** * Build Date: 2018-01-21**
oct. 01, 2018 4:54:56 PM com.jme3.system.lwjgl.LwjglContext printContextInitInfo
INFOS: LWJGL 2.9.3 context running on thread jME3 Main
** * Graphics Adapter: C:\WINDOWS\System32\DriverStore\FileRepository\nv_dispi.inf_amd64_f5be1f8d25335236\nvldumdx.dll,C:\WINDOWS\System32\DriverStore\FileRepository\nv_dispi.inf_amd64_f5be1f8d25335236\nvldumdx.dll,C:\WINDOWS\System32\DriverStore\FileRepository\nv_dispi.inf_amd64_f5be1f8d25335236\nvldumdx.dll,C:\WINDOWS\System32\DriverStore\FileRepository\nv_dispi.inf_amd64_f5be1f8d25335236\nvldumdx.dll**
** * Driver Version: null**
** * Scaling Factor: 1**
oct. 01, 2018 4:54:56 PM com.jme3.renderer.opengl.GLRenderer loadCapabilitiesCommon
INFOS: OpenGL Renderer Information
** * Vendor: NVIDIA Corporation**
** * Renderer: GeForce GTX 1080 Ti/PCIe/SSE2**
** * OpenGL Version: 3.2.0 NVIDIA 399.07**
** * GLSL Version: 1.50 NVIDIA via Cg compiler**
** * Profile: Core**
oct. 01, 2018 4:54:56 PM com.jme3.asset.AssetConfig loadText
AVERTISSEMENT: Cannot find loader com.jme3.scene.plugins.blender.BlenderModelLoader
oct. 01, 2018 4:54:56 PM com.jme3.asset.AssetConfig loadText
AVERTISSEMENT: Cannot find loader com.jme3.audio.plugins.OGGLoader

The Video

https://youtu.be/Bg7y-PTqFs0

1 Like

Could you provide your part of code which integrates jME to JavaFX? Is your application pure javaFX or you have some swing components?

Well that’s a shame… I hope ZeAmateis isn’t giving up here so easily. Not going to be possible for javasabr to fix potential issues if he doesn’t know what’s causing them… (assuming it’s the actual cause). :face_with_raised_eyebrow:

Yes, sorry to answer you late.

Summary
/**
 * The test to show how to integrate jME to Canvas.
 *
 * @author JavaSaBr
 */
public class TestJmeToJfxCanvas extends Application {

	private FXMLLoader loader;
	private Stage primaryStage;
	private AnchorPane root;
	public static JmeToJFXApplication application;

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

	@Override
	public void start(Stage stage) {
		this.primaryStage = stage;

		try {
			this.loader = new FXMLLoader();
			this.loader.setLocation(Main.class.getResource("/MineImationOverview.fxml"));
			this.root = (AnchorPane) this.loader.load();
		}
		catch (IOException e) {
			e.printStackTrace();
		}

		Canvas canvas = (Canvas) this.getComponent(this.loader, "renderPanel_Canvas");
		canvas.setFocusTraversable(true);
		canvas.setOnMouseClicked(event -> canvas.requestFocus());

		Scene scene = new Scene(this.root);

		// canvas.widthProperty().bind(stackPane.widthProperty());
		// canvas.heightProperty().bind(stackPane.heightProperty());

		stage.setTitle("Test");
		stage.setScene(scene);
		stage.show();
		stage.setOnCloseRequest(event -> System.exit(0));

		application = makeJmeApplication();

		// integrate jME application with Canvas
		JmeToJFXIntegrator.startAndBindMainViewPort(application, canvas, Thread::new);
	}

	public Object getComponent(FXMLLoader loader, String keyIn) {
		return loader.getNamespace().get(keyIn);
	}

	private JmeToJFXApplication makeJmeApplication() {

		AppSettings settings = new AppSettings(true);

		GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
		DisplayMode[] modes = device.getDisplayModes();

		settings.setGammaCorrection(true);

		if (Main.getConfig().getBoolean("use_anti-aliasing")) {
			settings.setDepthBits(Main.getConfig().getInt("bits_depth"));
			settings.setStencilBits(Main.getConfig().getInt("stencil_bits"));
			settings.setSamples(4);
		}

		settings.setFrequency(modes[0].getRefreshRate());
		settings.setBitsPerPixel(modes[0].getBitDepth());
		settings.setUseInput(true);
		settings.setFullscreen(false);
		settings.setFrameRate(Main.getConfig().getInt("framerate"));
		settings.setVSync(Main.getConfig().getBoolean("use_vsync"));
		settings.setCustomRenderer(JmeOffscreenSurfaceContext.class);
		settings.setAudioRenderer(null);

		JmeToJFXApplication application = new JmeToJFXApplication() {
			@Override
			public void simpleInitApp() {
				super.simpleInitApp();
				getStateManager().detach(getStateManager().getState(FlyCamAppState.class));
				getStateManager().detach(getStateManager().getState(DebugKeysAppState.class));

				getStateManager().attach(new AppStateMain());
				getStateManager().attach(new ModifiedFlyCamAppState());
				getStateManager().attach(new ScreenshotAppState(OSHelper.getWorkingDirectory() + "/screenshots/", "mineimation-"));
			}
		};
		application.setSettings(settings);
		application.setShowSettings(false);

		return application;
	}

}```

ImageView is better option than Canvas for integration, but it still looks like good, could you make a short video about your laggy issue?