3

I'm having a problem with my Java layout. I'm trying to place a JLabel across the very top follow by a grid of five WorldWindowGLCanvas's. Something like:

------------------------------------------------
                     JLabel
------------------------------------------------
                       |
         WWCanvas      |       WWCanvas
                       |

------------------------------------------------
                       |
         WWCanvas      |       WWCanvas
                       |

I'm currently using a GridBagLayout inside of a JPanel. When the program first starts everything looks as it should. However, upon the first redraw of all the WorldWindowGLCanvas's the top JLabel immediately doubles in size and takes up was too much space. Here's some relevant code:

JFrame f = new JFrame("ScintDisplay");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLayout(new GridBagLayout());

        JLabel timeLabel = new JLabel(getTime(), JLabel.CENTER);
        timeLabel.setSize(new Dimension(200,200));


        WorldWindowGLCanvas wwd1 = new WorldWindowGLCanvas();
        wwd1.setPreferredSize(new java.awt.Dimension(960, 1000));

        WorldWindowGLCanvas wwd2 = new WorldWindowGLCanvas();
        wwd2.setPreferredSize(new java.awt.Dimension(500, 480));

        WorldWindowGLCanvas wwd3 = new WorldWindowGLCanvas();
        wwd3.setPreferredSize(new java.awt.Dimension(500, 480));

        WorldWindowGLCanvas wwd4 = new WorldWindowGLCanvas();
        wwd4.setPreferredSize(new java.awt.Dimension(500, 480));

        WorldWindowGLCanvas wwd5 = new WorldWindowGLCanvas();
        wwd5.setPreferredSize(new java.awt.Dimension(500, 480));

        wwd1.setModel(new BasicModel());
        wwd2.setModel(new BasicModel());
        wwd3.setModel(new BasicModel());
        wwd4.setModel(new BasicModel());
        wwd5.setModel(new BasicModel());

        addComponent(f, wwd2, 0, 2, 1, 4, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
        addComponent(f, wwd1, 1, 2, 2, 8, GridBagConstraints.CENTER, GridBagConstraints.BOTH);            
        addComponent(f, wwd3, 3, 2, 1, 4, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
        addComponent(f, wwd4, 0, 6, 1, 4, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
        addComponent(f, wwd5, 3, 6, 1, 4, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
        addComponent(f, timeLabel, 0, 0, 4, 1, GridBagConstraints.WEST, GridBagConstraints.NONE);

        f.setSize(1920, 1200);
        f.setVisible(true);


        double lat1 = getTimeLon();

        for( ; ; )
        {
            //System.out.println(lat);
            timeLabel.setText(getTime());
            System.out.println(timeLabel.getSize());
            wwd1.getView().setEyePosition(Position.fromDegrees(0, lat1, 10500000));
            wwd2.getView().setEyePosition(Position.fromDegrees(0, 0, 23500000));
            wwd3.getView().setEyePosition(Position.fromDegrees(0, 0, 23500000));
            wwd4.getView().setEyePosition(Position.fromDegrees(0, 0, 23500000));
            wwd5.getView().setEyePosition(Position.fromDegrees(0, 0, 23500000));
            wwd1.redraw();
            wwd2.redraw();
            wwd3.redraw();
            wwd4.redraw();
            wwd5.redraw();
            Thread.sleep(30000);
            lat1 = getTimeLon();
        }

     private static void addComponent(Container container, Component component, int gridx, int gridy, int gridwidth, int gridheight, int anchor, int fill)
    {
            GridBagConstraints gbc = new GridBagConstraints(gridx, gridy, gridwidth, gridheight, 1.0, 1.0, anchor, fill, insets, 0, 0);
            container.add(component, gbc);
    }

I've never done a GUI with GL components that redraw before. Am I missing something? Is this a layout problem. or something to do with redrawing?

Thanks, -B

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Brandon
  • 137
  • 2
  • 7

1 Answers1

5

You're trying to ask GridBagLayout to do too much and instead should use nested JPanels to achieve this. Have the center JPanel use GridBagLayout, sure, but have it held by another JPanel that uses BorderLayout. Add the center panel to the BorderLayout.CENTER position, and the JLabel to the main BorderLayout-using JPanel's BorderLayout.NORTH or BorderLayout.PAGE_START position. Also be sure that the JLabel has been set to display it's text centered.

Also, you've got code there that looks dangerous from a Swing threading point of view. That non-stopping loop and Thread.sleep(...) appear to be called on the Swing event thread or EDT, and this can cause your application to freeze. Consider using a SwingWorker to allow this code to be called on a background thread.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • +1 rel. example how Thread.sleep(int) block EDT http://stackoverflow.com/a/7944388/714968 – mKorbel Feb 03 '12 at 23:06
  • Ah thanks. That did the trick. I'm still getting used to GUI stuff. I'll look into backgrounding the thread as well. Thanks for the heads up. – Brandon Feb 03 '12 at 23:11
  • @Brandon: You're welcome. I think part of your problem with GridBagLayout is that you're giving all components the same weightx and weighty constants, and so when the GUI expands, all components increase. And you use the same anchors and fills. Myself, I hate using GridBagLayout and avoid it unless necessary. – Hovercraft Full Of Eels Feb 03 '12 at 23:18