Trouble using ViewPortPanel2D for making a Scroll Box

Hello, I am trying to make a scroll box container for my Lemur GUIs by using the ViewPortPanel2D class, but I am running into a problem where the ViewPortPanel2D automatically resizes itself whenever the game is minimized - but only when using a SpringGridLayout with FillMode.None on both the X and Y axis - which is necissary in order to make sure the scroll box items always appear with the PreferredSize value that i set.

I created a simple test case that adds 3 rows to a ViewPortPanel2D, and I also attached a .gif that shows the way that the rows resize whenever the game is minimized and regains focus.

Here Is my Code:

import com.jme3.app.SimpleApplication;
import com.jme3.math.Vector3f;

import com.jme3.renderer.RenderManager;
import com.jme3.system.AppSettings;
import com.jme3.util.BufferUtils;
import com.nx.util.jme3.lemur.panel.ViewportPanel2D;
import com.simsilica.lemur.Axis;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.FillMode;
import com.simsilica.lemur.GuiGlobals;
import com.simsilica.lemur.Insets3f;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.component.SpringGridLayout;
import com.simsilica.lemur.style.BaseStyles;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;

public class Main extends SimpleApplication {
    
    
    
    
  private static float width, height ;
  private static GraphicsDevice device;
  

    public static void main(String[] args) {
        Main app = new Main();
        
        app.setShowSettings(false);
        app.setDisplayStatView(false);
        app.setDisplayFps(false);
    
        device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
        width = device.getDisplayMode().getWidth() * .99f;
        height = device.getDisplayMode().getHeight() * .925f;


    AppSettings settings = new AppSettings(true);

    settings.put("Title", "Afflicted Scene Designer");

    settings.put("FrameRate", 140);
    settings.put("GammaCorrection", true);
    settings.put("Samples", 16);


    settings.put("Width", ((int)width));
    settings.put("Height", ((int)height));

    app.setSettings(settings);


    BufferUtils.setTrackDirectMemoryEnabled(true);
    
    app.start();
}

    

@Override
public void simpleInitApp() {
    
     GuiGlobals.initialize(this);
     BaseStyles.loadGlassStyle();  
     GuiGlobals.getInstance().getStyles().setDefaultStyle("glass");
    
    Container windowContainer = new Container();
    
    windowContainer.setPreferredSize(new Vector3f(500, 500, 1f));
    
    windowContainer.setLayout(new SpringGridLayout(Axis.X, Axis.Y, FillMode.None, FillMode.None));
    
    guiNode.attachChild(windowContainer);
    windowContainer.move(new Vector3f(width * 0.2f, height * 0.8f, 0));
    
    
 
    ViewportPanel2D scrollviewPort = new ViewportPanel2D(getStateManager(), windowContainer.getElementId(), "glass");
    
    Container containerOnViewport = new Container();
    
    
   
    
     scrollviewPort = new ViewportPanel2D(getStateManager(), containerOnViewport.getElementId(), "glass");
      
     
    
    windowContainer.addChild(scrollviewPort);
      
    scrollviewPort.attachScene(containerOnViewport);
      
    containerOnViewport.addChild(getRowContainer(), 0, 0);
    
    containerOnViewport.addChild(getRowContainer(), 1, 0);
    containerOnViewport.addChild(getRowContainer(), 2, 0);

  
     scrollviewPort.setPreferredSize(new Vector3f(500, 220, 1));
     containerOnViewport.setPreferredSize(new Vector3f(400, 220, 1));
    
     
     setPauseOnLostFocus(false);
}

 private Container getRowContainer(){
    Container rowContainer = new Container();
   
    
    rowContainer.setBackground(new QuadBackgroundComponent());
    
    rowContainer.addChild(new Label(" ROW "), 0, 0);
    
    rowContainer.setInsets(new Insets3f(2,2,2,2));
    
    rowContainer.setPreferredSize(new Vector3f(80, 30, 1));
    
    return rowContainer;
}

@Override
public void simpleUpdate(float tpf) {

}

@Override
public void simpleRender(RenderManager rm) {
    
}
}

And here is the results when the game is minimzied and restored and the contents of the ViewPortPanel2D are scaled down.


Any pointers as to what I need to do to get my Containers on the alternate viewport to always be the size i set using .setPreferredSize() would be greatly appreciated.

I am also fairly new to Lemur, as I had started using JME with Nifty, so any advice or tips on how I could improve my Lemur code is also appreciated :smiley:

I typically like to use the default SpringGridLayout for auto-sizing my static interfaces that never change at run-time, and then I like to use the SpringGridLayout with FillMode.None for containers that have a pre-set PreferredSize when I am making an interface that can be added to / removed from dynamically at run time (such as the scroll box that I am having trouble making with the ViewPortPanel2D).

Thanks in advance for any help :slightly_smiling_face:

It’s been a long time since I made this post but I still have this issue unfortunately.

Does anyone know anything about this bug?

I also wonder if I used wrong or outdated code for setting up alternate viewports? I used this implementation which does not appear to be an official lemur implementation:

I also have just noticed that anything displayed on an alternate viewport is not captured when I take a screenshot with the ScreenShotAppState (and unfortunately regular print-screening to the clipboard for easy pasting doesn’t work in full screen mode, so I have no choice but to use ScreenShotAppState). I made another thread about this issue, but since no one else seems to have reported similar screenshot issues, I also suspect it could be related to the problems I’m having with this library I used for setting up viewports.

Is there a better library I should be using for alternate viewports?

Any help on this issue is greatly appreciated

Without looking at the library, it’s weird that something that appears on screen wouldn’t be captured by the screen shot app state. As a guess, maybe that library is clearing something at a time that confuses the screen shot.

As to the other, for some reason I don’t remember ever seeing it.

I don’t understand why any Lemur components would resize themselves based on application minimization. JME doesn’t even provide hooks to do so even if I wanted to. (Even catching screen size changes is non-trivial.)

Probably not coincidence that SceneProcessors are the only way to catch this sort of thing and I suspect that’s what’s happening here. Probably there is something detecting the reshape() and not handling it very well with respect to 0,0.

That’s kind of just a guess, though. We are in uncharted territory.

1 Like

I see there’s a new release of this lemur-utility library I was using for alternate viewports that was released a few months after I made this thread 4 years ago, although I am unsure if the original author @NemesisMate was still around at that point to see this thread or not, I probably should have also mentioned them back when I made this thread. Maybe upgrading could fix this issue and/or the screenshot issue, but I am not particularly hopeful.

It looks like quite a big library and I had to include the entire utility library for the viewport specific stuff to work, so it would probably be non-trivial to find out what could be breaking things…

Are there any other lemur implementations for setting up viewports? I thought there were other users who have set up scroll containers with lemur so I am curious what they used or how they did it.

Edit: mis-tagged the wrong user when mentioning the author

I see here there is this ViewPortDemoState that doesn’t rely on any extra libraries like the one I used:

Instead of trying to debug this lemur-utils library I was using, I will probably just make my own custom implementation based off of this example eventually, and hopefully that will fix the issues.

And if not, I will at least be in a better place to troubleshoot the issues since I will be debugging my own code as opposed to trying to debug a whole utility library coded by someone else. But since this isn’t a severe issue I probably won’t get around to doing this for at least a while.


In the meantime, if there are any other lemur users with a working implementation of scrollable-viewports, I would greatly appreciate hearing from you. :slightly_smiling_face:

1 Like

Not scrollable but I did have some code that rendered a UI off screen for painting onto a quad. If that’s not what you’re doing then I think I misunderstood the issue.

If all you are doing is rendering a second scene in a regular viewport (ie: different root on a ViewPort) then I’m even more convinced that the screen shot app state problem is a call-order issue.

…and yeah, I suspect the library you were using was resizing your components for you.

1 Like

I think I am actually doing both of those things with alternate viewports.

Currently I am using that library’s Viewport2D class for a scrollable list box component.

And I am also using the library’s Viewport3D class for rendering a scene to another viewport to show an animated view of your characer’s face (and your target’s) in a frame near the status bars in the hud.

So if you’re able to share it then I think that should do almost exactly what I need for rendering animated faces in a frame on the hud.