I’m running the jme3test.awt.TestCanvas example with the JOGL renderer, and the app crashes with the following output when one of the following “Canvas Torture Methods” are used:
- “Remove Canvas”
- “Switch to tab #2”
- “Stop/Start Canvas”
It appears the JOGL canvas does not like being re-parented.
finishLifecycleAction(com.jogamp.opengl.util.Animator$3): ++++++ timeout reached ++++++ main-Display-.windows_nil-1-EDT-1
finishLifecycleAction(com.jogamp.opengl.util.Animator$3): OK false- pollPeriod 1000, blocking true -> res false, waited 1000/1000 - main-Display-.windows_nil-1-EDT-1
- com.jogamp.opengl.util.Animator[started true, animating true, paused true, drawable 1, totals[dt 0, frames 0, fps 0.0], modeBits 1, init'ed true, animThread Thread[AWT-EventQueue-0-AWTAnimator#00,6,main], exclCtxThread false(null)]
[2]: com.jogamp.opengl.util.AnimatorBase.finishLifecycleAction(AnimatorBase.java:633)
[3]: com.jogamp.opengl.util.Animator.pause(Animator.java:332)
[4]: com.jogamp.newt.opengl.GLWindow$GLLifecycleHook.pauseRenderingAction(GLWindow.java:696)
[5]: jogamp.newt.WindowImpl$ReparentAction.run(WindowImpl.java:1585)
[6]: com.jogamp.common.util.RunnableTask.run(RunnableTask.java:145)
[7]: jogamp.newt.DefaultEDTUtil$NEDT.run(DefaultEDTUtil.java:375)
Exception in thread "AWT-EventQueue-0" java.lang.RuntimeException: java.lang.RuntimeException: Waited 5000ms for: <5a1698f1, 193246c>[count 2, qsz 0, owner <AWT-EventQueue-0-AWTAnimator#00>] - <main-Display-.windows_nil-1-EDT-1>
at jogamp.newt.DefaultEDTUtil.invokeImpl(DefaultEDTUtil.java:252)
at jogamp.newt.DefaultEDTUtil.invoke(DefaultEDTUtil.java:165)
at jogamp.newt.DisplayImpl.runOnEDTIfAvail(DisplayImpl.java:442)
at jogamp.newt.WindowImpl.runOnEDTIfAvail(WindowImpl.java:2782)
at jogamp.newt.WindowImpl.reparentWindow(WindowImpl.java:1920)
at com.jogamp.newt.opengl.GLWindow.reparentWindow(GLWindow.java:545)
at com.jogamp.newt.awt.NewtCanvasAWT.detachNewtChild(NewtCanvasAWT.java:1101)
at com.jogamp.newt.awt.NewtCanvasAWT.destroyImpl(NewtCanvasAWT.java:701)
at com.jogamp.newt.awt.NewtCanvasAWT.removeNotify(NewtCanvasAWT.java:660)
at com.jme3.system.jogl.JoglNewtCanvas$1.removeNotify(JoglNewtCanvas.java:68)
at java.awt.Container.remove(Container.java:1199)
at java.awt.Container.remove(Container.java:1257)
at jme3test.awt.TestCanvas$3.actionPerformed(TestCanvas.java:123)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.AbstractButton.doClick(AbstractButton.java:376)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:833)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:877)
at java.awt.Component.processMouseEvent(Component.java:6516)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3320)
at java.awt.Component.processEvent(Component.java:6281)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4872)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4698)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4698)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:708)
at java.awt.EventQueue$4.run(EventQueue.java:706)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
Caused by: java.lang.RuntimeException: Waited 5000ms for: <5a1698f1, 193246c>[count 2, qsz 0, owner <AWT-EventQueue-0-AWTAnimator#00>] - <main-Display-.windows_nil-1-EDT-1>
at jogamp.common.util.locks.RecursiveLockImpl01Unfairish.lock(RecursiveLockImpl01Unfairish.java:198)
at jogamp.newt.WindowImpl$ReparentAction.reparent(WindowImpl.java:1608)
at jogamp.newt.WindowImpl$ReparentAction.run(WindowImpl.java:1587)
at com.jogamp.common.util.RunnableTask.run(RunnableTask.java:145)
at jogamp.newt.DefaultEDTUtil$NEDT.run(DefaultEDTUtil.java:375)
In case it’s helpful, here’s the modified TestCanvas class (added two lines of code to enable JOGL):
package jme3test.awt;
import com.jme3.app.LegacyApplication;
import com.jme3.app.SimpleApplication;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;
import com.jme3.util.JmeFormatter;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.concurrent.Callable;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Logger;
import javax.swing.*;
public class TestCanvas {
private static JmeCanvasContext context;
private static Canvas canvas;
private static LegacyApplication app;
private static JFrame frame;
private static Container canvasPanel1, canvasPanel2;
private static Container currentPanel;
private static JTabbedPane tabbedPane;
private static final String appClass = "jme3test.post.TestRenderToTexture";
private static void createTabs(){
tabbedPane = new JTabbedPane();
canvasPanel1 = new JPanel();
canvasPanel1.setLayout(new BorderLayout());
tabbedPane.addTab("jME3 Canvas 1", canvasPanel1);
canvasPanel2 = new JPanel();
canvasPanel2.setLayout(new BorderLayout());
tabbedPane.addTab("jME3 Canvas 2", canvasPanel2);
frame.getContentPane().add(tabbedPane);
currentPanel = canvasPanel1;
}
private static void createMenu(){
JMenuBar menuBar = new JMenuBar();
frame.setJMenuBar(menuBar);
JMenu menuTortureMethods = new JMenu("Canvas Torture Methods");
menuBar.add(menuTortureMethods);
final JMenuItem itemRemoveCanvas = new JMenuItem("Remove Canvas");
menuTortureMethods.add(itemRemoveCanvas);
itemRemoveCanvas.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (itemRemoveCanvas.getText().equals("Remove Canvas")){
currentPanel.remove(canvas);
itemRemoveCanvas.setText("Add Canvas");
}else if (itemRemoveCanvas.getText().equals("Add Canvas")){
currentPanel.add(canvas, BorderLayout.CENTER);
itemRemoveCanvas.setText("Remove Canvas");
}
}
});
final JMenuItem itemHideCanvas = new JMenuItem("Hide Canvas");
menuTortureMethods.add(itemHideCanvas);
itemHideCanvas.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (itemHideCanvas.getText().equals("Hide Canvas")){
canvas.setVisible(false);
itemHideCanvas.setText("Show Canvas");
}else if (itemHideCanvas.getText().equals("Show Canvas")){
canvas.setVisible(true);
itemHideCanvas.setText("Hide Canvas");
}
}
});
final JMenuItem itemSwitchTab = new JMenuItem("Switch to tab #2");
menuTortureMethods.add(itemSwitchTab);
itemSwitchTab.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if (itemSwitchTab.getText().equals("Switch to tab #2")){
canvasPanel1.remove(canvas);
canvasPanel2.add(canvas, BorderLayout.CENTER);
currentPanel = canvasPanel2;
itemSwitchTab.setText("Switch to tab #1");
}else if (itemSwitchTab.getText().equals("Switch to tab #1")){
canvasPanel2.remove(canvas);
canvasPanel1.add(canvas, BorderLayout.CENTER);
currentPanel = canvasPanel1;
itemSwitchTab.setText("Switch to tab #2");
}
}
});
JMenuItem itemSwitchLaf = new JMenuItem("Switch Look and Feel");
menuTortureMethods.add(itemSwitchLaf);
itemSwitchLaf.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Throwable t){
t.printStackTrace();
}
SwingUtilities.updateComponentTreeUI(frame);
frame.pack();
}
});
JMenuItem itemSmallSize = new JMenuItem("Set size to (0, 0)");
menuTortureMethods.add(itemSmallSize);
itemSmallSize.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
Dimension preferred = frame.getPreferredSize();
frame.setPreferredSize(new Dimension(0, 0));
frame.pack();
frame.setPreferredSize(preferred);
}
});
JMenuItem itemKillCanvas = new JMenuItem("Stop/Start Canvas");
menuTortureMethods.add(itemKillCanvas);
itemKillCanvas.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
currentPanel.remove(canvas);
app.stop(true);
createCanvas(appClass);
currentPanel.add(canvas, BorderLayout.CENTER);
frame.pack();
startApp();
}
});
JMenuItem itemExit = new JMenuItem("Exit");
menuTortureMethods.add(itemExit);
itemExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
frame.dispose();
app.stop();
}
});
}
private static void createFrame(){
frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener(new WindowAdapter(){
@Override
public void windowClosed(WindowEvent e) {
app.stop();
}
});
createTabs();
createMenu();
}
public static void createCanvas(String appClass){
AppSettings settings = new AppSettings(true);
settings.setWidth(640);
settings.setHeight(480);
// Added for JOGL
settings.setAudioRenderer(null);
settings.setRenderer("JOGL");
try{
Class<? extends LegacyApplication> clazz = (Class<? extends LegacyApplication>) Class.forName(appClass);
app = clazz.newInstance();
}catch (ClassNotFoundException ex){
ex.printStackTrace();
}catch (InstantiationException ex){
ex.printStackTrace();
}catch (IllegalAccessException ex){
ex.printStackTrace();
}
app.setPauseOnLostFocus(false);
app.setSettings(settings);
app.createCanvas();
app.startCanvas();
context = (JmeCanvasContext) app.getContext();
canvas = context.getCanvas();
canvas.setSize(settings.getWidth(), settings.getHeight());
}
public static void startApp(){
app.startCanvas();
app.enqueue(new Callable<Void>(){
public Void call(){
if (app instanceof SimpleApplication){
SimpleApplication simpleApp = (SimpleApplication) app;
simpleApp.getFlyByCamera().setDragToRotate(true);
}
return null;
}
});
}
public static void main(String[] args){
JmeFormatter formatter = new JmeFormatter();
Handler consoleHandler = new ConsoleHandler();
consoleHandler.setFormatter(formatter);
Logger.getLogger("").removeHandler(Logger.getLogger("").getHandlers()[0]);
Logger.getLogger("").addHandler(consoleHandler);
createCanvas(appClass);
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
}
SwingUtilities.invokeLater(new Runnable(){
public void run(){
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
createFrame();
currentPanel.add(canvas, BorderLayout.CENTER);
frame.pack();
startApp();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}