i can´t create a scroll panel using lemur and jmonkey
this is my code
my optons class
package mygame;
import com.jme3.app.Application;
import com.jme3.app.state.BaseAppState;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
import com.simsilica.lemur.ActionButton;
import com.simsilica.lemur.Axis;
import com.simsilica.lemur.CallMethodAction;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.FillMode;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.PasswordField;
import com.simsilica.lemur.TabbedPanel;
import com.simsilica.lemur.TextField;
import com.simsilica.lemur.component.SpringGridLayout;
import com.simsilica.lemur.style.ElementId;
import mygame.panel.ViewportPanel;
/**
*
* @author Pedro Alves
*/
public class OptionsState extends BaseAppState {
private Container loginPanel;
private TextField nameField;
private PasswordField passwordfield;
public OptionsState() {
}
@Override
protected void initialize(Application app) {
loginPanel = new Container();
loginPanel.addChild(new Label("Options", new ElementId("title")));
Container props = loginPanel.addChild(new Container(new SpringGridLayout(Axis.Y, Axis.X, FillMode.None, FillMode.Last)));
props.setBackground(null);
TabbedPanel tabs = new TabbedPanel();
Container panel1 = tabs.addTab("Game Options", new Container());~
ViewportPanel panel= new ViewportPanel(panel1.getElementId(),panel1.getStyle());
panel.attachScene(panel1);
?
panel1.addChild(new Label("Game Options"));
panle1.addChild(panel);
Container panel2 = tabs.addTab("Graphic Options", new Container());
panel2.addChild(new Label("Grapicos options"));
Container panel3 = tabs.addTab(" Audio Options", new Container());
panel3.addChild(new Label("Audio"));
Container panel4 = tabs.addTab("Key Mapping ", new Container());
panel4.addChild(new Label("Key Mapping"));
loginPanel.addChild(tabs);
/* props.addChild(new Label("Username:"));
nameField = props.addChild(new TextField(System.getProperty("user.name")), 1);
props.addChild(new Label("Password:"));
passwordfield=props.addChild(new PasswordField(System.getProperty("Pass.word")), 1);
Container buttons = loginPanel.addChild(new Container(new SpringGridLayout(Axis.X, Axis.Y)));
*/ // buttons.setBackground(null);
//buttons.setLayout(new SpringGridLayout(Axis.X, Axis.Y));
// buttons.addChild(new ActionButton(new CallMethodAction("Join", this, "join")));
// buttons.addChild(new ActionButton(new CallMethodAction("Cancel", this, "cancel")));
float scale = 1.5f * getState(MainMenuState.class).getStandardScale();
loginPanel.setLocalScale(scale);
Vector3f prefs = loginPanel.getPreferredSize().clone();
prefs.x = Math.max(300, prefs.x);
loginPanel.setPreferredSize(prefs.clone());
// Now account for scaling
prefs.multLocal(scale);
int width = app.getCamera().getWidth();
int height = app.getCamera().getHeight();
loginPanel.setLocalTranslation(width * 0.5f - prefs.x * 0.5f, height * 0.5f + prefs.y * 0.5f, 10);
}
@Override
protected void cleanup(Application app) {
}
@Override
protected void onEnable() {
Node root = ((Main)getApplication()).getGuiNode();
root.attachChild(loginPanel);
}
@Override
protected void onDisable() {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
loginPanel.removeFromParent();
}
}
viewportpanel class
import com.jme3.app.Application;
import com.jme3.app.state.AppStateManager;
import com.jme3.bounding.BoundingBox;
import com.jme3.light.Light;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import com.simsilica.lemur.Panel;
import com.simsilica.lemur.core.AbstractGuiControlListener;
import com.simsilica.lemur.core.GuiControl;
import com.simsilica.lemur.event.BasePickState;
import com.simsilica.lemur.event.PickState;
import com.simsilica.lemur.style.ElementId;
import org.slf4j.LoggerFactory;
/**
*
* @author xelun
*/
public class ViewportPanel extends Panel {
protected ViewPort viewport;
protected Node viewPortNode;
// protected Vector3f lastSize = new Vector3f();
protected Camera cam;
protected RenderManager renderManager;
protected AppStateManager stateManager;
Vector3f camOrigin = new Vector3f();
// Vector3f boundsExtents = new Vector3f();
Vector3f camOffset = new Vector3f();
protected boolean autoZoom = true;
private Node rootNode;
public ViewportPanel(AppStateManager stateManager, ElementId elementid, String style) {
this(elementid, style);
setStateManager(stateManager);
}
public ViewportPanel(ElementId elementid, String style) {
super(elementid, style);
viewPortNode = new Node("Root Node ViewPort Panel");
// setPreferredSize(new Vector3f(1, 1, 1)); // Patch to the first NaN size value. Try with setSize instead?
getControl(GuiControl.class).addListener(new AbstractGuiControlListener() {
@Override
public void reshape(GuiControl source, Vector3f pos, Vector3f size) {
open();
setViewPortSize(size);
}
});
addControl(new AbstractControl() {
@Override
protected void controlUpdate(float tpf) {
if(viewport != null) {
// Vector3f size = ViewportPanel.this.getSize();
//// LoggerFactory.getLogger(this.getClass()).debug("Size: {}.", size);
// if(!size.equals(lastSize)) {
// lastSize.set(size);
// setViewPortSize(lastSize);
// }
viewPortNode.updateLogicalState(tpf);
if(autoZoom) {
if(viewPortNode.getQuantity() > 0) {
Spatial child = viewPortNode.getChild(0);
viewPortNode.updateModelBound();
//FIXME: When rotating, the bounds dimension can change, making the y be bigger than the x or z and viceverse, showing an undesired zoom-in-out effect.
BoundingBox bb = (BoundingBox) child.getWorldBound();
if (bb != null) {
float x = bb.getXExtent();
float y = bb.getYExtent();
float z = bb.getZExtent();
float dimensions;
float bigger = x;
if(z > bigger) {
bigger = z;
}
if (y > bigger) {
bigger = y;
dimensions = cam.getFrustumTop() - cam.getFrustumBottom();
} else {
dimensions = cam.getFrustumRight() - cam.getFrustumLeft();
}
// Teoria de los triangulos semejantes
float distance = (bigger * cam.getFrustumNear()) / (dimensions / 2f);
// LoggerFactory.getLogger(this.getClass()).debug("BB center: {}, extents: {}, frustums: [b:{}, t:{}, r:{}, l:{}]distance: {}.",
// bb.getCenter(),
// bb.getExtent(new Vector3f()),
// cam.getFrustumBottom(),
// cam.getFrustumTop(),
// cam.getFrustumRight(),
// cam.getFrustumLeft(),
// distance);
//TODO: Set the correct equation in relation with origin to know the perfect cam distance.
camOffset.set(bb.getCenter()).addLocal(camOrigin).addLocal(0, 0, distance + bigger);
if (!cam.getLocation().equals(camOffset)) {
// LoggerFactory.getLogger(this.getClass()).debug("Setting cam location: {}.", camOffset);
//TODO: Smooth this movement.
cam.setLocation(camOffset);
}
}
}
}
viewPortNode.updateGeometricState();
}
// else {
// open();
// }
// LoggerFactory.getLogger(this.getClass()).debug("Geom location: {}, scale: {}.", geom.getWorldTranslation(), geom.getWorldScale());
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
// viewPortNode.updateGeometricState();
}
});
}
/**
* If changed to public, other operations with the statemanager should be taken in account.
* @param stateManager
*/
private void setStateManager(AppStateManager stateManager) {
Application app = stateManager.getApplication();
setCam(app.getCamera().clone());
setRenderManager(app.getRenderManager());
this.stateManager = stateManager;
}
public void setCam(Camera cam) {
this.cam = cam.clone();
this.cam.setFrustumPerspective(40, 1, 0.05f, 500f);
// this.cam.setLocation(Vector3f.ZERO);
this.cam.setLocation(new Vector3f(0, 0, 10));
}
public void setCamPosition(Vector3f position) {
//If autozoom, this location works as the camera origin
if(!autoZoom) {
this.cam.setLocation(position);
}
camOrigin.set(position);
}
public void setRenderManager(RenderManager renderManager) {
this.renderManager = renderManager;
}
private void open() {
if(viewport != null) {
return;
}
// LoggerFactory.getLogger(this.getClass()).debug("Opening viewport panel");
setViewPort(renderManager.createPostView("viewportPanel", cam));
/*
* Se ha puesto que use la layer "PICK_LAYER_GUI" para que reconozca los eventos de ratón, de la otra forma
* no los reconoce si hay algún panel que tome eventos (aunque no los consuma), tanto debajo como encima de
* él graficamente.
*/
stateManager.getState(BasePickState.class).addCollisionRoot(viewPortNode, viewport, PickState.PICK_LAYER_GUI);
// Ensure that it gets closed when it is detached from the scenegraph.
Node rootParent = null;
Node parent = getParent();
while(parent != null) {
rootParent = parent;
parent = parent.getParent();
}
if(rootParent != null) {
ViewportPanel.this.rootNode = rootParent;
rootParent.addControl(new AbstractControl() {
@Override
protected void controlUpdate(float tpf) {
Node rootParent = null;
Node parent = ViewportPanel.this.getParent();
while(parent != null) {
rootParent = parent;
parent = parent.getParent();
}
if(rootParent != spatial) {
close();
spatial.removeControl(this);
}
}
@Override
public void setSpatial(Spatial spatial) {
if(spatial == null) {
if(viewport != null) {
LoggerFactory.getLogger(this.getClass()).warn("Shouldn't be removing this control manually!");
// this.spatial.addControl(this); // Readd??, or just better let the developer see problem.
}
// close();
}
super.setSpatial(spatial);
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
}
});
}
}
private void close() {
LoggerFactory.getLogger(this.getClass()).debug("Closing viewport panel");
clearViewport();
// renderManager.removePostView(viewport);
//
// stateManager.getState(BasePickState.class).removeCollisionRoot(viewport);
}
protected void clearViewport() {
if(viewport == null) {
return;
}
renderManager.removePostView(viewport);
stateManager.getState(BasePickState.class).removeCollisionRoot(viewport);
// lastSize.set(0, 0, 0);
viewport = null;
}
protected void setViewPort(ViewPort viewport) {
clearViewport();
this.viewport = viewport;
if(viewport == null) {
return;
}
this.viewport.setClearFlags(false, true, true);
// This two lines shouldn't be needed... hm....
viewPortNode.updateModelBound();
viewPortNode.updateGeometricState();
//////////////////////////
this.viewport.attachScene(viewPortNode);
}
protected void setViewPortSize(Vector3f size) {
if(viewport == null) {
return;
}
LoggerFactory.getLogger(this.getClass()).debug("VIEWPORT SIZE: {}", size);
// Vector2f aux2f = new Vector2f();
Vector3f aux3f = Vector3f.UNIT_Z.negate();
cam.lookAtDirection(aux3f, Vector3f.UNIT_Y);
Vector3f pos = this.getWorldTranslation();
// float h = Display.getHeight();
// float w = Display.getWidth();
float h = cam.getHeight();
float w = cam.getWidth();
float top = (pos.y - 10 ) / h;
float bottom = (pos.y - size.y + 10) / h;
float left = (pos.x + 10) / w;
float right = (pos.x + size.x - 10) / w;
// float top = (pos.y ) / h;
// float bottom = (pos.y - size.y ) / h;
// float left = (pos.x ) / w;
// float right = (pos.x + size.x ) / w;
cam.setViewPort(left, right, bottom, top);
// cam.setFrustumPerspective(40, size.x/size.y, 0.05f, 500f);
// viewport.getCamera().setParallelProjection(true);
updatePerspective(size);
}
protected void updatePerspective(Vector3f size) {
cam.setFrustumPerspective(40, size.x/size.y, 0.05f, 500f);
}
public boolean isAutoZoom() {
return autoZoom;
}
public void setAutoZoom(boolean autoZoom) {
this.autoZoom = autoZoom;
}
@Override
public void addLight(Light light) {
viewPortNode.addLight(light);
}
public void attachScene(Spatial spatial) {
viewPortNode.detachAllChildren();
viewPortNode.attachChild(spatial);
LoggerFactory.getLogger(this.getClass()).debug("Attaching to scene");
}
}
i have this error
java.lang.NullPointerException
at mygame.panels.ViewportPanel.open(ViewportPanel.java:386) ~[classes/:?]
at mygame.panels.ViewportPanel.access$000(ViewportPanel.java:58) ~[classes/:?]
at mygame.panels.ViewportPanel$1.reshape(ViewportPanel.java:120) ~[classes/:?]
at com.simsilica.lemur.core.GuiControl.setSize(GuiControl.java:323) ~[lemur-1.10.1.jar:?]
at com.simsilica.lemur.component.SpringGridLayout$Entry.setSize(SpringGridLayout.java:537) ~[lemur-1.10.1.jar:?]
at com.simsilica.lemur.component.SpringGridLayout.reshape(SpringGridLayout.java:310) ~[lemur-1.10.1.jar:?]
at com.simsilica.lemur.core.GuiControl.setSize(GuiControl.java:316) ~[lemur-1.10.1.jar:?]
at com.simsilica.lemur.component.BorderLayout.reshape(BorderLayout.java:181) ~[lemur-1.10.1.jar:?]
at com.simsilica.lemur.core.GuiControl.setSize(GuiControl.java:316) ~[lemur-1.10.1.jar:?]
at com.simsilica.lemur.component.BorderLayout.reshape(BorderLayout.java:181) ~[lemur-1.10.1.jar:?]
at com.simsilica.lemur.core.GuiControl.setSize(GuiControl.java:316) ~[lemur-1.10.1.jar:?]
at com.simsilica.lemur.component.SpringGridLayout$Entry.setSize(SpringGridLayout.java:537) ~[lemur-1.10.1.jar:?]
at com.simsilica.lemur.component.SpringGridLayout.reshape(SpringGridLayout.java:310) ~[lemur-1.10.1.jar:?]
at com.simsilica.lemur.core.GuiControl.setSize(GuiControl.java:316) ~[lemur-1.10.1.jar:?]
at com.simsilica.lemur.core.GuiControl.revalidate(GuiControl.java:417) ~[lemur-1.10.1.jar:?]
at com.simsilica.lemur.core.GuiControl.controlUpdate(GuiControl.java:384) ~[lemur-1.10.1.jar:?]
at com.jme3.scene.control.AbstractControl.update(AbstractControl.java:128) ~[jme3-core-3.1.0-stable.jar:3.1-stable]
at com.jme3.scene.Spatial.runControlUpdate(Spatial.java:737) ~[jme3-core-3.1.0-stable.jar:3.1-stable]
at com.jme3.scene.Spatial.updateLogicalState(Spatial.java:880) ~[jme3-core-3.1.0-stable.jar:3.1-stable]
at com.jme3.scene.Node.updateLogicalState(Node.java:230) ~[jme3-core-3.1.0-stable.jar:3.1-stable]
at com.jme3.scene.Node.updateLogicalState(Node.java:241) ~[jme3-core-3.1.0-stable.jar:3.1-stable]
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:243) ~[jme3-core-3.1.0-stable.jar:3.1-stable]
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151) ~[jme3-lwjgl-3.1.0-stable.jar:3.1-stable]
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:193) ~[jme3-lwjgl-3.1.0-stable.jar:3.1-stable]
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:232) ~[jme3-lwjgl-3.1.0-stable.jar:3.1-stable]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_111]
can someone help-me