Code sample for tabbed pane?

Hi,
I’d like to show a tabbed pane full of options. Something like that of SimArboreal or Dragonfly Odissey. Is there some code I can take a look at? Thanks! :smile:

The SimArboreal source is available as is the source for the IsoSurfaceDemo. Under here:
https://code.google.com/p/simsilica-tools/source/browse/

They use a Lemur extension called PropertyPanel that is under the Lemur source tree.
https://code.google.com/p/jmonkeyplatform-contributions/source/browse/#svn%2Ftrunk%2FLemur%2Fextensions%2FLemurProps

It supports a few different property types.

For example, you can see how it is called here:
https://code.google.com/p/simsilica-tools/source/browse/trunk/IsoSurfaceDemo/src/main/java/com/simsilica/iso/demo/PostProcessingState.java#142

…that’s the start of the code that sets up the properties for the water filter.

1 Like

TabbedPane is part of Lemur itself (totally missed the mention in the original post) and you can also see how it’s used in that same file I think.

Yeah, 2 lines above:
https://code.google.com/p/simsilica-tools/source/browse/trunk/IsoSurfaceDemo/src/main/java/com/simsilica/iso/demo/PostProcessingState.java#139

1 Like

Thanks! Downloaded Lemur.jar, but still have unresolved dependencies:

com.simsilica.fx
com.simsilica.lemur.props

What/where should I download that?

props is the property panel stuff under lemur/extensions.

fx is the sim-fx stuff under simsilica tools (sim-fx is sibling to IsoSurfaceDemo, etc.)

I did

statemanager.attach(new PostProcessingState());

And got this:

Grave: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException
	at com.simsilica.lemur.Container.<init>(Container.java:88)
	at com.simsilica.lemur.Container.<init>(Container.java:68)
	at prototype.appstates.PostProcessingState.initialize(PostProcessingState.java:108)
	at com.simsilica.lemur.event.BaseAppState.initialize(BaseAppState.java:75)
	at com.jme3.app.state.AppStateManager.initializePending(AppStateManager.java:251)
	at com.jme3.app.state.AppStateManager.update(AppStateManager.java:281)
	at com.jme3.app.SimpleApplication.update(SimpleApplication.java:239)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)
	at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:185)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:228)
	at java.lang.Thread.run(Thread.java:744)

It crashes when trying to instance a Container… :scream:

Did you initialize GuiGlobals? Take a look at the lemur demo or any of the lemur gems.

You’re obviously right! Also imported some other required lib… now when I do this:

    getState(SettingsPanelState.class).getParameterTabs().addTab("Filters", main);               

I get this:

Grave: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException
	at prototype.appstates.PostProcessingState.initialize(PostProcessingState.java:109)
	at com.simsilica.lemur.event.BaseAppState.initialize(BaseAppState.java:75)

I tried to figure out myself what I missed, but I failed :frowning:

Maybe you didn’t also add the SettingsPanelState?

The app you are cribbing from organizes things in a specific way so that other states can easily add their settings to one master panel. If you don’t need that then you can just make your own tab pane and add it right to the gui node or whatever.

In my case, I have a master SettingsPanelState that sets up a main HUD UI for settings and creates a master tab pane and so on. You could maybe copy that too if you need something similar.

If you don’t need that sort of collaboration between multiple settings panels then it might not be worth it to copy that class too. Though in my apps I tend to always have at least a HudState to more easily manage a global screen space for HUD UI thingies.

Thanks! I didn’t attach the Settings appstate. Finally managed to make it run! :monkey_face:
Now I have a starting place to hack my own settings…

Great. Let us know how it goes. :slight_smile:

Going rather well :wink:
Your code provides nice examples about beans and JME Capsule (which is the obvious next logical step). I’ve also found this post which does 90% of what I want to do:

  1. How can I make this script work on my game?
  2. Are there other styles besides glass? Where should I start for building my own style?
  3. I need a text field input component… where can I find it?
  4. How can I move the Panel around like you did on your cool demos?

Thanks! :slight_smile:

  1. Well… with lots of work. Mythruna has a whole layer that abstracts the UI ‘model’ into such a structure and then generates a UI from that. It’s also had major changes at least 2 times as I realized I did some things in a crazy way, re: styles and events, as just two examples. But anyway, I did that with Groovy and I have some loose plans to create a similar thing for Lemur (but UI direct instead of an abstracted model). It doesn’t take too many additions to make Groovy have a more DSL-like feel for something like this:

    container(style:“glass”) {
    label(“Title”, “glass”)
    tabbedPanel(style:“glass”) {

    }
    }

I just have to do some serious design work on it first to make sure I’ve covered the bases.

  1. Glass is the only built in style right now but I’d like more. I want to do a metallic theme and perhaps a ‘wood’ theme at some point. Stone would be nice, too. To do wood and stone as I’d like I need to more easily support tileable textures in the background components.

For a style, basically anything you’d do to a GUI element directly can be moved into a style. You can get an idea of how that’s done by looking at the existing glass style. It’s in the Lemur source… called glass-styles.groovy or something like that.

The way the style resource mechanism works you can even build this up from multiple style files. It just has to be called the same and be in the same ‘package’. For example, Lemur-proto adds some additional glass styling by simply having its own glass-styles.groovy located in the com/simsilica/lemur/style/base directory. Obviously, your own resource-based styles (ie: loaded as class resources) can use the same mechanism if it wants to.

  1. TextField

  2. There is a DragHandler that you can attach or just look at its source if, say, you need it to move a different element than what it’s actually attached to (for example, a title bar that moves a window). Right now it has to be attached to the thing that drags. I want to make it more flexible out of the box but it works for what I needed it for so far. The demo included in the Lemur source uses the drag handler.

Hope it helps.

(Slowly) going forward :stuck_out_tongue:

That DisplaySettings, is a Mythruna-specific class? Where can I find the jME equivalent?

Thanks!

Yeah, it’s a set of code I wrote for Mythruna to handle the graphics settings. I think DisplaySettings wraps the JME and lejgl code because JME doesn’t provide access to some of the OpenGL information.

Like, I have code like:

public void initializeOpenGlInfo() {
    try {
        vendor = GL11.glGetString(GL11.GL_VENDOR);
        System.out.println( "Vendor:" + vendor ); 

        openGlVersion = GL11.glGetString(GL11.GL_VERSION);
        System.out.println( "OpenGL Version:" + openGlVersion );

        renderer = GL11.glGetString(GL11.GL_RENDERER);
        System.out.println( "Renderer:" + renderer );

        if (GLContext.getCapabilities().OpenGL20) {
            glslVersion = GL11.glGetString(GL20.GL_SHADING_LANGUAGE_VERSION);
            System.out.println( "GLSL Ver:" + glslVersion);
            
            int split = glslVersion.indexOf(' ');
            if( split >= 0 )
                glslVersion = glslVersion.substring(0, split);
            System.out.println( "GLSL Ver:" + glslVersion);
        }
    } catch( Exception e ) {
        log.error( "Error retrieving OpenGL info", e );
    }     
}

Essentially catching what JME logs as info during startup because I want to actually know it at runtime and JME doesn’t provide a way to get it. My DisplaySettings also does some stuff to manage the resolutions I allow the user to select as a subset of what’s actually available and so on.

1 Like

:rage: :-1:

However your code was exactly what I needed. I’ve also “discovered” the lemur gems, digging into it! :wink:
Are you planning further episodies?

Yeah, I just need to get inspired with an idea and have the time at the same time. :slight_smile:

Running the scene picking, but when I move the mouse I also move the camera… Tried to disable the CameraMovementState but did not help… :frowning:

I might have to see code to help. Or you might be able to look at the IsoSurfaceDemo and see how it does it… it lets you toggle between camera movement and HUD selection by pressing the space bar.

Semi-solved with a trick learned from @t0neg0d:

flyCam.setDragToRotate(true); 

:smiling_imp:
Will however check your source for a “proper” solution.

How did you get the GPU name (nv4 disp)? Can’t find the right GL getString…