[SOLVED] Lwjgl3 getWidth, getHeight

Given how it seems to want to work, it seems reasonable.

As does static default fields… I mean it was already trying to access static resources for the same purpose. Allowing the caller to specify just makes it more flexible… whichever approach is taken.

Heres what I did to fix these in the end with advice given.

        /**
         * Previous implementations used lwjgl methods to obtain this value, 
         * which returns the users monitor width. This fix uses the jme camera 
         * to get this value, as this may be a different size. This also removes 
         * the requirement of specific lwjgl implementations.
         * 
         * If PopupState() is not enabled by the time this method is called, an 
         * exception would be thrown. We use DEFAULT_MAX_WIDTH in those cases. 
         * This should be set using the cameras width value, wherever and 
         * however you decide to obtain it.
         * 
         * @param hHint is not used.
         * @return The maximum width of the component.
         */
        @Override
        public int getMaximumWidth(int hHint) {
            Application application = GuiGlobals.getInstance().getPopupState().getApplication();

            if (application != null) {
                return application.getCamera().getWidth();
            } else {
                return Main.DEFAULT_MAX_WIDTH;
            }
        }

I set the defaults in SimpleApplication on startup by reading the default camera values. I tested within a secondary ViewPort and it works fine there even though the viewport is different in size. This value only needs to match the maximum screen size rather than viewport it would seem as it was using the main cameras values in the secondary viewport.

The issue would come in the case where you have a UI projected onto some texture that is not the same size as the screen.

…but you can always wait to deal with that until you have that use case.

Actually, I’m surprised it wouldn’t also come up with a viewport that is only part of the screen and you never wanted your stuff to be bigger than that.

Heres normal,

        // Create a window in the viewport
        vpWindow = new Container(new MigLayout("wrap"));
        CursorEventControl.addListenersToSpatial(vpWindow, new DragHandler());
        
        vpWindow.addChild(new Label("ViewPort Child", new ElementId("label")));
        Button addChild = vpWindow.addChild(new Button("Click Me 1"));

Heres first button massively larger than screen.

        // Create a window in the viewport
        vpWindow = new Container(new MigLayout("wrap"));
        CursorEventControl.addListenersToSpatial(vpWindow, new DragHandler());
        
        vpWindow.addChild(new Label("ViewPort Child", new ElementId("label")));
        Button addChild = vpWindow.addChild(new Button("Click Me 1"));  
        addChild.setPreferredSize(new Vector3f(700.0f, 500.0f, 0));

I made sure that it uses both default values and GuiGlobals values for width and height.

Edit: This is loaded from super constructor and built on init.

I suspect this particular case is a “perfect storm” sequence of events.

UI is initialized in the init method of an app state passed to the app constructor.
UI also wants to get the panel’s preferred size for proper placement.
Calculating the preferred size at that point requires MigLayout to do ‘something’ and that requires max width, etc…

A lot of my apps put that first main menu in a fixed position off to the side instead of centered, I think partially for this reason. (Though mostly because of the spinning SiO2 molecule in the background. :slight_smile: )

I skip that and build the Viewport and lemur objects in the AppState init when Main instantiates super just to make sure its missing the data it wants .

The “Lemur Demo” buttons never get clicked. I didnt remove that code as its not affecting things.

Using your implementation prevents it from ever failing if I dont.

@mitm what’s wrong with the MigLayout I created and posted for everyone? Just curious because I use it everywhere on my UI.

The way you depend on the lwjgl implementation for getMaximumWidth and height. This will break when upgrading or downgrading the lwjgl implementation.

It also use the users screen size rather than the applications viewport size if the methods get called at a time when the viewport settings are not available.

So I changed it to use a variable that gets set during startup of the application, based off camera settings, if it cant find the camera else use the camera for the settings.

The only drawback is having to set the variable to use the class.

1 Like