NPE related to Artemis in Libgdx project - libgdx

Update:
WorldConfiguration and World are still the same,
WorldConfiguration setup = new WorldConfigurationBuilder()
.with(new HelloSystemArtemis())
.with(new RenderSystem(batch, environment))
.with(new BulletSystem(this))
.with(new PlayerSystem(perspectiveCamera, batch, gameUi, this))
.with(new AthmosphereSystem(modelComponent,
bulletComponent))
.with(new MovementSystem(this))
.with(new StatusSystem(this))
.with(new EnemySystem(this))
.build();
World world = new World(setup);
world.setDelta(delta);
int entityId = world.create();
world.edit(entityId).create(HelloComponentArtemis.class).message = "\n\rHello Oxyddians!\n\r";
Decided to post full code for clarity reason, in fact can't explain from where the problem is coming, even if I got errors that point me to
#All({ModelComponentArtemis.class, ModelComponentArtemis.class})
public class AthmosphereSystem extends BaseSystem {
private static OxyddiA game;
private static Assets assets = new Assets();
private ComponentMapper<ModelComponentArtemis> mc;
private ComponentMapper<BulletComponentArtemis> bc;
public AthmosphereSystem(ComponentMapper<ModelComponentArtemis> mc,
ComponentMapper<BulletComponentArtemis> bc) {
this.mc = mc;
this.bc = bc;
}
#Override
protected void processSystem() {
int entity = world.create();
ModelComponentArtemis mc = new ModelComponentArtemis(assets.Athmosphere,0,0,0);
mc.create(entity); //Not working
BulletComponentArtemis bc = new BulletComponentArtemis();
btCollisionShape shape = Bullet.obtainStaticNodeShape(assets.Athmosphere.nodes);
bc.bodyInfo = new btRigidBody.btRigidBodyConstructionInfo(0, null, shape, Vector3.Zero);
bc.body = new btRigidBody(bc.bodyInfo);
bc.body.userData = entity;
bc.motionState = new MotionState(mc.instance.transform);
((btRigidBody) bc.body).setMotionState(bc.motionState);
bc.create(entity); //Not working
return entity; //Not working as well
}
}
ModelComponent used in this approach
public class ModelComponentArtemis extends Component {
public Model model;
public ModelInstance instance;
public ModelComponentArtemis(Model model, float x, float y, float z)
{
this.model = model;
this.instance = new ModelInstance(model, new Matrix4().setToTranslation(x, y, z));
}
public void reset() {
}
}
BulletComponent used in this approach
public class BulletComponentArtemis extends Component {
public MotionState motionState;
public btRigidBody.btRigidBodyConstructionInfo bodyInfo;
public btCollisionObject body;
public Model model;
public void init() {
ModelComponentArtemis modelComponent = new ModelComponentArtemis(model,0,0,0);
BulletComponentArtemis bulletComponent = new BulletComponentArtemis();
btCollisionShape shape = Bullet.obtainStaticNodeShape(model.nodes);
bulletComponent.bodyInfo = new btRigidBody.btRigidBodyConstructionInfo(0, null, shape, Vector3.Zero);
bulletComponent.body = new btRigidBody(bulletComponent.bodyInfo);
Object bCuD = null;
bulletComponent.body.userData = bCuD;
bulletComponent.motionState = new MotionState(modelComponent.instance.transform);
((btRigidBody) bulletComponent.body).setMotionState(bulletComponent.motionState);
}
public void reset() {
}
}
And of course the BulletSystem used in this project
#All(ModelComponentArtemis.class)
public class BulletSystem extends EntitySystem
{
public Entity e;
public final btCollisionConfiguration collisionConfiguration;
public final btCollisionDispatcher dispatcher;
public final btBroadphaseInterface broadphase;
public final btConstraintSolver solver;
public final btDiscreteDynamicsWorld collisionWorld;
public GameWorld gameWorld;
public PreGameWorld preGameWorld;
private final btGhostPairCallback ghostPairCallback;
public final int maxSubSteps = 5;
public final float fixedTimeStep = 0.2f / 60f;
private EntityContactListener myContactListener;
public BulletSystem(GameWorld gameWorld)
{
super(Aspect.all(ModelComponentArtemis.class));
this.gameWorld = gameWorld;
myContactListener = new EntityContactListener();
myContactListener.enable();
collisionConfiguration = new btDefaultCollisionConfiguration();
dispatcher = new btCollisionDispatcher(collisionConfiguration);
broadphase = new btAxisSweep3(new Vector3(-1000, -1000, -1000), new Vector3(1000, 1000, 1000));
solver = new btSequentialImpulseConstraintSolver();
collisionWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
ghostPairCallback = new btGhostPairCallback();
broadphase.getOverlappingPairCache().setInternalGhostPairCallback(ghostPairCallback);
this.collisionWorld.setGravity(new Vector3(0f, -0.5f, 0f));
}
public BulletSystem(PreGameWorld preGameWorld)
{
this.preGameWorld = preGameWorld;
myContactListener = new EntityContactListener();
myContactListener.enable();
collisionConfiguration = new btDefaultCollisionConfiguration();
dispatcher = new btCollisionDispatcher(collisionConfiguration);
broadphase = new btAxisSweep3(new Vector3(-1000, -1000, -1000), new Vector3(1000, 1000, 1000));
solver = new btSequentialImpulseConstraintSolver();
collisionWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
ghostPairCallback = new btGhostPairCallback();
broadphase.getOverlappingPairCache().setInternalGhostPairCallback(ghostPairCallback);
this.collisionWorld.setGravity(new Vector3(0f, -0.5f, 0f));
}
public void update(float deltaTime)
{
collisionWorld.stepSimulation(deltaTime, maxSubSteps, fixedTimeStep);
}
protected void processSystem(int entityId) {
this.world.getEntity(entityId).getComponent(BulletComponentArtemis.class);
}
#Override
protected void processSystem() {
}
public void dispose()
{
collisionWorld.dispose();
if (solver != null) solver.dispose();
if (broadphase != null) broadphase.dispose();
if (dispatcher != null) dispatcher.dispose();
if (collisionConfiguration != null)
collisionConfiguration.dispose();
ghostPairCallback.dispose();
}
}
With all that in mind, I know I just can't find any solution,
Maybe it will be clearer like that for anyone wishing to help
Thanks anyawy.

Couple of things to note:
you don't need to inject entity instances
working with Entity and EntityEdit is slower than working with int and ComponentMapper/Archetype/EntityTransmuter, but fine for the beginning.
What you probably want to do is creating an AtmosphereSystem (extending BaseSystem) and create the entity within the initialize method or offer a public method (non-static).
If you need to call those entity factory methods, just inject the AtmosphereSystem (or anything extending BaseSystem) by adding a field "AtmosphereSystem atmosphereSytem;" inside any other BaseSystem.
See this gist for a similar use case (factory methods for creating entities).

Related

JavaFX: can't call a Controller function from anoher class

I have this simple controller:
#FXML
private VBox VVbox;
private ButtonBar newNode = new ButtonBar();
private Circle c= new Circle();
private Button b= new Button();
private Label lname = new Label();
private Label lIMEI = new Label();
private Label lroot = new Label();
#Override
public void initialize(URL location, ResourceBundle resources) {
// TODO Auto-generated method stub
}
public void create(String imei){
System.out.println(imei);
newNode = new ButtonBar();
b = setButtonSpec(imei + "btnHavefun");
c = setCircleSpec(imei + "statuOnline");
lname= setLNameSpec(imei + "name");
lIMEI = setLIMEISpec(imei + "Imei");
lroot = setLrootSpec(imei + "root");
newNode.getButtons().addAll(lname,lIMEI,lroot,b,c);
VVbox.getChildren().addAll(newNode) ;
}
this is my main:
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("Thypheon Application");
Connection connessione = new Connection();
Thread t = new Thread(connessione);
initDesign();
t.start();
}
public static void main(String[] args) {
launch(args);
}
public void initDesign(){
try {
loader2= new FXMLLoader(getClass().getResource("Design.fxml"));
AnchorPane anchor = (AnchorPane) loader2.load();
rootLayout.setCenter(anchor);
controller = loader2.getController();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
As you can see in main I start a new thread in which I would like a Controller function.
public class Connection implements Runnable {
String result;
Controller controller = new Controller();
public void run() {
controller.create("TEST123");
}
Everything seems to be inside create function until The last line is executed: VVbox.getChildren().addAll(newNode) ;
Probably because it has a reference to the FXML file.. How can I solve this?
Yes you are right. The controller that you instantiate yourself does not get its fields injected by FXML. To obtain a reference to the controller the following is a possible solution:
public Controller initDesign(){
// some FXML loading code
return controller;
}
You will then need to modify your Connection to take a Controller object in the constructor:
class Connection ... {
Controller contoller;
public Connection(Controller controller) {
this.controller = controller;
}
}
Finally in start() you will need:
Controller controller = initDesign();
Connection connessione = new Connection(controller);
Thread t = new Thread(connessione);
t.start();
However, there is more than one issue with your design.
Your Connection instance is NOT run on JavaFX Application Thread. Therefore, any attempt to modify the scene graph from a different thread (e.g. your call to VVbox.getChildren().addAll(newNode);) will cause an error.
The start() method is called from JavaFX Thread. There is no need to create a new thread. I am unsure of the intentions, but you can call your create() from Controller in start() to be executed on JavaFX Thread.

LIBGDX - Touchpad

I can't figure out why I'm not able to see my thouchpad that I've created, but it works. Here is the code
package com.mygdx.game;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Touchpad;
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
public class AnalogStick extends Touchpad {
private static Touchpad.TouchpadStyle touchpadStyle;
private static Skin touchpadSkin;
private static Drawable touchBackground;
private static Drawable touchKnob;
public AnalogStick(float x, float y) {
super(10, getTouchpadStyle());
setBounds(15, 15, 200, 200);
setPosition(x,y);
}
private static Touchpad.TouchpadStyle getTouchpadStyle() {
touchpadSkin = new Skin();
touchpadSkin.add("touchBackground", new Texture("touchBackground.png"));
touchpadSkin.add("touchKnob", new Texture("touchKnob.png"));
touchpadStyle = new Touchpad.TouchpadStyle();
touchBackground = touchpadSkin.getDrawable("touchBackground");
touchKnob = touchpadSkin.getDrawable("touchKnob");
touchpadStyle.background = touchBackground;
touchpadStyle.knob = touchKnob;
return new TouchpadStyle();
}
}
And in my Create class I use this code for adding it into the stage
asMove = new AnalogStick(15,15);
Gdx.input.setInputProcessor(stage);
playerTexture = new Texture(Gdx.files.internal("player.png"));
playerSprite = new Sprite(playerTexture);
stage = new Stage(new ScreenViewport(), batch);
stage.addActor(asMove);
Gdx.input.setInputProcessor(stage);
And in the render method this code
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
There seems to be a problem with your getTouchpadStyle method: it initializes touchpadStyle but instead of returning it, it returns a new and empty style object. In other words, Replace
return new TouchpadStyle();
with
return touchpadStyle;

How can I add items to ChartSeries in my BarChartModel?

I'm using PrimeFaces, in order to build a BarChart. My goal is to compare some Testprojects to each other. Each Bar should be a Testproject from which you can read off the different Phases in which the project is situated.
My question is: I have a View where I can add new Testprojects. When I add one, there is a new Bar. But If I want to add another one, the old Bar is owerwritten. Of course It is, because of set... but I would like to do something like add(testprojectProducer.getTestproject().getName(), 1).
The chart schould be able to remembe the old bar and add the new one. Is there a way or do I have to say goodby to primefaces and build my own chart?
Here is my code:
#ManagedBean
public class ChartView implements Serializable {
private static final long serialVersionUID = 9181815723688700642L;
private BarChartModel barModel;
#Inject
private TestprojectProducer testprojectProducer;
#PostConstruct
public void init() {
createBarModel();
new ArrayList<String>();
}
private BarChartModel initBarModel() {
BarChartModel model = new BarChartModel(); //Diagram
ChartSeries cs= new ChartSeries(); // Balken
cs.setLabel("Testprojekte");
cs.set("Testprojekt 1",5);
cs.set(testprojectProducer.getTestproject().getName(), 1);
model.addSeries(cs);
return model;
}
public void createBarModel() {
barModel =initBarModel();
barModel.setTitle("");
barModel.setLegendPosition("");
barModel.setSeriesColors("C80000");
Axis xAxis = barModel.getAxis(AxisType.X);
xAxis.setLabel("Testprojekte");
Axis yAxis = barModel.getAxis(AxisType.Y);
yAxis.setLabel("Phasen");
yAxis.setMin(0);
yAxis.setMax(7);
}
public BarChartModel getBarModel() {
return barModel;
}
public void setBarChartModel(BarChartModel barModel){
this.barModel= barModel;
}
}
I hope there is a solution to my problem. Thank you!
I resolved my problem. When you use 'HashMap', then It's not that hard:
private BarChartModel initBarModel() {
BarChartModel model = new BarChartModel();
ChartSeries cc = new ChartSeries();
cc.setLabel("Testprojekte");
HashMap<Object, Number> groupData = new HashMap<Object, Number>();
for (int i = 0; i < 3; i++) {
groupData.put(testProjectListProducer.getList().get(i).getName(), 2);
}
cc.setData(groupData);
model.addSeries(cc);
return model;
}

How to run a javaFX MediaPlayer in swing?

I've made a simple Media Player for an application I'm working on, the problem is that I thought that you could simply integrate JavaFX into Swing. Which is not the case. I have been searching for a solution to this problem and tried to use this website: http://docs.oracle.com/javafx/2/swing/jfxpub-swing.htm
The problem is that even though I have the website that explains how to put the code together, I still don't understand how. Here is the mediaplayer and I plan to integrate it into my Swing code, so that I can call the media player when a button is clicked. Here is all my code for the media player and if anyone can share some light on how to integrate it into my Swing code i.e my GUI, I would probably have to kiss you through the computer.
public class Player extends Application{
private boolean atEndOfMedia = false;
private final boolean repeat = false;
private boolean stopRequested = false;
private Duration duration;
private Label playTime;
private Slider volumeSlider;
#Override
public void start(final Stage stage) throws Exception {
stage.setTitle("Movie Player");//set title
Group root = new Group();//Group for buttons etc
final Media media = new Media("file:///Users/Paul/Downloads/InBruges.mp4");
final MediaPlayer playa = new MediaPlayer(media);
MediaView view = new MediaView(playa);
//Slide in and out and what causes that.
final Timeline slideIn = new Timeline();
final Timeline slideOut = new Timeline();
root.setOnMouseEntered(new javafx.event.EventHandler<javafx.scene.input.MouseEvent>() {
#Override
public void handle(MouseEvent t) {
slideIn.play();
}
});
root.setOnMouseExited(new javafx.event.EventHandler<javafx.scene.input.MouseEvent>() {
#Override
public void handle(MouseEvent t) {
slideOut.play();
}
});
final VBox vbox = new VBox();
final Slider slider = new Slider();
final Button playButton = new Button("|>");
root.getChildren().add(view);
root.getChildren().add(vbox);
vbox.getChildren().add(slider);
vbox.getChildren().add(playButton);
vbox.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 400, 400, Color.BLACK);
stage.setScene(scene);
stage.show();
// Play/Pause Button
playButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
Status status = playa.getStatus();
if (status == Status.UNKNOWN || status == Status.HALTED)
{
// don't do anything in these states
return;
}
if ( status == Status.PAUSED
|| status == Status.READY
|| status == Status.STOPPED)
{
// rewind the movie if we're sitting at the end
if (atEndOfMedia) {
playa.seek(playa.getStartTime());
atEndOfMedia = false;
}
playa.play();
} else {
playa.pause();
}
}
});
//Listeners and Shit for Play Button
playa.setOnPlaying(new Runnable() {
#Override
public void run() {
if (stopRequested) {
playa.pause();
stopRequested = false;
} else {
playButton.setText("||");
}
}
});
playa.setOnPaused(new Runnable() {
#Override
public void run() {
playButton.setText(">");
}
});
playa.play();
playa.setOnReady(new Runnable() {
#Override
public void run(){
int v = playa.getMedia().getWidth();
int h = playa.getMedia().getHeight();
stage.setMinWidth(v);
stage.setMinHeight(h);
vbox.setMinSize(v, 100);
vbox.setTranslateY(h-50);
//slider and graphical slide in/out
slider.setMin(0.0);
slider.setValue(0.0);
slider.setMax(playa.getTotalDuration().toSeconds());
slideOut.getKeyFrames().addAll(
new KeyFrame(new Duration(0),
new KeyValue(vbox.translateYProperty(), h-100),
new KeyValue(vbox.opacityProperty(), 0.9)
),
new KeyFrame(new Duration(300),
new KeyValue(vbox.translateYProperty(), h),
new KeyValue(vbox.opacityProperty(), 0.0)
)
);
slideIn.getKeyFrames().addAll(
new KeyFrame(new Duration(0),
new KeyValue(vbox.translateYProperty(), h),
new KeyValue(vbox.opacityProperty(), 0.0)
),
new KeyFrame(new Duration(300),
new KeyValue(vbox.translateYProperty(), h-100),
new KeyValue(vbox.opacityProperty(), 0.9)
)
);
}
});
//Slider being current and ability to click on slider.
playa.currentTimeProperty().addListener(new ChangeListener<Duration>(){
#Override
public void changed(ObservableValue<? extends Duration> observableValue, Duration duration, Duration current){
slider.setValue(current.toSeconds());
}
});
slider.setOnMouseClicked(new javafx.event.EventHandler<javafx.scene.input.MouseEvent>() {
#Override
public void handle(javafx.scene.input.MouseEvent t) {
playa.seek(Duration.seconds(slider.getValue()));
}
});
}
Use JFXPanel:
public class Test {
private static void initAndShowGUI() {
// This method is invoked on Swing thread
JFrame frame = new JFrame("FX");
final JFXPanel fxPanel = new JFXPanel();
frame.add(fxPanel);
frame.setVisible(true);
Platform.runLater(new Runnable() {
#Override
public void run() {
initFX(fxPanel);
}
});
}
private static void initFX(JFXPanel fxPanel) {
// This method is invoked on JavaFX thread
Scene scene = createScene();
fxPanel.setScene(scene);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
initAndShowGUI();
}
});
}
}
where method createScene() is start(final Stage stage) from your code.
Just instead of putting scene to stage you return it.

jgoodies binding: using a JTextField with a formatted number?

I am trying to bind a JTextField to a bean's field that is a double using JGoodies Binding:
JTextField myJTextField = ...
BeanAdapter adapter = ...
Bindings.bind(myJTextField,
ConverterFactory.createStringConverter(adapter.getValueModel("amplitude"),
new DecimalFormat("0.00000")));
This works, at least in the bean → JTextField direction. In the JTextField → bean direction, it has one hitch: if I start typing in the JTextField it takes my update immediately after the first digit after the decimal point, messes up the JTextField focus, and tweaks my JTextField value.
(the problem seems to come from trying to adapt a GUI's String to a model's double)
How do I fix this????
sample program that demonstrates this:
package com.example.test.gui;
import java.awt.GridLayout;
import java.beans.PropertyChangeListener;
import java.text.DecimalFormat;
import java.util.Hashtable;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import com.jgoodies.binding.adapter.Bindings;
import com.jgoodies.binding.adapter.BoundedRangeAdapter;
import com.jgoodies.binding.beans.BeanAdapter;
import com.jgoodies.binding.beans.ExtendedPropertyChangeSupport;
import com.jgoodies.binding.value.ConverterFactory;
public class FloatPointBinding {
public static class MyModel {
private int x;
final private ExtendedPropertyChangeSupport changeSupport =
new ExtendedPropertyChangeSupport(this);
public void addPropertyChangeListener(PropertyChangeListener x) {
this.changeSupport.addPropertyChangeListener(x);
}
public void removePropertyChangeListener(PropertyChangeListener x) {
this.changeSupport.removePropertyChangeListener(x);
}
static private int clip(int a)
{
return Math.min(Math.max(a, -32768), 32767);
}
static private int d2i(double a) {
return clip((int) Math.floor(a*32768 + 0.5));
}
static private double i2d(int a) {
return (clip(a)/32768.0);
}
public void setXCount(int x) {
int oldX = this.x;
int newX = x;
this.x=newX;
this.changeSupport.firePropertyChange("x", i2d(oldX), i2d(newX));
this.changeSupport.firePropertyChange("XCount", oldX, newX);
}
public void setX(double x) { setXCount(d2i(x)); }
public double getX() { return i2d(this.x); }
public int getXCount() { return this.x; }
}
public static class MyView extends JFrame
{
public MyView(MyModel model, String title)
{
super(title);
JTextField jtf = new JTextField();
JSlider jsl = new JSlider();
jsl.setMinimum(-32768);
jsl.setMaximum(32767);
jsl.setMajorTickSpacing(4096);
jsl.setPaintTicks(true);
Hashtable labelTable = new Hashtable();
labelTable.put( new Integer( -32768 ), new JLabel("-1") );
labelTable.put( new Integer( 0 ), new JLabel("0") );
labelTable.put( new Integer( 32767 ), new JLabel("1") );
jsl.setLabelTable( labelTable );
jsl.setPaintLabels(true);
setLayout(new GridLayout());
add(jsl);
add(jtf);
BeanAdapter adapter = new BeanAdapter(model, true);
Bindings.bind(jtf,
ConverterFactory.createStringConverter(adapter.getValueModel("x"),
new DecimalFormat("0.#####")));
jsl.setModel(new BoundedRangeAdapter(adapter.getValueModel("XCount"), 0, -32768, 32767));
}
}
public static void main(String[] args)
{
MyModel model = new MyModel();
MyView view = new MyView(model, "FloatPointBinding");
view.pack();
view.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
view.setVisible(true);
}
}
I am not sure if this is what you are trying to solve, but if you change the binding to only commit on focus lost you shouldn't have that issue anymore. Just specify true as the third argument to the bind method below:
Bindings.bind(jtf,
ConverterFactory.createStringConverter(adapter.getValueModel("x"),
new DecimalFormat("0.#####")),
true);