GLCanvas won't resize inside a JSplitPane

When a GLCanvas is added to a JPanel, and the JPanel is added to a JSplitPane, the splitter bar can only be moved in one direction. For example, if the JPanel is added to the left side of the splitter pane, then the splitter bar can only be moved to the right. If two JPanels with two GLCanvas objects are added to both sides of the splitter pane, then the splitter bar is completely locked up.

What’s going on here? Does anyone know how to fix this?

Thanks.

– Brian Stone

JPanel uses FlowLayout as default layout manager, use BorderLayout instead.

Lilian

In fact I believe the cause of this is the GLCanvas on a resize event explicitly calls setMinimumSize() with the new canvas size which prevents it from being resized smaller again.

I’m pretty sure there’s already a bug raised, at least I hope so, because this is something we really need fixed too. :slight_smile:

GLCanvas doesn’t override Canvas’s resizing behavior nor does it call setMinimumSize explicitly. There are I believe a couple of bugs filed about the GLCanvas’s resizing behavior but I never looked into them deeply enough to understand how to make GLCanvas behave more like a JPanel in terms of respecting the minimum and maximum size requests. If you or someone else could investigate some of these issues and provide patches that would be a great help.

Thanks for the info. I’m using BorderLayout in the JPanel and adding the JPanel to the Center section. I need this capability for the software I’m developing, so I’ll keep looking into it.

BTW, here’s a simple example that demonstrates the problem. This program creates a JFrame with a JSplitPane control. Two TestPanel’s are added to both sides of the JSplitPane. The TestPanel class extends the JPanel class. The TestPanel also creates a GLCanvas and renders a white square in the center of the canvas.


package joglswingtest2;

import net.java.games.jogl.*;
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.event.*;

public class Main extends javax.swing.JFrame {
    private javax.swing.JMenuItem fileExit;
    private javax.swing.JMenu fileMenu;
    private javax.swing.JPanel leftPanel;
    private javax.swing.JMenuBar menubar;
    private javax.swing.JPanel rightPanel;
    private javax.swing.JSplitPane splitPane;
    
    private TestPanel panel1, panel2;
    
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Main().setVisible(true);
            }
        });
    }
    
    public Main() {
        // This call ensures that the JMenuBar will render over the GLCanvas.
        JPopupMenu.setDefaultLightWeightPopupEnabled(false);
        
        // Create components.
        splitPane = new javax.swing.JSplitPane();
        leftPanel = new javax.swing.JPanel();
        rightPanel = new javax.swing.JPanel();
        menubar = new javax.swing.JMenuBar();
        fileMenu = new javax.swing.JMenu();
        fileExit = new javax.swing.JMenuItem();
        
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        leftPanel.setLayout(new java.awt.BorderLayout());        
        leftPanel.setPreferredSize(new java.awt.Dimension(300, 600));
        splitPane.setLeftComponent(leftPanel);        
        rightPanel.setLayout(new java.awt.BorderLayout());        
        splitPane.setRightComponent(rightPanel);
        
        getContentPane().add(splitPane, java.awt.BorderLayout.CENTER);
        
        fileMenu.setText("File");
        fileExit.setText("Exit");
        fileExit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                fileExitActionPerformed(evt);
            }
        });
        
        fileMenu.add(fileExit);        
        menubar.add(fileMenu);        
        setJMenuBar(menubar);        
        
        panel1 = new TestPanel();
        panel2 = new TestPanel();
        leftPanel.add(panel1, java.awt.BorderLayout.CENTER);    
        rightPanel.add(panel2, java.awt.BorderLayout.CENTER);
        
        pack();
        
        setSize(800, 600);        
    }

    private void fileExitActionPerformed(java.awt.event.ActionEvent evt) {                                         
        System.exit(0);
    }                                        
    
        
    public class TestPanel extends javax.swing.JPanel {
        GLCanvas canvas;
        
        public TestPanel() {
            // The JPanel must use the Border layout manager.
            setLayout(new java.awt.BorderLayout());
            
            // Create the GLCanvas.
            canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities());
            canvas.addGLEventListener(new TestRenderer());
            
            // Add the canvas to the center of the JPanel.
            add(canvas);
        }
        
        class TestRenderer implements GLEventListener {
            private GL gl;
            private GLDrawable gldrawable;
            
            public void init(GLDrawable drawable) {        
                gl = drawable.getGL();
                this.gldrawable = drawable;
            }
            
            public void reshape(GLDrawable drawable, int x, int y, int width, int height) {
                gl. glViewport(0, 0, width, height);
            }
            
            public void display(GLDrawable drawable) {
                gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
                gl.glBegin(GL.GL_POLYGON);
            gl.glVertex2f(-0.5f, -0.5f);
            gl.glVertex2f(-0.5f, 0.5f);
            gl.glVertex2f(0.5f, 0.5f);
            gl.glVertex2f(0.5f, -0.5f);
                gl.glEnd();
            }
            
            public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {}
        }
    }
}

Simple workaround : adding a setMinimumSize on TestPanel works…

// Add the canvas to the center of the JPanel.
add(canvas);
setMinimumSize(new java.awt.Dimension(100,100));

Lilian

Thanks Lilian, that did it!

– Brian Stone