Bug 176

Summary: javax.media.opengl.GLException: Unable to create OpenGL context when deiconizied JInternalFrame with GLCanvas
Product: [JogAmp] Jogl Reporter: Sven Gothel <sgothel>
Component: coreAssignee: Sven Gothel <sgothel>
Status: VERIFIED FIXED    
Severity: normal    
Priority: P3    
Version: 1   
Hardware: All   
OS: windows   
Type: DEFECT SCM Refs:
Workaround: ---
Attachments: four source files and newly build jogl.jar and jogl.dll

Description Sven Gothel 2010-03-24 07:48:02 CET


---- Reported by javaalh 2005-09-22 02:03:12 ----

This problem DON'T occur when using release build 1.1.1 July 12 2005. It only 
occurred for the build I did from the source I checkout using
 cvs -d :pserver:guest@cvs.dev.java.net:/cvs co -r JSR-231 -P jogl jogl-demos

I build it using j2sdk1.4.2_08, ant from netbeans-4.1, antlr-2.7.5.jar and 
winGW-4.1.1.exe. This build solved my problem of JInternalFrame (JIF) with 
GLJPanel but cause problem if use JIF with GLCanvas. The test program is 
written to check JIF with GLJPanel, JIF with GLCanvas, JIF with JPanel and JIF 
with Canvas. It also checks the look and feel.

Previously when I run the test with release build jogl1.1.1, the only problem 
is JIF with GLJPanel. Now with my build (ie. use import javax.media.opengl.*; 
instead of import net.java.games.jogl.*;) no problem for JIF with GLJPanel but 
problem for JIF with GLCanvas. When I deiconized the JIF with GLCanvas, I got 
the following error :

javax.media.opengl.GLException: Unable to create OpenGL context
                at com.sun.opengl.impl.windows.WindowsGLContext.create
(WindowsGLContext.java:116)
                at com.sun.opengl.impl.windows.WindowsGLContext.makeCurrentImpl
(WindowsGLContext.java:141)
                at 
com.sun.opengl.impl.windows.WindowsOnscreenGLContext.makeCurrentImpl
(WindowsOnscreenGLContext.java:74)
                at com.sun.opengl.impl.GLContextImpl.makeCurrent
(GLContextImpl.java:79)
                at com.sun.opengl.impl.GLDrawableHelper.invokeGL
(GLDrawableHelper.java:117)
                at javax.media.opengl.GLCanvas.maybeDoSingleThreadedWorkaround
(GLCanvas.java:207)
                  :
                  :

In actual application I don't think people will put GLCanvas in JIF and have a 
few JIF since GLCanvas is heavy weight and JIF is light weight; however I felt 
obligated to report this issue so that it can be fixed.

I would like to attach my test files (4 of them), jogl.jar and jogl.dll but 
don't see any way to attach files, can someone teach me ? I'll cut and paste my 
source (some of the code is cut and paste from 
http://www.genedavissoftware.com/books/jogl/ljogl_ch1.html) for your testing. 
Thank you for your attention.


/***** SimpleJoglApp.java
*****/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
//import net.java.games.jogl.*;
import javax.media.opengl.*;
import javax.media.opengl.glu.*;
import java.beans.*;

public class SimpleJoglApp extends JFrame implements InternalFrameListener, 
ComponentListener {
    protected static final String metal    =
            "javax.swing.plaf.metal.MetalLookAndFeel";
    protected static final String motif    =
            "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
    protected static final String windows  =
            "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
    protected static String currentLookAndFeel = metal;

    static String[] rdstr={"java","motif","window"};

    JButton b = new JButton("make JInternalFrame");
    JRadioButton rdc = new JRadioButton("GLCanvas");
    JRadioButton rdp = new JRadioButton("GLJPanel");
    JRadioButton rdj = new JRadioButton("JPanel");
    JRadioButton rdw = new JRadioButton("Canvas");
    ButtonGroup btngp = new ButtonGroup();
    JRadioButton[] rdbtn;
    
    JDesktopPane desktopPane = new JDesktopPane();
    int windowCount = 1;
    
  public static void main(String[] args) {
    final SimpleJoglApp app = new SimpleJoglApp();

    // show what we've done
    SwingUtilities.invokeLater (
      new Runnable() {
        public void run() {
          app.setVisible(true);
        }
      }
    );
  }

  public SimpleJoglApp() {
    //set the JFrame title
    super("Test JInternalFrame with JOGL");
    
    //desktopPane.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);

    Container contentPane = getContentPane();
    JPanel top = new JPanel();
    top.add(b);
    JPanel toptype = new JPanel();
    toptype.setLayout(new BoxLayout(toptype, BoxLayout.Y_AXIS));
    btngp.add(rdc);
    btngp.add(rdp);
    btngp.add(rdj);
    btngp.add(rdw);
    toptype.add(rdc);
    toptype.add(rdp);
    toptype.add(rdj);
    toptype.add(rdw);
    rdp.setSelected(true);
    top.add(toptype);
    JPanel lafp = createList(this, desktopPane);
    top.add(lafp);
    
    contentPane.add(top, BorderLayout.NORTH);
    contentPane.add(desktopPane, BorderLayout.CENTER);
    //desktopPane.setLayout(new FlowLayout());
    
    b.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent event) {
            JInternalFrame jif = createJInternalFrame(windowCount);
            windowCount++;
            jif.setBounds(windowCount*20,windowCount*20,250,100);
            //jif.validate();
            jif.setVisible(true);
            desktopPane.add(jif);
            //desktopPane.revalidate();
        }
    });
                
    //kill the process when the JFrame is closed
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    setSize(500, 500);

    //center the JFrame on the screen
    centerWindow(this);
  }

  public void centerWindow(Component frame) {
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension frameSize  = frame.getSize();

    if (frameSize.width  > screenSize.width ) frameSize.width  = 
screenSize.width;
    if (frameSize.height > screenSize.height) frameSize.height = 
screenSize.height;

    frame.setLocation (
      (screenSize.width  - frameSize.width ) >> 1, 
      (screenSize.height - frameSize.height) >> 1
    );
  }
  
    JInternalFrame createJInternalFrame(int ctr)
    {
        String str = "GLJPanel";
        if (rdc.isSelected())
            str = "GLCanvas";
        else if (rdj.isSelected())
            str = "JPanel";
        else if (rdw.isSelected())
            str = "Canvas";
        JInternalFrame jif = new JInternalFrame("JInternal Frame "+ctr+" 
with "+str,true,true,true,true);
        //jif.setPreferredSize(new Dimension(250, 100));

        Component glcanvas = null;
        if (rdj.isSelected()) {
            glcanvas = new MyPanel(ctr);
        }
        else if (rdw.isSelected()) {
            glcanvas = new MyCanvas(ctr);
        }
        else {
        //only three JOGL lines of code ... and here they are 
    
            GLCapabilities glcaps = new GLCapabilities();
            if (rdp.isSelected()) {
                glcanvas = (Component) GLDrawableFactory.getFactory
().createGLJPanel(glcaps);
            }
            else {
                glcanvas = (Component) GLDrawableFactory.getFactory
().createGLCanvas(glcaps);
            }
            ((GLAutoDrawable) glcanvas).addGLEventListener(new 
SecondGLEventListener());
            jif.addInternalFrameListener(this);
            jif.addComponentListener(this);
        }
        Container cp = jif.getContentPane();
        cp.setLayout(new BorderLayout());
        cp.add(glcanvas, BorderLayout.CENTER);
        return jif;
    }
  
    JPanel createList(final JFrame frame, final JDesktopPane desktop)
    {
        JPanel rp = new JPanel();
        rp.setLayout(new BoxLayout(rp, BoxLayout.Y_AXIS));
        rdbtn = new JRadioButton[rdstr.length];
        ButtonGroup group = new ButtonGroup();
        for (int i=0; i<rdbtn.length; i++) {
            rdbtn[i] = new JRadioButton(rdstr[i]);
            if (i == 0)
                rdbtn[i].setSelected(true);
            group.add(rdbtn[i]);
            rdbtn[i].addItemListener(new ItemListener() {
                public void itemStateChanged(ItemEvent e) {
                    if (e.getStateChange() == ItemEvent.SELECTED) {
                        JRadioButton rb = (JRadioButton) e.getItem();
                        for (int j=0; j<rdbtn.length; j++) {
                            if (rdbtn[j] == rb) {
                                setLookAndFeel(frame, desktop, j);
                                break;
                            }
                        }
                    }
                }
            });
            rp.add(rdbtn[i]);
        }
        return rp;
    }
    
    public static String getLFstr(int idx)
    {
        String laf;
        if (idx == 0)
            laf = metal;
        else if (idx == 1)
            laf = motif;
        else
            laf = windows;
        return laf;    
    }
    
    public static void setLookAndFeel(Frame f, JDesktopPane desktop, int idx)
    {
        String laf = getLFstr(idx);
        if (laf != currentLookAndFeel) {
            currentLookAndFeel = laf;
        	try {
        	    UIManager.setLookAndFeel(currentLookAndFeel);
        		JInternalFrame [] jif=desktop.getAllFrames();
        		for (int i=0;i<jif.length;i++)
        		{
        			SwingUtilities.updateComponentTreeUI(jif[i]);
        		}
                // update LAF for the toplevel frame, too
                SwingUtilities.updateComponentTreeUI(f);
        	} catch (Exception ex) {
        		System.out.println("Failed loading L&F: "+ 
currentLookAndFeel+ " Set Look and Feel");
        	}
        }
    }
        
/** ========== ComponentListener interface ========== **/
    public void componentHidden(ComponentEvent e)
    {
    }
    public void componentMoved(ComponentEvent e)
    {
    }
    public void componentResized(ComponentEvent e)
    {
	    JInternalFrame jif = (JInternalFrame) e.getComponent();
        System.out.println("componentResized() is called for ["+jif.getTitle()
+"]");
        //ensureUpdate();
    }
    public void componentShown(ComponentEvent e)
    {
    }
/** ========== End of ComponentListener interface ========== **/

/** ========== InternalFrameListener interface ========== **/
 	public void internalFrameOpened(InternalFrameEvent e) 
	{	
	}
	public void internalFrameDeactivated(InternalFrameEvent e) 
	{	
	}
 	public void internalFrameClosed(InternalFrameEvent e) 
	{	
	}
	public void internalFrameClosing(InternalFrameEvent e) 
	{
	}

 	public void internalFrameActivated(InternalFrameEvent e) 
	{
	    JInternalFrame jif = e.getInternalFrame();
        System.out.println("internalFrameActivated() is called for 
["+jif.getTitle()+"]");
        //ensureUpdate();
	}

    void ensureUpdate()
    {        
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JInternalFrame cnt = desktopPane.getSelectedFrame();
                if (cnt != null) {
                    Rectangle rect = cnt.getNormalBounds();
                    if (cnt.isMaximum())
                        rect = cnt.getBounds();
                    System.out.println("reshape issued for ["+cnt.getTitle()
+"], rect="+rect+", isMaximum="+cnt.isMaximum());
                    cnt.reshape(rect.x, rect.y, rect.width, rect.height);
                }
                else {
                    System.out.println("why no selected JIFrame !!!!");
                }
            }
        });
    }
    
 	public void internalFrameIconified(InternalFrameEvent e) 
	{
	    JInternalFrame jif = e.getInternalFrame();
        System.out.println("internalFrameIconified() is called for 
["+jif.getTitle()+"]");
	}

 	public void internalFrameDeiconified(InternalFrameEvent e) 
	{
	    JInternalFrame jif = e.getInternalFrame();
        System.out.println("internalFrameDeiconified() is called for 
["+jif.getTitle()+"]");
    }
}



/*****SecondGLEventListener.java
*****/
//import net.java.games.jogl.*;
import javax.media.opengl.*;
import javax.media.opengl.glu.*;
public class SecondGLEventListener implements GLEventListener {

  /**
  * Take care of initialization here.
  */
//  public void init(GLDrawable gld) {
  public void init(GLAutoDrawable gld) {
    GL gl = gld.getGL();
    GLU glu = gld.getGLU();
    
    gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    
    gl.glViewport(0, 0, 500, 300);
    gl.glMatrixMode(GL.GL_PROJECTION);
    gl.glLoadIdentity();
    glu.gluOrtho2D(0.0, 500.0, 0.0, 300.0);
  }

  /**
  * Take care of drawing here.
  */
//  public void display(GLDrawable drawable) {
  public void display(GLAutoDrawable drawable) {

    float red = 0.0f;
    float green = 0.0f;
    float blue = 0.0f;
    
    GL gl = drawable.getGL();
    
    gl.glClear(GL.GL_COLOR_BUFFER_BIT);
    
    gl.glPointSize(5.0f);

    for (int i=0; i<50; i++) {
      
      red -= .09f;
      green -= .12f;
      blue -= .15f;
      
      if (red < 0.15) red = 1.0f;
      if (green < 0.15) green = 1.0f;
      if (blue < 0.15) blue = 1.0f;
      
      gl.glColor3f(red, green, blue);
      
      gl.glBegin(GL.GL_POINTS);
          gl.glVertex2i((i*10), 150);
      gl.glEnd();
      
    }
  }

  public void reshape(
                        GLAutoDrawable drawable, 
                        int x, 
                        int y, 
                        int width, 
                        int height
                      ) {}
  public void displayChanged(
                              GLAutoDrawable drawable, 
                              boolean modeChanged, 
                              boolean deviceChanged
                            ) {}
}


/*****MyPanel.java
*****/
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.border.*;

public class MyPanel extends JPanel {
    String idstr;
    private Color[] colors = { Color.yellow, Color.magenta,
                                    Color.cyan,   Color.blue,
                                    Color.green };
    
    MyPanel(int ctr)
    {
        idstr = new String("JPanel "+ctr);
        setBorder(BorderFactory.createTitledBorder(
            BorderFactory.createEtchedBorder(), idstr,
            TitledBorder.CENTER, TitledBorder.DEFAULT_POSITION));
    }
    
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Dimension d = getSize();
        Insets insets = getInsets();
        int dx = (d.width - insets.left - insets.right) / (colors.length * 
2);    
        int dy = (d.height - insets.top - insets.bottom) / (colors.length * 
2);    
        for (int i=0; i<colors.length; i++) {
            float yyx = i*dx + insets.left;
            float yyy = i*dy + insets.top;
            float yyw = (d.width - insets.left - insets.right) - 2*i*dx;
            float yyh = (d.height - insets.top - insets.bottom) - 2*i*dy;
            Shape shape =new Rectangle2D.Float(yyx,yyy,yyw,yyh);
            g.setColor(colors[i]);
            ((Graphics2D) g).fill(shape);
        }
    }
}        


/*****MyCanvas.java
*****/
import java.awt.*;
import java.awt.geom.*;

public class MyCanvas extends Canvas {
    String idstr;
    private Color[] colors = { Color.yellow, Color.magenta,
                                    Color.cyan,   Color.blue,
                                    Color.green };
    
    MyCanvas(int ctr)
    {
        idstr = new String("Canvas "+ctr);
    }
    
    public void paint(Graphics g) {
        Dimension d = getSize();
        int dx = d.width / (colors.length * 2);    
        int dy = d.height / (colors.length * 2);
        int[] xp = new int[4];
        int[] yp = new int[4];    
        for (int i=0; i<colors.length; i++) {
            xp[0] = d.width / 2;
            xp[1] = i*dx;
            xp[2] = xp[0];
            xp[3] = d.width - i*dx;
            yp[0] = i*dy;
            yp[1] = d.height / 2;
            yp[2] = d.height - i*dy;
            yp[3] = yp[1];
            Shape shape =new Polygon(xp,yp,4);
            g.setColor(colors[i]);
            ((Graphics2D) g).fill(shape);
        }
        g.setColor(Color.red);
        g.setFont(new Font("Helvetica",Font.BOLD,14));
        int sw = g.getFontMetrics().stringWidth(idstr);
        g.drawString(idstr, (d.width - sw)/2, d.height/2);
    }
}



---- Additional Comments From javaalh 2005-09-22 02:12:38 ----

Created an attachment
four source files and newly build jogl.jar and jogl.dll




---- Additional Comments From kbr 2005-09-22 18:29:23 ----

This was a regression accidentally introduced during the split of the GLContext
class into separate GLDrawable and GLContext classes. On Windows only, the pixel
format was not being set for the newly-materialized underlying window. This has
been fixed in the JSR-231 branch.




--- Bug imported by sgothel@jausoft.com 2010-03-24 07:48 EDT  ---

This bug was previously known as _bug_ 176 at https://jogl.dev.java.net/bugs/show_bug.cgi?id=176
Imported an attachment (id=63)

The original submitter of attachment 63 [details] is unknown.
   Reassigning to the person who moved it here: sgothel@jausoft.com.