Toolkit.getDefaultToolkit().getScreenSize()
returns the full size of the default screen, it does not take into consideration things like task bars or other elements which may occupy space on the desktop which windows should avoid been placed under/over.
A better solution would be to use Toolkit.getDefaultToolkit().getScreenInsets(GraphicsConfiguration)
and GraphicsConfiguration#getBounds
public static Rectangle getScreenViewableBounds(Window window) {
return getScreenViewableBounds((Component) window);
}
public static Rectangle getScreenViewableBounds(Component comp) {
return getScreenViewableBounds(getGraphicsDevice(comp));
}
public static Rectangle getScreenViewableBounds(GraphicsDevice gd) {
Rectangle bounds = new Rectangle(0, 0, 0, 0);
if (gd == null) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
gd = ge.getDefaultScreenDevice();
}
if (gd != null) {
GraphicsConfiguration gc = gd.getDefaultConfiguration();
bounds = gc.getBounds();
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
bounds.x += insets.left;
bounds.y += insets.top;
bounds.width -= (insets.left + insets.right);
bounds.height -= (insets.top + insets.bottom);
}
return bounds;
}
/**
* Attempts to locate the graphics device that the component most likely is
* on.
*
* This calculates the area that the window occupies on each screen deivce and
* returns the one which it occupies the most.
*
* @param comp
* @return
*/
public static GraphicsDevice getGraphicsDevice(Component comp) {
GraphicsDevice device = null;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice lstGDs[] = ge.getScreenDevices();
ArrayList<GraphicsDevice> lstDevices = new ArrayList<GraphicsDevice>(lstGDs.length);
if (comp != null && comp.isVisible()) {
Rectangle parentBounds = comp.getBounds();
/*
* If the component is not a window, we need to find its location on the
* screen...
*/
if (!(comp instanceof Window)) {
Point p = new Point(0, 0);
SwingUtilities.convertPointToScreen(p, comp);
parentBounds.setLocation(p);
}
for (GraphicsDevice gd : lstGDs) {
GraphicsConfiguration gc = gd.getDefaultConfiguration();
Rectangle screenBounds = gc.getBounds();
if (screenBounds.intersects(parentBounds)) {
lstDevices.add(gd);
}
}
if (lstDevices.size() == 1) {
device = lstDevices.get(0);
} else {
GraphicsDevice gdMost = null;
float maxArea = 0;
for (GraphicsDevice gd : lstDevices) {
int width = 0;
int height = 0;
GraphicsConfiguration gc = gd.getDefaultConfiguration();
Rectangle bounds = gc.getBounds();
Rectangle2D intBounds = bounds.createIntersection(parentBounds);
float perArea = (float) ((intBounds.getWidth() * intBounds.getHeight()) / (parentBounds.width * parentBounds.height));
if (perArea > maxArea) {
maxArea = perArea;
gdMost = gd;
}
}
if (gdMost != null) {
device = gdMost;
}
}
}
return device;
}
The main issue you're having is that there is no such method as setLocation(int)
...what would the value int
represent any way? x or y position?
You need to pass both the x and y position to setLocation
in order for it to work.
Rectangle bounds = getScreenViewableBounds(this); // where this is a reference to your window
int x = bounds.x + ((bounds.width - getWidth()) / 2;
int y = bounds.y;
setLocation(x, y);
For example...