3.1-alpha1 With the swing Canvas Are not compatible

Just tested with the TestAwtPanels and it works

package jme3test.awt;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.*;
import com.jme3.scene.Geometry;
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.concurrent.CountDownLatch;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class TestAwtPanels extends SimpleApplication {

    final private static CountDownLatch panelsAreReady = new CountDownLatch(1);
    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(){
                /*
                 * Sleep 2 seconds to ensure there's no race condition.
                 * The sleep is not required for correctness.
                 */
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException exception) {
                    return;
                }

                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);
                /*
                 * Both panels are ready.
                 */
                panelsAreReady.countDown();
            }
        });
    }
    
    @Override
    public void simpleInitApp() {
        flyCam.setDragToRotate(true);
        
        Box b = new Box(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);
        rootNode.attachChild(geom);
        /*
         * Wait until both AWT panels are ready.
         */
        try {
            panelsAreReady.await();
        } catch (InterruptedException exception) {
            throw new RuntimeException("Interrupted while waiting for panels", exception);
        }

        FilterPostProcessor filterPostProcessor = new FilterPostProcessor(assetManager);
        BloomFilter bloom = new BloomFilter(BloomFilter.GlowMode.Scene);
        bloom.setBloomIntensity(5);
        bloom.setBlurScale(2);
        filterPostProcessor.addFilter(bloom);
        viewPort.addProcessor(filterPostProcessor);

        panel.attachTo(true, viewPort);
        guiViewPort.setClearFlags(true, true, true);
        panel2.attachTo(false, guiViewPort);
    }
}

Could you test this? maybe it’s a more a hardware/driver issue?

1 Like

Nope it’s still broken. The problem is when you create your own ViewPort … Basically the only reason why you would want AWTPanel is to have multiple panels in one swing app. Here is a modified version of the test code with a third panel created. Run it and watch it blow up :slight_smile:

package jme3test.awt;

import com.jme3.app.SimpleApplication;
import com.jme3.input.FlyByCamera;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.BloomFilter;
import com.jme3.renderer.Camera;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
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.concurrent.CountDownLatch;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class TestAwtPanels extends SimpleApplication {

    final private static CountDownLatch panelsAreReady = new CountDownLatch(1);
    private static TestAwtPanels app;
    private static AwtPanel panel, panel2, panel3;
    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 == 3) {
                    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() {
                /*
                 * Sleep 2 seconds to ensure there's no race condition.
                 * The sleep is not required for correctness.
                 */
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException exception) {
                    return;
                }

                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));
                panel3 = ctx.createPanel(PaintMode.Accelerated);
                panel3.setPreferredSize(new Dimension(400, 300));

                createWindowForPanel(panel, 300);
                createWindowForPanel(panel2, 700);
                createWindowForPanel(panel3, 1100);
                /*
                 * Both panels are ready.
                 */
                panelsAreReady.countDown();
            }
        });
    }

    @Override
    public void simpleInitApp() {
        flyCam.setDragToRotate(true);

        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);
        rootNode.attachChild(geom);
        /*
         * Wait until both AWT panels are ready.
         */
        try {
            panelsAreReady.await();
        } catch (InterruptedException exception) {
            throw new RuntimeException("Interrupted while waiting for panels", exception);
        }
        

        Camera newCamera = new Camera(getCamera().getWidth(),
                getCamera().getHeight());
        newCamera.copyFrom(getCamera());
        newCamera.setFrustumPerspective(35, 400f / 300f, .1f, 5000f);
        FlyByCamera newFlyCamera = new FlyByCamera(newCamera);
        newFlyCamera.setMoveSpeed(5);
        newFlyCamera.registerWithInput(getInputManager());
        newFlyCamera.setDragToRotate(true);
        newFlyCamera.setEnabled(false);
        FilterPostProcessor filterPostProcessor = new FilterPostProcessor(assetManager);
        BloomFilter bloom = new BloomFilter(BloomFilter.GlowMode.Scene);
        bloom.setBloomIntensity(5);
        bloom.setBlurScale(2);
        filterPostProcessor.addFilter(bloom);
        
        
        ViewPort newViewPort = getRenderManager()
                .createMainView("testViewPort", newCamera);
        newViewPort.setClearFlags(true, true, true);
        newViewPort.attachScene(rootNode);
        newViewPort.addProcessor(filterPostProcessor);

        
        panel.attachTo(true, viewPort);
        guiViewPort.setClearFlags(true, true, true);
        panel2.attachTo(false, guiViewPort);
        panel3.attachTo(false, newViewPort);
    }
}

So is the sdk he only need the main viewport and that’s it so he gets around the bug by not creating multiple panels.

OK, indeed, there is only one Panel in the SDK.