JavaFX Application proportions are not right - java

I am trying to set my applications center in the middle of the screen, and I apparently figured out myself the common solution proposed on other threads here at StackOverFlow, although you can clearly see that the application should be further to the left.
The screen I am using now is a 1920x1080, but the same thing used to happen on the 1366x766 screen.
Rectangle2D p = Screen.getPrimary().getVisualBounds();
double w = p.getWidth() / 1.5;
double h = p.getHeight() / 1.5;
stage.setWidth(w);
stage.setHeight(h);
stage.setX(p.getWidth()/2 - stage.getWidth()/2);
stage.setY(p.getHeight()/2 - stage.getHeight()/2);
The stage proportions are (in my case) 1280x720
Is there any reason why this is happening? Thanks in advance.
EDIT: Ok, I figured out that it works pretty well (from someones comment) and that the issue is the windows application bar that I positioned on the left, whilst when it is on the original position, the application is central.

Related

JavaFX: PannableCanvas: get CenterX/Y

I've been using a customized PannableCanvas that was presented here, and I've run into a bit of trouble. My software is almost finished, and the last thing I need to do is add support for spawning the Nodes on the center of the screen. So what I did originally was:
nodeTranslateX/Y = -pannableCanvas.getTranslateX/Y
And that worked until I realized that if you zoom in/out (where scale no longer = 1.0), it completely messes it up and the node starts getting placed in weird spots. So then I tried:
nodeTranslateX/Y = -pannableCanvas.getTranslateX/Y * pannableCanvas.getScale()
And that didn't work either! It gets thrown even further out of whack.
I tried numerous combinations of transformations such as dividing the scale, inverting the scale, using screenToLocal(), you name it. None of them have worked. The problem is that when you zoom out, the translateX/Y of the canvas is adjusted for the scale, but that gives you stuff like 1500 when the nodes should be spawn with sane coordinates like 300.
Is there a way to get the coordinates of the top-left corner of the screen relative to the canvas? I'm completely at a loss on how to fix this. Again, I just need to be able to spawn the node at the center of the screen. What should I do?
Thank you for your time!
I got it to work by doing this:
Window window = scene.getWindow();
double screenCenterX = (window.getX() + window.getWidth()/2);
double screenCenterY = (window.getY() + window.getHeight()/2);
Point2D point = pannablePane.screenToLocal(screenCenterX, screenCenterY);
double nodeX = point.getX() - MyNodeImplementation.WIDTH/2;
double nodeY = point.getY() - MyNodeImplementation.HEIGHT/2;
I had mistaken screenX/Y for being within the window (I.E. center = WIDTH/2, HEIGHT/2), but instead you actually have to take the actual window position into account too.

JFrame scaling for high resolution screens

I have a non resizable Jframe of size 1280x800. Of course this size appears bigger and smaller according to the resolution of the screen. (It has a background image). Now, if i try this on lets say a 4k monitor, it would be absolutely impractical because to small. Isn't there a way to scale the JFrame? Or a solution to this problem? What i thought i would do is write bigger jFrames and tell the main class which one to open according to the resolution. I am sure there is a much more elegant way to do that, since i guess it is a problem that many would have come across!
What a nightmare! Please help me!
Thank you
One way you could achieve that is by getting the screen size of the device, and then setting the size of your JFrame accordingly:
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
double jFrameWidth = screenDimension.width * 0.7;
double jFrameHeight = screenDimension.height * 0.5;
Or if you just want to maximise the JFrame you can use:
jFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
Detect the resolution of the window you're launching on and scale the frame to a percentage of that window. Have a baseline dimension (1280 * 800) so it isn't too-squashed on smaller screens.
As an example I pull the local GraphicsEnvironment, I pull the data from each relevant GraphicsDevice into a data class that I wrote myself, and I use that throughout my project as it gives me all sorts of stuff like buffer strategies, window dimensions, and so on. I do this when the application is loading (using a SplashScreen) which affords me control over the whole process.
That's about as elegant as you can get, I think.
EDIT
Editing in some example pseudocode to give an idea of what I'm getting at. I write primarily in Java, but I'm not doing this in an IDE so it won't necessarily be compile-ready:
public void scaleWindowDimensions(JFrame frame, GraphicsDevice gd) {
Rectangle bounds = gd.getDefaultConfiguration().getBounds();
int screenX = (int) bounds.getWidth();
int screenY = (int) bounds.getHeight();
// substitute this for however you're setting the size of the JFrame; this is simply how I sometimes do it
frame.getContentPane().setPreferredSize(new Dimension(screenX, screenY));
}
This is a very quick example that will set the size of your JFrame to that of the monitor it's running on. You'll need to modify the background image you're using as well. There's a lot more you could do with this but I'm keeping it simple on purpose.

openGL drawing distorted sprites (images) in psuedo-3d perspective

Alright so this is going to be a doozy to explain. I'm making a very basic "pseudo-3d" racing game for Android using AndEngine (and in turn, openGL - I think). I don't believe using AndEngine really has anything to do with this problem though, because I'm directly accessing openGL functions to accomplish my drawing.
Anyways, I copy-pasta'd some code that allowed the normally 2d AndEngine to have a 3d perspective (tutorial for such can be found here. This works pretty well, and I also don't believe this has much to do with my problem, but I don't fully understand openGL so it's a little hard for me to say. Here's the code from the onLoadEngine (called when app starts) that sets up the camera with a 3d perspective:
this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT) {
//other methods...
private void setFrustum(GL10 pGL) {
// set field of view to 60 degrees
float fov_degrees = 60;
float fov_radians = fov_degrees / 180 * (float)Math.PI;
// set aspect ratio and distance of the screen
float aspect = this.getWidth() / (this.getHeight());
float camZ = this.getHeight()/2 / (float)Math.tan(fov_radians/2);
// set projection
GLHelper.setProjectionIdentityMatrix(pGL);
GLU.gluPerspective(pGL, fov_degrees, aspect, camZ/10, camZ*10);
// set view
GLU.gluLookAt(pGL, 0,120f, camZ, 0, 0, 0f, 0, 1, 0); // move camera back+up
pGL.glScalef(1,-1,1); // reverse y-axis
pGL.glTranslatef(-CAMERA_WIDTH/2,-CAMERA_HEIGHT/2,0); // origin at top left
}
};
Then later in the onLoadScene (where the drawing takes place), I draw a bunch of my images like so:
for (int n=0;n<=100;n++) {
final int k = n;
final Sprite line = new Sprite(0, 0,CAMERA_WIDTH,16f, [AndEngine texture holding road img]) {
#Override
protected void applyTranslation(GL10 pGL) {
pGL.glTranslatef(this.mX, 120f, 15f*k); //16*k causes a sliver of a space between each segment
pGL.glRotatef(90f, 1, 0, 0); //**MAY BE MY ISSUE**
}
};
scene.attachChild(line); //actually draws the image to the screen
}
Which works pretty darn well as well, except for one thing! It distorts the shit out of my images. The images are simple pngs, both matching the CAMERA_WIDTH, and both looking similar to this:
And when I draw it without the rotate line, I get this:
Which has a decently straight middle line (tbh I'd be happy with them this way), but then you can see the edges of the road are all facing basically the exact opposite way they should be facing. I figured why not just flip them? I thought I would have to rotate them 180 degrees around the x axis, but instead that just makes them disappear, and instead I found that 90 degrees works (???). Anyways, Here's what I get:
So yeah. Here's where my problem lies - the middle lane divider is distorted as crap!! The lines marking the edge of the road line up wonderfully, but for whatever reason its really messing with that middle line. I get most of the math behind the 3d, but I really don't know what to make of this...it's almost like the image is being compressed because its being viewed at such a sharp angle, but I don't really know how the hell I could solve that without simply making it a top-down view? :S
Anyways... any ideas or guidance is welcome. Sorry this is such a long and convoluted post - it makes it hard when I really have no idea where the problem lies.
Also - It might be worth noting I have little to no experience with openGL or 3d graphics, and have even less interest in learning much about them in depth. I need a band-aid to this problem!
Ok so I found the solution! Turns out there is this little issue called Perspective Correct Texturing, that is basically just a flag that needs to be turned on in OpenGL to make it not skew images when they are being drawn with perspective.
Inside my Camera initializing code, I added this line to the method setFrustum(GL10 pGL):
pGL.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
That this essentially solved the problem. Lines are as straight as ever now :) I found this out on another stackoverflow post where this answer actually wasn't what the asker wanted, but it just so happened to work for me :D The thread that led me to the answer can be found here.

Display JFrame Centred on main monitor when using dual screens

I am trying to write some code to center my main application JFrame in the center of the computer screen using Java. To do it I am using the code below, which divides the process into two part, this is just because I use the ScreenHeight and ScreenWidth for scaling purposes elsewhere in the class and they are properties of the class.
This code works, on my laptop and other single screen machines perfectly, but on my main machine, which is dual monitor, it places the screen in the centre of the workspace which puts half the dialogue box (which can be small) on each screen. It's in a method, so that I can call it each time the dialogue boxes size, is changed by the program.
I use the boolean Width value to keep the screen in the same location on the vertical axis, but to center it on the horizontal.
// Finds the size of the screen
private void find_ScreenSize() {
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension dim = toolkit.getScreenSize();
ScreenHeight = dim.height;
ScreenWidth = dim.width;
}
// Centres the dialogue box within the screen
private void centre_Frame(JFrame Frame, boolean Width) {
find_ScreenSize();
if (!Width) { // if you are not justifying on the X axis
Frame.setLocation(Frame.getLocationOnScreen().x,
((ScreenWidth / 2) - (Frame.getWidth() / 2)));
} else {
Frame.setLocation(((ScreenWidth / 2) - (Frame.getWidth() / 2)),
((ScreenHeight / 2) - (Frame.getHeight() / 2)));
}
}
I would like to be able to center the dialogue box in the center of the main/first screen on any multi screen computers. The dialogue boxes in my application, that I don't control the location of, manage to do what I am trying to do for example my JOptionPane and file open and save dialogues all work perfectly.
I am developing on Linux, but the application is for use on Linux and MS platforms.
Searching for this problem gives me lots of examples of the above but nothing that shows me how to do what I want, any help would be appreciated.
Thanks in advance for any help.
frame.setLocationRelativeTo(null);
should work (doc). At least it does on my multi monitor setup. Note that the window is always displayed on the center of the main monitor, even if the app is launched from the secondary monitor.
You can use GraphicsEnvironment.getCenterPoint to find the center point rather than calculating youselves.
If you want to display in a specific monitor, see Show JFrame in a specific screen in dual monitor configuration

scale() and shape() in Processing

UPDATE: I think I figured it out. The scaleMultiplier also applied to the translate that I was trying to do. I had a suspicion this was the case but couldn't figure out exactly how it got affected.
Anyone familiar with a spinoff of Java called Processing? I'm trying to do something simple, scale a shape and place it in the center of the sketch. This is my code in a nutshell:
pushMatrix();
float scaleX, scaleY, scaleMultiplier, resetX, resetY, transX, transY;
scaleX = 500 / (float)clickState.bounds.getWidth();
scaleY = 500 / (float)clickState.bounds.getHeight();
scaleMultiplier = min(scaleX,scaleY);
resetX = -(float)clickState.bounds.getX();
resetY = -(float)clickState.bounds.getY();
transX = resetX + ((800 - ((float)clickState.bounds.getWidth() * scaleMultiplier))/2);
transY = resetY + ((550 - ((float)clickState.bounds.getHeight() * scaleMultiplier))/2);
scale(scaleMultiplier);
shape(clickState.pshape, transX, transY);
popMatrix();
What I'm trying to do is scale a state on a US Map. clickState is the state that the user clicked on. clickState.bounds is a Rectangle that surrounds the shape of the state. getX() and getY() return the x and y coords of the upper left hand corner of said box. I want to scale the state so that it's no bigger than 500x500 pixels. After that, I want to translate it so that it's in the middle of the sketch, which is 800x550.
Here's where I run into trouble: When I do
shape(clickState.pshape, resetX, resetY);
It draws the state in the upper left hand corner of the sketch. That's exactly what it should do. Then from there I want to add the number of pixels that it would take to center the shape, which is what transX and transY are for. However, when I use transX and transY, the shape gets drawn almost completely off the canvas, depending on where the state is located (even if its only being moved 50 pixels to the right from 0,0). It doesn't make any sense to me whatsoever. I've tried all sorts of combinations of translate(), and even skipping scale() altogether and using a width and height in shape(). It's like Processing is trying to frustrate me on purpose. Any help is appreciated.
I'm not familiar with Processing, but matrix operations are not commutative—the order matters. Typically, operations are applied in an apparent last-specified-first-applied order, as shown in this example.
Vince, I think I was trying to do something very similar last week. Sounds like you figured it out, but check out the answers on this board:
http://forum.processing.org/topic/how-do-i-move-svg-child-shapes#25080000000689051

Categories

Resources