On this forum, it seems like the most commonly-cited solution to those who want to run multiple views of jME3 in separate windows is to use the AwtPanel class. I see a lot of references to the TestAwtPanels.java code in the repository to provide guidance.
Fair enough. When I download and run this file, here’s what I see:
This is a step in the right direction, but I want two separate windows, each with its own view. So, based on extensive research (Googling, source code, browsing around the forum), I modify the TestAwtClass like so:
[java]import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import com.jme3.system.AppSettings;
import com.jme3.system.awt.AwtPanel;
import com.jme3.system.awt.AwtPanelsContext;
import com.jme3.system.awt.PaintMode;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class TestAwtPanels extends SimpleApplication {
private static TestAwtPanels app;
private static AwtPanel panel, panel2;
private static int panelsClosed = 0;
private static void createWindowForPanel(AwtPanel panel, int location){
JFrame frame = new JFrame("Render Display " + location);
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(panel, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
if (++panelsClosed == 2){
app.stop();
}
}
});
frame.pack();
frame.setLocation(location, Toolkit.getDefaultToolkit().getScreenSize().height - 400);
frame.setVisible(true);
}
public static void main(String[] args){
Logger.getLogger("com.jme3").setLevel(Level.WARNING);
app = new TestAwtPanels();
app.setShowSettings(false);
AppSettings settings = new AppSettings(true);
settings.setCustomRenderer(AwtPanelsContext.class);
settings.setFrameRate(60);
app.setSettings(settings);
app.start();
SwingUtilities.invokeLater(new Runnable(){
public void run(){
final AwtPanelsContext ctx = (AwtPanelsContext) app.getContext();
panel = ctx.createPanel(PaintMode.Accelerated);
panel.setPreferredSize(new Dimension(400, 300));
ctx.setInputSource(panel);
panel2 = ctx.createPanel(PaintMode.Accelerated);
panel2.setPreferredSize(new Dimension(400, 300));
createWindowForPanel(panel, 300);
createWindowForPanel(panel2, 700);
}
});
}
@Override
public void simpleInitApp() {
flyCam.setDragToRotate(true);
Node node1 = new Node("View 1");
Node node2 = new Node("View 2");
Box b = new Box(Vector3f.ZERO, 1, 1, 1);
Geometry geom = new Geometry("Box", b);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
geom.setMaterial(mat);
Box b2 = new Box(Vector3f.ZERO, 1, 1, 1);
Geometry geom2 = new Geometry("Box", b2);
Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat2.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
geom2.setMaterial(mat2);
rootNode.attachChild(geom2);
rootNode.attachChild(geom);
Camera cam1 = cam.clone();
ViewPort view1 = renderManager.createMainView("view1", cam1);
view1.attachScene(node1);
panel.attachTo(true, view1);
Camera cam2 = cam.clone();
ViewPort view2 = renderManager.createMainView("view1", cam2);
view2.attachScene(node2);
panel2.attachTo(false, view2);
node1.updateLogicalState(speed);
node1.updateGeometricState();
node2.updateLogicalState(speed);
node2.updateGeometricState();
//panel.attachTo(true, viewPort);
// guiViewPort.setClearFlags(true, true, true);
//panel2.attachTo(false, guiViewPort);
}
}[/java]
and this is the result:
Still not quite right. On this thread on using multiple 3D views, someone else claimed to run similar code that produces two windows, one with red boxes and one with blue boxes. I copied the code over and made the corrections the responders suggested (i.e. make one of the attachTo calls use a “false” parameter):
[java] import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import com.jme3.system.AppSettings;
import com.jme3.system.awt.AwtPanel;
import com.jme3.system.awt.AwtPanelsContext;
import com.jme3.system.awt.PaintMode;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class MultipleViews extends SimpleApplication {
private static MultipleViews app;
private static AwtPanel panel1, panel2;
private static int panelsClosed = 0;
private static AwtPanelsContext ctx;
private static void createWindowForPanel(final AwtPanel panel, final int location)
{
JFrame frame = new JFrame("Render Display " + location);
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(panel, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
if (++panelsClosed == 2){
app.stop();
}
}
public void windowActivated(WindowEvent e) {
System.out.println(location + " activated");
ctx.setInputSource(panel);
}
});
frame.pack();
//frame.setLocation(location, Toolkit.getDefaultToolkit().getScreenSize().height - 900);
frame.setLocation(location, 100);
Window window = SwingUtilities.getWindowAncestor(frame);
if (window != null) window.revalidate();
frame.setVisible(true);
}
public static void main(String[] args){
app = new MultipleViews();
app.setShowSettings(false);
AppSettings settings = new AppSettings(true);
settings.setCustomRenderer(AwtPanelsContext.class);
settings.setFrameRate(60);
app.setSettings(settings);
app.start();
ctx = (AwtPanelsContext) app.getContext();
SwingUtilities.invokeLater(new Runnable(){
public void run()
{
panel1 = ctx.createPanel(PaintMode.Accelerated);
panel1.setPreferredSize(new Dimension(400, 300));
panel2 = ctx.createPanel(PaintMode.Accelerated);
panel2.setPreferredSize(new Dimension(400, 300));
ctx.setInputSource(panel1);
createWindowForPanel(panel1, 100);
createWindowForPanel(panel2, 500);
}
});
}
@Override
public void simpleInitApp()
{
Node rootNodeView1 = new Node(“rootNode View 1”);
Node rootNodeView2 = new Node(“rootNode View 2”);
rootNode.attachChild(rootNodeView1);
rootNode.attachChild(rootNodeView2);
flyCam.setDragToRotate(true);
flyCam.setMoveSpeed(100f);
Box b = new Box(Vector3f.ZERO, 1, 1, 1);
Geometry geom1 = new Geometry("Box1", b);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Blue);
geom1.setMaterial(mat);
rootNodeView1.attachChild(geom1);
Box b2 = new Box(new Vector3f(5, 0, 0), 1, 1, 1);
Geometry geom2 = new Geometry("Box2", b2);
Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat2.setColor("Color", ColorRGBA.Red);
geom2.setMaterial(mat2);
rootNodeView2.attachChild(geom2);
Camera cam1 = cam.clone();
ViewPort vp1 = renderManager.createMainView("view1", cam1);
//vp1.setClearFlags(true, true, true);
vp1.attachScene(rootNodeView1);
panel1.attachTo(false, vp1);
Camera cam2 = cam.clone();
ViewPort vp2 = renderManager.createMainView("view2", cam2);
//vp2.setClearFlags(true, true, true);
vp2.attachScene(rootNodeView2);
panel2.attachTo(true, vp2);
rootNodeView1.updateLogicalState(speed);
rootNodeView1.updateGeometricState();
rootNodeView2.updateLogicalState(speed);
rootNodeView2.updateGeometricState();
}
}
[/java]
and I still get everything in one window:
I’m completely stuck. How do I use AwtPanels to create two views in two separate windows? I would appreciate any help you can give. Thanks in advance!