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
Related
What I mean is there a way to set the window size to related to the result given by this method: GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds() ? This gives back a different result compared to Gdx.graphics.getWidth() and Gdx.graphics.getHeight(): these return the screen size, but what I'd like to have is the screen area - menu bars area (for example the Dock on a Mac). I'd also like to keep the ratio of the window while doing so.
I tried to use the Java.awt method GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds(), but it couldn't run. I was looking on google and people say that using Java.awt methods with Libgdx causes problems, so I presume that's why.
Main code
Debug view
If you mean you want the window to be maximised on start then you can set that directly in the Lwjgl3ApplicationConfiguration config with
config.setMaximised(true);
You can maximise after the start with (which is going below the abstraction libGDX provides).
GLFW.glfwMaximizeWindow(window.getWindowHandle);
https://www.glfw.org/docs/3.3/window_guide.html#window_sizelimits
You can capture the window with a listener on config.
config.setWindowListener(new Lwjgl3WindowAdapter() {
#Override
public void created(final Lwjgl3Window window) {
If you need in the program to know what the available dimensions is without menu bars etc (which is the equivalent of AWT GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds() then
GLFW.glfwGetMonitorWorkarea(long monitor, int[] xpos, int[] ypos, int[] width, int[] height);
using
GLFW.glfwGetPrimaryMonitor()
and then you can build a custom window maximiser with
GLFW.glfwSetWindowPos(long window, int xpos, int ypos);
GLFW.glfwSetWindowSize(long window, int width, int height);
https://javadoc.lwjgl.org/org/lwjgl/glfw/GLFW.html
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.
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.
I'm currently making a game using the Libgdx library, and have currently hit a small hurdle.
I've disabled the ability to resize currently, in my Main.java class in the desktop project.
LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
cfg.resizable = false;
I'm wondering whether there is a simple way to make the window resize whilst keeping the aspect ratio. (Like when you shift+resize)
What are my options? :)
that function does not give you the ability to keep the aspect ratio or even something of that what you think. It does just disables the possebilty to resize the screen at the desktop application.
Please take a look at the libGDX wiki especialy the Scene2D page.
Take a look at the Viewport stuff from the Stage. It's explained how you do keep the aspect ratio with the current libGDX. There are tutorials out there who do explain a different way with the help of a virtual resolution and the screen resize method. It's outdate!
from the wiki
This example also uses a fixed stage size with "black bars" on either
side, this time using glViewport. First the stage size of 800x480 is
scaled to fit the screen size using the Scaling class. The result is
used to configure glViewport, which changes which part of the screen
OpenGL will use. Lastly, setViewport is passed the viewport position
and size. The result is the same as the last example, the stage has
"black bars" as necessary to keep the aspect ratio, but no drawing can
occur outside the viewport.
public void resize (int width, int height) {
Vector2 size = Scaling.fit.apply(800, 480, width, height);
int viewportX = (int)(width - size.x) / 2;
int viewportY = (int)(height - size.y) / 2;
int viewportWidth = (int)size.x;
int viewportHeight = (int)size.y;
Gdx.gl.glViewport(viewportX, viewportY, viewportWidth, viewportHeight);
stage.setViewport(800, 480, true, viewportX, viewportY, viewportWidth, viewportHeight);
}
regards
I'm creating a splash screen for a Java application using the SplashScreen class. The problem is that the position on multi-monitor systems is undefined. The documentation states "the position on multi-monitor systems is not specified - it is platform and implementation dependent". The application is going to be used solely on multi-monitor platforms, and I would like to ensure that it's always centered on one of the screens. Is there any way to achieve this? The application is going to be used on Linux only, so the platform is the same everywhere.
There is a sample Javafx equivalent of Splash screen. However this splash screen is basically a java swing applet that is called from javafx to be displayed to the user and simulates more or less eclipse and netbeans splash screen using progress bar and titles for the loaded contents.
Following is the link at
http://0divides0.wordpress.com/2011/03/17/splash-screen-with-javafx/
You must be able to get the code and seperate out the splash screen code written in java swings and use it for yourself.
This is a custom java swing splash screen.
and hence to center the splash screen it uses the traditional functions
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension labelSize = l.getPreferredSize();
setLocation(screenSize.width / 2 - (labelSize.width / 2), screenSize.height / 2 - (labelSize.height / 2));
Then don't use the builtin splash screen from Java 6. Create your own splash screen using your UI toolkit and position the window manually by calculating its size and the size of the available screens.
An other sample code :
// Get the size of the screen
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
// Determine the new location of the window
int w = login.getSize().width;
int h = login.getSize().height;
int x = (dim.width-w)/2;
int y = (dim.height-h)/2;
// Move the window
setLocation(x, y);
setVisible(true);
It might not be defined in the context of Java, but it's for sure defined in the context of the display server.
For Linux / X11 the important aspect is whether XInerama is enabled or not. This X extension enables applications to get knowledge of the physical displays that comprise the desktop.
A quick way of verifying that XInerama is enabled is to try to maximize a window on your multi monitor target system. With XInerama enabled it should only maximize to the dimensions of the active monitor, not the entire screen surface.
Splash screens will when XInerama is enabled be centered on the active monitor as the application launches.
If you focus solely on getting your application's splash screen positioned correctly you will quickly get feedback on other multi monitor issues like for instance the task bar stretching across all screens or windows that maximize across all screens.
A different solution to center a frame on a screen:
GraphicsConfiguration c = frm.getGraphicsConfiguration();
Rectangle in = c.getBounds();
int center_x = in.x + in.width / 2;
int center_y = in.y + in.height / 2;
frm.setLocation(center_x - frm.getWidth()/2, center_y - frm.getHeight()/2);
With the accepted solution I had the problem that the frame was displayed at the border of my two screens. i.e. at the center of both screens.