Upgraded to Java 8, lwjgl AWT-Canvas does not work correctly anymore

Started by Cornix, April 21, 2014, 15:23:50

Previous topic - Next topic

Cornix

Hi there.

I wrote a simple class for myself to use LWJGL with Swing by using the Display.setParent() method with an AWT-Canvas.
The class looks somewhat like this: (I cut some MouseEvent, KeyEvent stuff out)
public abstract class OGL_Canvas extends Canvas {
	private static final long serialVersionUID = 1L;
	
	protected final Thread thread;
	protected volatile boolean paused;
	protected volatile boolean running;
	protected volatile boolean needUpdateViewport;
	
	private volatile boolean wasStarted;
	
	public OGL_Canvas() {
		super();
		
		setIgnoreRepaint(true);
		
		wasStarted = false;
		addComponentListener(new ComponentListener() {
			public void componentShown(ComponentEvent e) {
				setNeedUpdate();
			}
			public void componentResized(ComponentEvent e) {
				setNeedUpdate();
				
				if (!wasStarted && getWidth() > 0 && getHeight() > 0) {
					wasStarted = true;
					thread.start();
				}
			}
			public void componentMoved(ComponentEvent e) {
				setNeedUpdate();
			}
			public void componentHidden(ComponentEvent e) {
				setNeedUpdate();
			}
		});
		
		final Canvas thisAsCanvas = this;
		thread = new Thread() {
			public void run() {
				try {
					Display.create();
					Display.setParent(thisAsCanvas);
					Display.setVSyncEnabled(true);
					
					Rectangle rect = thisAsCanvas.getBounds();
					int w = (int) rect.getWidth();
					int h = (int) rect.getHeight();
					
					if (w == 0 || h == 0) {
						throw new IllegalStateException("OGL_Canvas can not be initialized with dimension of: "+w+" * "+h);
					}
					
					GL11.glClearColor(0, 0, 0, 1);
					GLError.throwIfNecessary(this, "glClearColor");
					
					GL11.glMatrixMode(GL11.GL_PROJECTION);
					GLError.throwIfNecessary(this, "glMatrixMode");
					GL11.glLoadIdentity();
					GLError.throwIfNecessary(this, "glLoadIdentity");
					GL11.glOrtho(0, w, h, 0, -1, 1);
					GLError.throwIfNecessary(this, "glOrtho("+w+", "+h+", "+-1+", "+1+")");
					
					GL11.glViewport(0, 0, w, h);
					GLError.throwIfNecessary(this, "glViewport");
					
					Display.update();
					
					running = true;
				} catch (Exception e) {
					e.printStackTrace();
				}
				try {
					initialize();
				} catch (Exception e) {
					e.printStackTrace();
				}
				try {
					while (running) {
						updateGL();
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				try {
					terminate();
				} catch (Exception e) {
					e.printStackTrace();
				}
				if (Display.isCreated()) {
					Display.destroy();
				}
			}
		};
	}
	
	public void stop() {
		running = false;
		try {
			thread.join();
			assert !Display.isCreated() : "Display was not successfully killed.";
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	public void removeNotify() {
		stop();
	}
	
	private void setNeedUpdate() {
		needUpdateViewport = true;
	}
	
	private void updateGL() {
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
		GLError.throwIfNecessary(this, "glClear");
		
		render();
		
		Display.update();
		Display.sync(30);
		
		if (needUpdateViewport) {
			needUpdateViewport = false;
			
			Rectangle rect = getBounds();
			int w = (int) rect.getWidth();
			int h = (int) rect.getHeight();
			
			GL11.glMatrixMode(GL11.GL_PROJECTION);
			GLError.throwIfNecessary(this, "glMatrixMode");
			GL11.glLoadIdentity();
			GLError.throwIfNecessary(this, "glLoadIdentity");
			GL11.glOrtho(0, w, h, 0, -1, 1);
			GLError.throwIfNecessary(this, "glOrtho("+w+", "+h+", "+-1+", "+1+")");

			GL11.glViewport(0, 0, w, h);
			GLError.throwIfNecessary(this, "glViewport");
		}
	}
	
	protected abstract void render();
	
	protected abstract void initialize();
	
	protected abstract void terminate();
	
}

I also have a test application for this:
public class OGL_CanvasTest {
	
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					OGL_CanvasTest window = new OGL_CanvasTest();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	
	private JFrame frame;
	private OGL_Canvas canvas;
	
	public OGL_CanvasTest() {
		frame = new JFrame();
		frame.setBounds(100, 100, 769, 594);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JPanel panel = new JPanel();
		frame.getContentPane().add(panel, BorderLayout.WEST);
		panel.setLayout(new BorderLayout(0, 0));
		
		JScrollPane scrollPane = new JScrollPane();
		panel.add(scrollPane, BorderLayout.CENTER);
		
		JList list = new JList();
		scrollPane.setViewportView(list);
		
		JPanel panel_1 = new JPanel();
		frame.getContentPane().add(panel_1, BorderLayout.NORTH);
		panel_1.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
		
		JLabel lblThisIsA = new JLabel("This is a nice Title!");
		panel_1.add(lblThisIsA);
		
		JPanel panel_2 = new JPanel();
		frame.getContentPane().add(panel_2, BorderLayout.SOUTH);
		panel_2.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
		
		JButton btnNewButton = new JButton("OK");
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				frame.getContentPane().remove(canvas);
			}
		});
		panel_2.add(btnNewButton);
		
		JButton btnNewButton_1 = new JButton("Cancel");
		panel_2.add(btnNewButton_1);
		
		JPanel panel_3 = new JPanel();
		frame.getContentPane().add(panel_3, BorderLayout.EAST);
		panel_3.setLayout(new BorderLayout(0, 0));
		
		JTextArea txtrAsdsdgsdfsdhsdfg = new JTextArea();
		txtrAsdsdgsdfsdhsdfg.setLineWrap(true);
		txtrAsdsdgsdfsdhsdfg.setWrapStyleWord(true);
		txtrAsdsdgsdfsdhsdfg.setText("This is a long and nice looking text");
		panel_3.add(txtrAsdsdgsdfsdhsdfg, BorderLayout.CENTER);
		
		canvas = new OGL_Canvas() {
			private static final long serialVersionUID = 1L;
			protected void terminate() {
			}
			protected void render() {
				GL11.glBegin(GL11.GL_QUADS);
				GLError.throwIfNecessary(this, "glBegin(GL11.GL_QUADS)");
				
				GL11.glColor4f(0, 0, 1, 1);
				GLError.throwIfNecessary(this, "glColor4f(0, 0, 1, 1)");
				GL11.glVertex4f(0, 0, 0, 1);
				GLError.throwIfNecessary(this, "glVertex4f(0, 0, 0, 1)");
				
				GL11.glColor4f(0, 1, 0, 1);
				GLError.throwIfNecessary(this, "glColor4f(0, 1, 0, 1)");
				GL11.glVertex4f(0, 64, 0, 1);
				GLError.throwIfNecessary(this, "glVertex4f(0, 64, 0, 1)");
				
				GL11.glColor4f(1, 1, 0, 1);
				GLError.throwIfNecessary(this, "glColor4f(1, 1, 0, 1)");
				GL11.glVertex4f(64, 64, 0, 1);
				GLError.throwIfNecessary(this, "glVertex4f(64, 64, 0, 1)");
				
				GL11.glColor4f(1, 0, 0, 1);
				GLError.throwIfNecessary(this, "glColor4f(1, 0, 0, 1)");
				GL11.glVertex4f(64, 0, 0, 1);
				GLError.throwIfNecessary(this, "glVertex4f(64, 0, 0, 1)");
				
				GL11.glEnd();
				GLError.throwIfNecessary(this, "glEnd");
			}
			protected void initialize() {
			}
		};
		frame.getContentPane().add(canvas, BorderLayout.CENTER);
	}
	
}


This worked really well... Until I upgraded to Java 8 today.
Since then I get the following exception when I attempt to remove the OGL_Canvas from the JFrame:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at sun.java2d.ScreenUpdateManager.createScreenSurface(Unknown Source)
	at sun.java2d.d3d.D3DScreenUpdateManager.createScreenSurface(Unknown Source)
	at sun.awt.windows.WComponentPeer.createScreenSurface(Unknown Source)
	at sun.awt.windows.WComponentPeer.replaceSurfaceData(Unknown Source)
	at sun.awt.windows.WComponentPeer.replaceSurfaceData(Unknown Source)
	at sun.awt.windows.WComponentPeer.updateGraphicsData(Unknown Source)
	at java.awt.Component.updateGraphicsData(Unknown Source)
	at java.awt.Component.setGraphicsConfiguration(Unknown Source)
	at java.awt.Canvas.setGraphicsConfiguration(Unknown Source)
	at java.awt.Container.remove(Unknown Source)
	at java.awt.Container.remove(Unknown Source)
	at test.OGL_CanvasTest$2.actionPerformed(OGL_CanvasTest.java:72)
	at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
	at java.awt.Component.processMouseEvent(Unknown Source)
	at javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.awt.Component.processEvent(Unknown Source)
	at java.awt.Container.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$400(Unknown Source)
	at java.awt.EventQueue$3.run(Unknown Source)
	at java.awt.EventQueue$3.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue$4.run(Unknown Source)
	at java.awt.EventQueue$4.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)

(If you click the OK button the Canvas will be removed from the JFrame)

The problem with this error is: I have NO IDEA where this is coming from or what to do with it.
I didnt change anything with my code. This never happened before.
So my guess is this has to do with Java 8 and LWJGL not working together.

Any help is greatly appreciated.

kappa

are you using the latest nightly builds of lwjgl or some other version?

Cornix

I am using one of the stable version, I think it was the latest but I cant tell at this moment.

kappa


Cornix

Just downloaded the latest nightly build and tested again, it still does not work. I get the same error.

Can somebody please test this on another system? I am using Windows 7 64bit by the way.