[FIXED] OSX Canvas in JInternalFrame draws to DesktopPane

Started by orbitton, July 23, 2013, 08:19:32

Previous topic - Next topic

orbitton

Hey guys,

I'm trying to port an applet from Windows to OSX. We use an applet with a JDesktopPane with a JInternalFrame, which holds the canvas. On windows, the canvas moves with the JInternalFrame. On OSX, the canvas seems to align to the JDesktopPane. The canvas does resize with the JInternalFrame, and they are registered as each others child/parent.

This example behaves as expected on Windows, but not on OSX:

import java.awt.Canvas;
import java.awt.Container;
import java.beans.PropertyVetoException;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.WindowConstants;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;

public class DesktopTest {

    public static void main(String[] args) {

        final JFrame frame = new JFrame();

        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        frame.setSize(500, 500);

        JDesktopPane desktop = new JDesktopPane();
        desktop.setVisible(true);

        frame.setContentPane(desktop);

        final JInternalFrame internalFrame = new JInternalFrame("internal!", true, true, false);

        desktop.add(internalFrame);

        internalFrame.setVisible(true);
        internalFrame.setLocation(30,30);
        internalFrame.setBounds(40, 40, 200, 150);
        internalFrame.setFocusable(true);
        try {
            internalFrame.setSelected(true);
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }

        final Canvas canvas = makeCanvas();

        internalFrame.getContentPane().add(canvas);
        internalFrame.invalidate();

        Thread invalidator = new Thread() {
            @Override
            public void run() {
                while (true) {
                	//drawQuad();
			        //Display.update();
                    //canvas.setLocation((int) internalFrame.getLocation().getX() + internalFrame.getInsets().left, (int) internalFrame.getLocation().getY() + internalFrame.getInsets().top);
                    frame.invalidate();
                }
            }
        };
        invalidator.setDaemon(true);
        
        
        frame.setVisible(true);
        new Thread() {
        	public void run() {
		        try {
					Display.setParent(canvas);
					Display.create();
					
					drawQuad();
					
					while(true) {
	                	drawQuad();
				        Display.update();
					}
				} catch (LWJGLException e) {
					e.printStackTrace();
				}
        	}
        }.start();
    }
    
    public static void drawQuad() {


        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity(); // Resets any previous projection matrices
        GL11.glOrtho(0, 640, 480, 0, 1, -1);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
     // clear the screen and depth buffer
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);	
         
        // set the color of the quad (R,G,B,A)
        GL11.glColor3f(0.5f,0.5f,1.0f);
         
        // draw quad
        GL11.glBegin(GL11.GL_QUADS);
        GL11.glVertex2f(100,100);
        GL11.glVertex2f(100+200,100);
        GL11.glVertex2f(100+200,100+200);
        GL11.glVertex2f(100,100+200);
        GL11.glEnd();
    }
    
    public static Canvas makeCanvas() {
        //Application app = new Application();
        //app.createCanvas();
        //JmeCanvasContext context = (JmeCanvasContext) app.getContext();
        //Canvas canvas = context.getCanvas();
        Canvas canvas = new Canvas();
        canvas.setFocusable(true);
        canvas.setSize(200,150);
        canvas.setVisible(true);
        return canvas;
    }

}


EDIT: adjusted code to more clearly show canvas begin drawn (in)correctly


kappa

This issue is now fixed and will be available in the next nightly builds of LWJGL 2.9.1.

Thanks for the test case was very useful in debugging this issue.

Main reason for the slew of bug fixes to OSX/CALayers recently is due to this JDK bug which Oracle will not be fixing until Java 8. Therefore we've had to implement a workaround for this bug on Java 7, CALayer positioning should work as normal on Java 6 and Java 8 onwards and not require use of the workaround code.