I'm trying to make a Window class to abstract all the GLFW stuff. The thing is that I don't know how to use glfwSetWindowUserPointer in LWJGL.
I've used the function before, but in C++. Now I'm moving to Java, using LWJGL.
In C++, I would do something like:
glfwSetWindowUserPointer(myWindow, &myData)
But in LWJGL the function takes 2 long, where the first argument is the window handle, but I don't know what to do with the second one.
How can I pass a pointer to my object containing all the data I need inside the callbacks?
Thanks in advance
To expand on #elect's comment about JNINativeInterface and memGlobalRefToObject:
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.system.jni.JNINativeInterface;
class JavaObject {
String message;
JavaObject(String message) {
this.message = message
}
}
final long pointer = JNINativeInterface.NewGlobalRef(new JavaObject("Hello"));
JavaObject object = MemoryUtil.memGlobalRefToObject(pointer);
JNINativeInterface.DeleteGlobalRef(pointer);
System.out.println(object.message) // => "Hello"
// Already deleted the strong reference held by the native part of the application.
object = MemoryUtil.memGlobalRefToObject(pointer);
System.out.println(object) // => null
On a bit of advice: I'd only use the GLFW user pointer for the callbacks set with glfwSetMonitorCallback and glfwSetErrorCallback. You don't need it for the window callbacks, as you set one callback per window, so you already have a reference to each Java wrapper class.
class Window {
final long handle;
int width;
int height;
WindowObserver observer;
Window(final long handle, final int width, final int height) {
this.handle = handle;
this.width = width;
this.height = height;
glfwSetWindowSizeCallback(handle, (handle, w, h) -> {
if (observer != null) {
observer.windowDidResize(this, this.width, this.height, w, h);
}
this.width = w;
this.height = h;
});
}
}
Related
Let's say I have a class with multiple constructors, one of which is a copy-constructor (to copy an object):
public class Rectangle {
int width, height;
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
public Rectangle(Rectangle source) {
this(source.width, source.height);
}
}
Is there any way I can make check if source is null in the copy-constructor and throw an IllegalArgumentException if it is? Because the other constructor call has to be the first statement in my constructor.
You can do this:
public Rectangle(Rectangle source) {
this(checkNotNull(source, "Source cannot be null").width, source.height);
}
private static <T> T checkNotNull(T t, String msg) {
if (t == null) throw new IllegalArgumentException(msg);
return t;
}
I also agree with Jon Skeet that a NullPointerException is not a bad bevahiour in this case. The only thing is that in long lines when you get an NPE it can be a bit hard to identify which object is null, which is why a more specific message can be useful.
You can also not reinvent the wheel and use standard java.util.Objects methods if you don't bother throwing a NullPointerException instead:
public Rectangle(Rectangle source) {
this(Objects.requireNonNull(source, "Source cannot be null").width, source.height);
}
if your error message is expensive to build, you can provide a Supplier<String> instead, to pay the cost of the construction of the message only when it's actually needed:
public Rectangle(Rectangle source) {
this(Objects.requireNonNull(source, () -> explainError(source)).width, source.height);
}
Yes, you can use a helper method which will throw the exception if necessary, and return the original value otherwise... you can call that within your constructor invocation, as you're allow method calls as part of argument evaluation.
// In a helper class
public static <T> T checkNotNull(T value) {
if (value == null) {
throw new IllegalArgumentException();
}
return value;
}
Then use it as:
public Rectangle(Rectangle source) {
this(Helper.checkNotNull(source).width, source.height);
}
However... I believe that NullPointerException is the recommended exception to throw here anyway (in Effective Java 2nd edition, for example), which your existing code will throw already. So you quite possibly don't want to make any change to your existing code.
If you want a helper method for checks like this but are happy for it to throw NullPointerException, I'd recommend using Guava and its Preconditions class, which has this and a lot of other helpful checking methods.
Also note that Java 1.7 introduced java.util.Objects which has requireNonNull, so you don't even need a third party library.
One text-book trick is move the initialization out of the constructor to a method. Then, you can have whatever code you want before it:
public class Rectangle {
int width, height;
public Rectangle(int width, int height) {
init(width, height);
}
public Rectangle(Rectangle source) {
if (source == null) {
throw new IllegalArgumentException("source can't be null!");
}
init(source.width, source.height);
}
private void init(int width, int height) {
this.width = width;
this.height = height;
}
}
If you really do want to throw an IllegalArgumentException, I think the cleanest solution is to use a static method instead of a constructor:
public static Rectangle from(Rectangle source) {
if (source == null) {
throw new IllegalArgumentException("source can't be null!");
}
return new Rectangle(source.width, source.height);
}
Or you could just add a copy method:
public Rectangle copy() {
return new Rectangle(this.width, this.height);
}
I'd prefer the latter, since it removes the need to concern yourself with the Rectangle possibly being null. Note that this will cause a NPE if you use this with a null Object, which is possibly a further indication that an NPE is fine.
You can do like this
int width, height;
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
public Rectangle(Rectangle source) {
if(source != null) {
width = source.width;
height = source.height;
}
}
I'm attempting to use the Chinese (Traditional, Taiwan), Chinese (Traditional) - New Phonetic keyboard on an English (US) Windows 7. When I type into a Java Swing-based text area, the candidate list is showing up on the bottom-right of my screen, regardless of where the text area is positioned on the screen. When I'm not using a Java program, the candidate list shows up in the correct place, directly under the text I'm typing.
Has anybody else run into this behavior and found a workaround for it? I haven't found other reports of this behavior online.
Thanks in advance for any help!
System Details:
Microsoft New Phonetic IME 10.1 (10.1.7601.0)
Chinese input mode
Either half or full shape (doesn't matter)
Standard keyboard layout
Windows 7, 64-bit (same happens on 32-bit)
Affects Java 6, 7, and 8
Affects Swing and JavaFX
I did eventually find similar problems reported, but most of them were related to Japanese IMEs and have already been fixed in the JDK. I didn't find any reports specific to this Chinese IME, but I did find a workaround in case it's useful for others.
The brief summary is that I listen for the WM_IME_STARTCOMPOSITION Windows message. When I see that, I locate the IME candidate window, move it to the location I want, and override its WindowProc to prevent further moves. During composition I also listen for WM_KEYDOWN events because I no longer received any WM_IME messages while the user was composing, even though the candidate window closes and gets recreated several times throughout composition. When I receive the WM_IME_ENDCOMPOSITON message, I stop listening for WM_KEYDOWN messages.
As an alternative approach, I tried sending a WM_IME_CONTROL message with the IMC_SETCANDIDATEPOS command to move the candidate window, but this particular IME seems to ignore it.
I used JNA (https://github.com/twall/jna) to override the WindowProc on both the window containing my text area as well as the IME candidate window.
The code snippet below is an example of the workaround.
hwndMain = WIN_INSTANCE.FindWindow(null, "Main Window");
// Note the existing WindowProc so we can restore it later.
prevWndProc = new BaseTSD.LONG_PTR((long) WIN_INSTANCE.GetWindowLong(hwndMain, WinUser.GWL_WNDPROC));
// Register a new WindowProc that we will use to intercept IME messages.
mainListener = new WindowsCallbackListener() {
#Override
public int callback(int hWnd, int uMsg, int uParam, int lParam) {
if (uMsg == WM_IME_STARTCOMPOSITION || (imeComposing && uMsg == WM_KEYDOWN)) {
imeComposing = true;
final WinDef.HWND hwndIme = WIN_INSTANCE.FindWindow("SYSIME7_READING_UI", null);
if (hwndIme != null && !hwndIme.equals(imeWindow)) {
// We found an IME window that is not the same as the last one. We assume the last one was
// closed. We need to register our callback with the new window.
imeWindow = hwndIme;
final Point imeWindowLocation = getImeWindowLocation();
WIN_INSTANCE.MoveWindow(hwndIme, imeWindowLocation.x, imeWindowLocation.y, 0, 0, true);
final BaseTSD.LONG_PTR prevWndProcIme =
new BaseTSD.LONG_PTR((long) WIN_INSTANCE.GetWindowLong(hwndIme, WinUser.GWL_WNDPROC));
imeListener = new WindowsCallbackListener() {
#Override
public int callback(int hWnd, int uMsg, int uParam, int lParam) {
if (uMsg == WM_WINDOWPOSCHANGING) {
final WindowPosition pos = new WindowPosition(new Pointer((long)lParam));
pos.read();
pos.flags |= SWP_NOMOVE;
pos.write();
}
// Call the window's actual WndProc so the events get processed.
return WIN_INSTANCE.CallWindowProc(prevWndProcIme, hWnd, uMsg, uParam, lParam);
}
};
// Set the WndProc function to use our callback listener instead of the window's one.
WIN_INSTANCE.SetWindowLong(hwndIme, WinUser.GWL_WNDPROC, imeListener);
}
}
else if (uMsg == WM_IME_ENDCOMPOSITION) {
// We can discard the IME listener since its window is closed. If another one gets opened, we'll
// create a new listener.
imeListener = null;
imeComposing = false;
}
// Call the window's previous WindowProc so the event continues to get processed.
return WIN_INSTANCE.CallWindowProc(prevWndProc, hWnd, uMsg, uParam, lParam);
}
};
// Set the WindowProc function to use our WindowProc so the event continues to get processed.
WIN_INSTANCE.SetWindowLong(hwndMain, WinUser.GWL_WNDPROC, mainListener);
The code above assumes the following definitions:
private static final MyUser32 WIN_INSTANCE = MyUser32.INSTANCE;
private static final int SWP_NOMOVE = 2;
private static final int WM_KEYDOWN = 256;
private static final int WM_WINDOWPOSCHANGING = 70;
private static final int WM_IME_ENDCOMPOSITION = 270;
private static final int WM_IME_STARTCOMPOSITION = 269;
private WinDef.HWND hwndMain;
private BaseTSD.LONG_PTR prevWndProc;
// Keep references to these listeners so they don't get garbage-collected.
private WindowsCallbackListener mainListener;
private WindowsCallbackListener imeListener;
private boolean imeComposing;
private WinDef.HWND imeWindow;
public static class WindowPosition extends Structure {
public WinDef.HWND hwnd;
public WinDef.HWND hwndInsertAfter;
public int x;
public int y;
public int cx;
public int cy;
public int flags;
public WindowPosition(Pointer p) {
super(p);
}
#Override
protected List getFieldOrder() {
return Arrays.asList("hwnd", "hwndInsertAfter", "x", "y", "cx", "cy", "flags");
}
}
private interface MyUser32 extends User32 {
MyUser32 INSTANCE = (MyUser32) Native.loadLibrary("user32", MyUser32.class, W32APIOptions.DEFAULT_OPTIONS);
int CallWindowProc(BaseTSD.LONG_PTR prevWndProc, int hWnd, int uMsg, int uParam, int lParam);
int SetWindowLong(HWND hwnd, int nIndex, BaseTSD.LONG_PTR listener) throws LastErrorException;
int SetWindowLong(HWND hwnd, int nIndex, WindowsCallbackListener listener) throws LastErrorException;
}
private interface WindowsCallbackListener extends Callback, StdCall {
int callback(int hWnd, int Msg, int wParam, int lParam);
}
I want a Animations class that can be reused through different projects. The problem is how I let the class change another object's members (such as position). Here is a very simplified version of how it would operate and what it can do.
public class Animation() {
private float currValue, targetValue, duration;
public Animation(currValue, targetValue, duration) {
this.currValue = currValue;
this.targetValue = targetValue;
this.duration = duration;
}
public void update() {
// Here I would update its currValue based on duration and target
}
}
So when I want to animate let's say a rectangle's position I would do:
class Rectangle {
private float x, y;
private Animation a;
public Rectangle (x, y) {
this.x = x;
this.y = y;
this.a = new Animation(x, 100, 1000); // Duration in ms
}
public void update() {
a.update(); // Update animation
}
}
Obviously this does not work, because Animation does not update Rectangle's x value. Only one solution comes to mind, and that is passing in the instance of Rectangle and the field name "x" and then use the Reflection API to update the value. But that seems like a pretty poor solution.
Any suggestions? Should I design my code differently?
Reflection is not necessarily a poor solution in this case. In fact, it's a very general solution that allows elegant code on the client side. But of course, one should be aware of the caveats of using reflection in general.
A very pragmatic approach of such an animation would be to "factor out" what the animation actually does: Namely changing some float value, in your case. So one way of separating the "client" code and the implementation could be the following:
interface FloatSetter {
void setFloat(float f);
}
public class Animation
{
private float currValue, targetValue, duration;
private FloatSetter floatSetter;
public Animation(
float currValue, float targetValue, float duration,
FloatSetter floatSetter)
{
this.currValue = currValue;
this.targetValue = targetValue;
this.duration = duration;
this.floatSetter = floatSetter;
}
public void update()
{
...
floatSetter.setFloat(currValue);
}
}
Then you can pass an appropriate implementation of FloatSetter to your Animation - probably via an anonymous inner class:
class Rectangle
{
private float x, y;
private Animation a;
public Rectangle(float fx, float fy) {
this.x = fx;
this.y = fy;
FloatSetter floatSetter = new FloatSetter()
{
#Override
public void setFloat(float f)
{
this.x = f;
}
});
this.a = new Animation(x, 100, 1000, floatSetter);
}
public void update() {
a.update(); // Update animation
}
}
BTW: Depending on what you are going to achieve, I'd recommend to not put the Animation instance into the Rectangle. But I assume that this is just a sketch to show your intention.
Important : You should definitiely have a look at the "Timing Framework": https://java.net/projects/timingframework . It is the accompanying code for chapters of the book "Filthy Rich Clients" ( http://filthyrichclients.org/ ) by Chet Haase and Romain Guy, and they certainly know their stuff. The library is a very sophisticated and flexible implementation of what you obviously want to achieve there. (They also support a generic "PropertySetter" that uses reflection (https://java.net/projects/timingframework/sources/svn/content/trunk/timingframework-core/src/main/java/org/jdesktop/core/animation/timing/PropertySetter.java?rev=423 ), but this is just one helper class to define a general "TimingTarget", which is the sophisticated version of the "FloatSetter" that I sketched above).
I'm currently working on a game written in Java.
At the moment I'm stuck finding an easy way to store my GameObjects (Player, Enemies, and so on...) so that I can access them by their coordinates while still being able to move them easily.
I already tried Multidimensional Arrays, which is nice, but won't let me move my Objects easily. I'd have to physically move the Object in the array every time it moves.
Then I tried "normal" Arrays, which lets you move things easily, just increase the objects x, y or z value, but won't allow me to access Objects by coordinates without iterating through the whole array.
Right now, i'm trying to find a compromise that allows me to have both.
Thanks in advance,
//265
The simple solution is to use both forms at the same time. Store the coordinates in your GameObject instances, but also simultaneously cache them in your 3D array. The array should preferably be encapsulated in an object that provides method to update and query it. Something like this:
public class GameObjectDatabase implements LocationChangeListener {
private int [] [] [] data;
private Set<GameObjects> objects;
...
public GameObject gameObjectAt(int x, int y, int z) {
return data[x][y][z];
}
#Override
public void positionUpdated(GameObject obj, int oldX, int oldY, int oldZ) {
....
}
}
Why the listener and the overridden method? Because it's not really your GameObject's job to update this data - it's the responsibility of the GameObjectDatabase. So, ideally, your GameObject should allow to register listeners in a Set and call their positionUpdated methods every time its location changes.
All game objects that have a position (player, enemies etc) should have an internal reference to their position eg;
class Position {
int x;
int y;
}
interface Positionable {
Position getPosition();
void setPosition(int x, int y, GameArea area);
}
class Player implements Positionable {
//stuff
}
class Enemy implements Positionable {
//stuff
}
You can then have a class representing your game area;
class GameArea {
Positionable[][] grid;
List<Positionable> gameObjects;
public Positionable getByLocation(int x, int y) {
return grid[x][y];
}
public void setAtLocation(int x, int y, Positionable p) {
grid[x][y] = p;
}
public List<Positionable> getAll() {
return gameObjects;
}
}
This allows you to access by position and iterate over all objects. When a game object moves it needs to update its position internally and explicitly update the GameArea, as shown in the below example setPosition() implementation.
void setPosition(int x, int y, GameArea area) {
area.setAtLocation(this.x, this.y, null);
area.setAtLocation(x, y, this);
this.x = x;
this.y = y;
}
I am currently making a terrain generator, everything works fine in one class but I am going to be expanding my application.
Currently I have a JFrame class which holds everything, generating the terrain, painting the terrain, finding locations etc.
I want to add another class that will generate the terrain but when I create this class I need to access fields from the main JFrame class and when I do I get a stack overflow error - here is my code.
public class Simulator extends Applet
{
//fields
public Simulator()
{
grid = new int[100][100];
inhabGrid = new boolean[grid.length][grid.length];
gridSize = grid.length - 1;
dist = grid.length;
TerrainGenerator gen = new TerrainGenerator();
setSize(dist,dist);
seedGrid();
findInhabLocation();
printGridToConsole();
}
public void paint(Graphics g)
{
//panting the grid
}
public void seedGrid()
{
//seeding
}
public boolean generateTerrain(int x1,int y1, int x2, int y2)
{
//terrain generator
}
public boolean mouseUp(Event evt, int x, int y)
{
seedGrid(); //Create a new map
findInhabLocation();
repaint();
printGridToConsole();
return true;
}
public boolean keyEvents(Event evt, int x, int y)
{
seedGrid(); //Create a new map
findInhabLocation();
repaint();
printGridToConsole();
return true;
}
public void findInhabLocation()
{
//find best inhabitant location
}
public int locateWater(int x, int y)
{
//finding closest water
}
public int locateJungle(int x, int y)
{
//finding closest jungle
}
}
}
That works fine in its own class but when I create a class for example:
public class TerrainGenerator
{
Simulator sim = new Simulator();
}
I know this has something to do with the constructor and it's something silly I am doing, what would be the best way of splitting up this app into classes, for example terrain generator, inhabitants etc
For example I want to be able to call a method from the 'TerrainGenerator' class and call i.e. terrainGenerator.generateTerrain
Your TerrainGenerator creates a Simulator object and vice versa, hence you'll end up with infinitely many objects (but at some point the stack is full and a stack overflow exception is thrown instead...)
Instead of creating a new Simulator in your TerrainGenerator, you should pass a reference to your current Simulator (well, actually, that is not a great design either, but I'm not gonna confuse you with the problems of circular references).
Heuster answer is correct, furthermore, I think you could take look at MVC to help you organize your classes.
Depending which should be the parent, you can pass in the instantiated class to the other, ie;
private final TerrainGenerator gen; //if you need to save this.
public Simulator(TerrainGenerator terrainGenerator)
{
this.gen = terrainGenerator;
....etc
}
public class TerrainGenerator
{
Simulator sim = new Simulator(this);
}
or
private final TerrainGenerator gen; //if you need to save this.
public Simulator()
{
this.gen = new TerrainGenerator(this);
....etc
}
private final Simulator sim; //If you need to save it.
public class TerrainGenerator
{
public TerrainGenerator(Simulator simulator) {
this.sim = simulator;
}
}