JFrame.getInsets weird value - java

AdoptOpenJDK 11 on Windows 10. JFrame descendant constructor:
getGraphicsConfiguration().getBounds()
java.awt.Rectangle[x=0,y=0,width=2560,height=1440]
Toolkit.getDefaultToolkit().getScreenInsets(getGraphicsConfiguration())
java.awt.Insets[top=0,left=0,bottom=40,right=0]
set*Size(new Dimension(2560, 1400));
pack();
getSize();
java.awt.Dimension[width=2560,height=1400]
getInsets();
java.awt.Insets[top=31,left=8,bottom=8,right=8]
getContentPane().getSize()
java.awt.Dimension[width=2544,height=1361]
... and yet the window does not cover full desktop space minus the task bar (because of those extra insets of 8). Why?
Example code using my answer:
package javaapplication2;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GraphicsConfiguration;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JPanel;
public final class TestFrame extends JFrame {
private static final long serialVersionUID = 1L;
private static final class CustomPanel extends JPanel {
private static final long serialVersionUID = 1L;
public CustomPanel(Dimension d) {
setMinimumSize(d);
setPreferredSize(d);
setMaximumSize(d);
//this is just an example, there is custom layout code here, not using Swing, but it needs Dimension d to work
}
}
public TestFrame() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
GraphicsConfiguration gc = getGraphicsConfiguration();
Rectangle screenBounds = gc.getBounds();
Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
Dimension expectedFrameSize = new Dimension(screenBounds.width - screenInsets.left - screenInsets.right, screenBounds.height - screenInsets.top - screenInsets.bottom);
setExtendedState(JFrame.MAXIMIZED_BOTH);
setVisible(true);
Dimension frameSize = getSize();
Insets frameInsets = getInsets();
setVisible(false);
Dimension contentSize = new Dimension(frameSize.width - frameInsets.left - frameInsets.right, frameSize.height - frameInsets.top - frameInsets.bottom);
getContentPane().add(new CustomPanel(contentSize));
setVisible(true);
setResizable(false);
System.out.println("screenBounds " + screenBounds);
System.out.println("screenInsets " + screenInsets);
System.out.println("expectedFrameSize " + expectedFrameSize);
System.out.println("frameSize " + frameSize);
System.out.println("frameInsets " + frameInsets);
System.out.println("contentSize " + contentSize);
System.out.println("assert expectedFrameSize == frameSize " + expectedFrameSize.equals(frameSize));
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new TestFrame().setVisible(true);
}
});
}
}
I would like to be able to calculate Dimension dimension without making the window temporarily visible. But it's impossible to arrive at correct sizes using methods available in the JDK:
getGraphicsConfiguration().getBounds()
Toolkit.getDefaultToolkit().getScreenInsets(getGraphicsConfiguration())

The insets of a frame describe size of the window decoration, which may include semi-transparent borders. On Microsoft Windows, there’s also a connection to the fact that window borders used to be 8 pixels thick in earlier versions.
When you maximize the window, its bounds will be set in a way that these insets are outside the visible areas, except for some parts of the title bar, which stays visible. To make predictability even worse, the title bar changes its layout when the window has been maximized, having less margin space.
But when you are looking for a Windows-only solution, the legacy aspects may help here. Consider the article “Why does a maximized window have the wrong window rectangle?”. As it explains, the window will always be at (-n,-n) and have (2n×2n) more than the actual visible area, for the border size n, for compatibility with old software. But, as it also explains, the maximized mode is special, as these borders are always cut off, so they do not show up in other monitors nor over the task bar.
That’s why it is impossible to emulate the same behavior by setting bounds only. Not only does the rendition of the title bar differ, you would also make parts of the window appear in other monitors on multi-monitor systems and over the task bar.
So, using that knowledge, you can predict the content pane size:
JFrame frame = new JFrame("Max");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
Timer t = new Timer(1000, ev -> System.out.println("actual size is "
+frame.getContentPane().getWidth()+" x "+frame.getContentPane().getHeight()));
t.setRepeats(false);
t.start();
Rectangle scrBounds = frame.getGraphicsConfiguration().getBounds();
Insets scrInsets = frame.getToolkit().getScreenInsets(frame.getGraphicsConfiguration());
Insets winInsets = frame.getInsets();
int width = scrBounds.width - scrInsets.left - scrInsets.right;
int height = scrBounds.height - scrInsets.top - scrInsets.bottom
- winInsets.top + winInsets.bottom;
System.out.println("content pane size will be "+width+" x "+height);
frame.setVisible(true);
This assumes that the historical border thickness is the same for all edges, so we can use the bottom size to determine the top size with the title bar size, so top - bottom gives us the remaining title bar size.

Apparently maximized frame has size larger than actual screen, and frame insets include 8,8,8,8 pixels (on my Windows) of which some are outside actual frame. The only way to get actual frame size that is used for maximized window is to make it visible for a while. In the end I resorted to this cheat:
setExtendedState(JFrame.MAXIMIZED_BOTH);
setVisible(true);
Dimension size = getSize();
Insets insets = getInsets();
setVisible(false);
dimension = new Dimension(size.width - insets.left - insets.right, size.height - insets.top - insets.bottom);
This allows me to find out what will be the dimension of the frame's content pane with frame taking all of desktop space (screen minus taskbar). And setResizable(false) has to be called only after final setVisible(true).
See if those numbers make sense for you:
screen bounds java.awt.Rectangle[x=0,y=0,width=2560,height=1440]
screen insets java.awt.Insets[top=0,left=0,bottom=40,right=0]
frame size java.awt.Dimension[width=2576,height=1416]
frame insets java.awt.Insets[top=31,left=8,bottom=8,right=8]
calculated dimension java.awt.Dimension[width=2560,height=1377]
Frame size is larger than screen space (screen bounds minus screen insets) by 16 in each direction. And those extra pixels are included in frame insets, even though they are not in the frame.

Related

BoxLayout artifact at 125% display scaling

This simple Java swing BoxLayout UI apparently results in certain pixels not being drawn (resulting in artifacts/garbage) when my display scaling is set to 125% (Windows 10):
import javax.swing.*;
public class Test {
public static void main(String[] args) {
JPanel container = new JPanel();
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
for(int i = 1; i <= 3; i++) panel.add(new JButton("Button " + i));
JFrame frame = new JFrame();
container.add(panel);
frame.add(container);
frame.pack();
frame.setVisible(true);
}
}
Result:
There is a one pixel gap between Button 2 and Button 3. I'm not greatly concerned with the gap itself, but the pixels in this gap (within the width of the buttons) are filled with garbage. In the screenshot, this appears to be a misaligned piece of a button, but in general this can change whenever this area is repainted (such as after hovering Button 2), often coming from a recently-repainted component (often more obvious in a more complex application). Presumably this is just uninitialized data due to some kind of dimension mismatch triggered by display scaling and particular position values.
Last tested with openjdk-14.0.2. (Presumably this can only happen since JEP 263 added "HiDPI Graphics" support in Java 9.)
Am I doing something wrong? Is there a way to avoid this problem or work around it? Is this a problem in BoxLayout or is it a more fundamental problem? Basically, what's going on?

Force size restrictions on Applet embedded in html

I have a Java Applet with a GridLayout containing widgets which I wish to be square, and remain tightly packed to each other (so their sizes are unrestricted).
However, I wish for the GridLayout to take up as much space as possible before being too large for the screen or unable to preserve widget 'squareness'.
Note that the number of rows and columns in the GridLayout are not necessarily equal (the Grid as a whole can be non-square)
This Applet is displayed via this html file;
<html>
<body>
<applet code=client.Grid.class
archive="program.jar"
width=100% height=95%>
</applet>
</body>
</html>
Currently, this makes the Applet expand into the window it is put in; the Grid can be resized by resizing the window, but this causes the geometry of each widget to be changed (losing 'squaredness').
So; where and how do I place these geometrical restrictions?
It can't be in the html file alone, since it has no knowledge of row/column count, and so doesn't know the best size to make the Applet.
However, I don't know how to set the size on the GridLayout or the Panel containing it, since it must know the viewing-browser's page size (to make it as large as possible) and I'm of the impression that the html specified geometry overrides the Applet specified.
EDIT:
Attempting to implement Andrew's suggestion;
screen = new JPanel(new GridLayout(rows, columns)) {
public Dimension getPreferredSize() {
Dimension expected = super.getPreferredSize();
// calculate preferred size using expected, rows, columns
return new Dimension(100, 100) // testing
}
public Dimension getSize() {
return getPreferredSize();
}
};
I understand this ignores the 'minimum size' stuff, but that doesn't matter at the moment.
Screen is placed in the center of a border layout, containing other widgets
getContentPane().add(screen, BorderLayout.CENTER);
getContentPane().add(otherWidgets, BorderLayout.PAGE_END);
I know this doesn't make screen centered in the space it has, but that's not entirely necessary at the moment so I want to keep things as simple as possible.
This isn't at all working; there's no visible difference from what I had before (when viewed through Eclipse; I haven't even reached the html stage yet) excepting the minimum size stuff. The screen component is still being re-sized by the applet at leisure, making the cells 'unsquare'. What am I doing wrong?
Put the grid layout container into a grid bag layout as the only component with no constraint, as seen in this answer. That will center it.
Update
And of course, put it in a component that returns a preferred size equating to the maximum square size it can manage depending on the parent size. Such as in SquarePanel.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
/**
* A square panel for rendering. NOTE: To work correctly, this must be the only
* component in a parent with a layout that allows the child to decide the size.
*/
class SquarePanel extends JPanel {
#Override
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
System.out.println("Preferred Size: " + d);
int w = (int) d.getWidth();
int h = (int) d.getHeight();
// Set s to the larger of the mimimum component width or height
int s = (w > h ? w : h);
Container c = getParent();
if (c != null ){
Dimension sz = c.getSize();
if ( d.getWidth()<sz.getWidth() ) {
// Increase w to the size available in the parent container
w = (int)sz.getWidth();
System.out.println("WxH: " + w + "x" + h);
// recalculate s
s = (w < h ? w : h);
}
if ( d.getHeight()<sz.getHeight()) {
// Increase h to the size available in the parent container
h = (int)sz.getHeight();
System.out.println("WxH: " + w + "x" + h);
// recalculate s
s = (w < h ? w : h);
}
}
// Use s as the basis of a square of side length s.
System.out.println("Square Preferred Size: " + new Dimension(s, s));
return new Dimension(s, s);
}
#Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
#Override
public Dimension getSize() {
return getPreferredSize();
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
// the GUI as seen by the user (without frame)
// A single component added to a GBL with no constraint
// will be centered.
JPanel gui = new JPanel(new GridBagLayout());
gui.setBackground(Color.BLUE);
SquarePanel p = new SquarePanel();
p.setBorder(new EmptyBorder(5,15,5,15));
p.setLayout(new GridLayout(3,0,2,2));
for (int ii=1; ii<13; ii++) {
p.add(new JButton("" + ii));
}
p.setBackground(Color.red);
gui.add(p);
JFrame f = new JFrame("Demo");
f.add(gui);
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See https://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}

Making sure SpringLayout doesn't shrink below a certain size

I'm trying to implement a quite simple UI using SpringLayout (partly because I, as opposed to most tutorial writers I find on the net, quite like the coding interface compared to other layout managers and partly because I want to learn how to use it). The UI basically looks like this:
This is all well. The UI resizes the way I want (keeping the welcome text centered and expanding the text area to fill all the new available space) if I increase the window size. However, below a certain point (more specifically when the window becomes too narrow for the welcome text):
I would like the window to not allow further shrinking, so that if the user tries to shrink the window to a size smaller than enough to house the components, it simply stops. How do I accomplish this, using the SpringLayout layout manager?
I know I could probably do this by handling some resize-event and checking if the minimum size is reach, and then just set the size to the minimum size. But this requires me to a) know, or know how to calculate, the minimum size of the window, even before it renders, b) write a bunch of event-handling code just to get some UI rendering right, and c) write a bunch of code for things that I expect a good layout manager to take care of ;)
you can override MinimumSize for TopLevelContainer
you have put JTextArea to the JScrollPane
easiest way is mixing LayoutManagers (called as NestedLayout) by spliting GUI to the parts (separated JPanels with same or different LayoutManager), rather than implements some most sofisticated LayoutManager (GridBagLayout or SpringLayout) for whole Container
some LayoutManagers pretty ignore setXxxSize
SpringLayout isn't my cup of Java
import java.awt.*;
import javax.swing.*;
public class MinSizeForContainer {
private JFrame frame = new JFrame("some frame title");
public MinSizeForContainer() {
JTextArea textArea = new JTextArea(15, 30);
JScrollPane scrollPane = new JScrollPane(textArea);
CustomJPanel fatherPanel = new CustomJPanel();
fatherPanel.setLayout(new SpringLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(fatherPanel, BorderLayout.CENTER);
frame.setLocation(20, 20);
frame.setMinimumSize(fatherPanel.getMinimumSize());
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MinSizeForContainer Mpgp = new MinSizeForContainer();
}
});
}
}
class CustomJPanel extends JPanel {
private static final long serialVersionUID = 1L;
#Override
public Dimension getMinimumSize() {
return new Dimension(400, 400);
}
}
There are several issues to achieve a "real" (that is not shrinkable beyond) min size:
the child components must return some reasonable (based on their content) min size, many core components don't
the layoutManager must respect the compounded min of all children, no matter how little space is available
the top-level container (here the JFrame) must not allow shrinking beyond the min
The first is true for a JLabel, the second is met for SpringLayout (that's why the label is truncated) - which leaves the third as the underlying problem, the solution to which isn't obvious, actually I wasn't aware it's even possible before running #mKorbel's example. The relevant line indeed is
frame.setMinimumSize(someSize);
With that line in place, it's not possible to shrink the frame below. Without, it is. Starting from that observation, some digging turns out the doc for its override in Window
Sets the minimum size of this window to a constant value. [..] If
current window's size is less than minimumSize the size of the window
is automatically enlarged to honor the minimum size. If the setSize or
setBounds methods are called afterwards with a width or height less
[...] is automatically enlarged to honor the minimumSize value.
Resizing operation may be restricted if the user tries to resize
window below the minimumSize value. This behaviour is platform-dependent.
Looking at the code, there are two (implementation, don't rely on them :-) details related to the min size
Dimension minSize;
boolean minSizeSet;
and public api to access
public Dimension getMinimumSize()
public boolean isMininumSizeSet()
the first rather oldish (jdk1.1), the latter rather newish (jdk1.5) - implying that the first can't rely on the latter but internally has to check for a null minSize. The overridden sizing methods (with their guarantee to doing their best to respect a manually set minSize) on Window are the latest (jdk6) and do rely on the latter. Or in other words: overriding isMinimumSizeSet does the trick.
Some code snippet (beware: it's a hack, untested, might well be OS dependent with undesirable side-effects!):
// JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("some frame title") {
/**
* Overridden to tricks sizing to respect the min.
*/
#Override
public boolean isMinimumSizeSet() {
return true; //super.isMinimumSizeSet();
}
/**
* Overridden to adjust for insets if tricksing and not using
* LAF decorations.
*/
#Override
public Dimension getMinimumSize() {
Dimension dim = super.getMinimumSize();
// adjust for insets if we are faking the isMinSet
if (!super.isMinimumSizeSet() && !isDefaultLookAndFeelDecorated()) {
Insets insets = getInsets();
dim.width += insets.left + insets.right;
dim.height += insets.bottom + insets.top;
}
return dim;
}
};
// add a component which reports a content-related min
JLabel label = new JLabel("Welcome to my application!");
// make it a big min
label.setFont(label.getFont().deriveFont(40f));
frame.add(label);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);

Why jframe hides taskbar when maximized?

I'm using setUndecorated(true); and getRootPane().setWindowDecorationStyle(JRootPane.FRAME); in my jFrame. This works great but now when I maximized my frame it spreads all over the window even taskbar is not visible. What can I do to make frame not to hide taskbar?
Also when I maximize minimize my frame multiple times the cursor is changed to this <-> which is generally used change size of frame when cursor is on the border of frame. Is there anything I can do for this?
A small code then can reproduce the thing:
import javax.swing.JFrame;
import javax.swing.JRootPane;
public class Demo extends JFrame {
public Demo() {
setSize(250,125);
setUndecorated(true);
getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
setVisible(true);
}
public static void main(String[] args) {
new Demo();
}
}
This is a known bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4737788
Quote from this link:
A workaround is to subclass JFrame and
override the setExtendedState method,
catching any maximize events before
they happen and setting the maximum
bounds of the frame appropriately
before calling the superclass's
setExtendedState method.
import java.awt.*;
import javax.swing.*;
public class PFrame extends JFrame
{
private Rectangle maxBounds;
public PFrame()
{
super();
maxBounds = null;
}
//Full implementation has other JFrame constructors
public Rectangle getMaximizedBounds()
{
return(maxBounds);
}
public synchronized void setMaximizedBounds(Rectangle maxBounds)
{
this.maxBounds = maxBounds;
super.setMaximizedBounds(maxBounds);
}
public synchronized void setExtendedState(int state)
{
if (maxBounds == null &&
(state & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH)
{
Insets screenInsets = getToolkit().getScreenInsets(getGraphicsConfiguration());
Rectangle screenSize = getGraphicsConfiguration().getBounds();
Rectangle maxBounds = new Rectangle(screenInsets.left + screenSize.x,
screenInsets.top + screenSize.y,
screenSize.x + screenSize.width - screenInsets.right - screenInsets.left,
screenSize.y + screenSize.height - screenInsets.bottom - screenInsets.top);
super.setMaximizedBounds(maxBounds);
}
super.setExtendedState(state);
}
}
Fortega answer worked however, some part is not needed (or no longer needed with Java 8):
The Rectangle does not need to be saved.
The code does not take into account dual screen configuration. In particular, the GraphicsConfiguration will change if the window change screen.
As far as I tested, the only required override is setExtendedState.
When factoring dual screen configuration, at least on Windows, the below code does not work as intended:
Rectangle maxBounds = new Rectangle(screenInsets.left + screenSize.x,
screenInsets.top + screenSize.y,
screenSize.x + screenSize.width - screenInsets.right - screenInsets.left,
screenSize.y + screenSize.height - screenInsets.bottom - screenInsets.top);
On the following dual screen set up:
Left screen 1920x1080 (not primary), position: -1920, 0
Right screen 1920x1080 (primary), position: 0, 0
The maxBounds will contains negative x (-1920) but the setMaximizedBounds is somehow expecting a coordinate in the screen space (where (x,y) starts at (0,0)) , not the virtual screen:
It will set to setMaximizedBounds(x=-1920,y=0,width=1920,height=1050)
Windows will see the window on the left screen (because I have one taskbar per screen showing only window on that screen) however the window won't be shown on the screen because it is off bounds.
If the resolution of the screen, or worse, its scale factor (with a laptop, Windows 10 will apply a scale factor, ex: 25%, making the screen "not so" 1920x1080), then the above code does not adapt. For example, if my configuration have 3 screens with the right most being the primary, the window will badly display on the left and middle screen. I don't think I fixed this in the below code.
The following code work on Windows, with dual screen:
#Override
public synchronized void setExtendedState(final int state) {
if ((state & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH) {
final GraphicsConfiguration cfg = getGraphicsConfiguration();
final Insets screenInsets = getToolkit().getScreenInsets(cfg);
final Rectangle screenBounds = cfg.getBounds();
final int x = screenInsets.left + screenBounds.x * 0;
final int y = screenInsets.top + screenBounds.y * 0;
final int w = screenBounds.width - screenInsets.right - screenInsets.left;
final int h = screenBounds.height - screenInsets.bottom - screenInsets.top;
final Rectangle maximizedBounds = new Rectangle(x, y, w, h);
System.out.println("cfg (" + cfg + ") screen.{bounds: " + screenBounds + ", insets: " + screenInsets + ", maxBounds: " + maximizedBounds);
super.setMaximizedBounds(maximizedBounds);
}
super.setExtendedState(state);
}
On a simple JFrame:
Maximizing on the left screen ("screen=0") will print cfg (D3DGraphicsConfig[dev=D3DGraphicsDevice[screen=0],pixfmt=0]) screen.{bounds: java.awt.Rectangle[x=-1920,y=0,width=1920,height=1080], insets: java.awt.Insets[top=0,left=0,bottom=30,right=0], maxBounds: java.awt.Rectangle[x=0,y=0,width=1920,height=1050]
Maximizing on the right screen ("screen=1") will print cfg (D3DGraphicsConfig[dev=D3DGraphicsDevice[screen=1],pixfmt=0]) screen.{bounds: java.awt.Rectangle[x=0,y=0,width=1920,height=1080], insets: java.awt.Insets[top=0,left=0,bottom=30,right=0], maxBounds: java.awt.Rectangle[x=0,y=0,width=1920,height=1050]
Maybe you can set the maximum size of the jFrame and restrict it according to the screen size.
EDIT
Also check out setExtendedState
Starting from Fortega answer, you can make it work even with 125% screen sizi adding
Rectangle screenSize = getGraphicsConfiguration().getBounds();
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
screenSize.setSize(new Dimension(gd.getDisplayMode().getWidth(), gd.getDisplayMode().getHeight()));
......

How come JFrame window size in Java does not produce the size of window specified?

I am just messing around trying to make a game right now, but I have had this problem before too. When I specify a specific window size (1024 x 768 for instance) the window produced is just a little larger than what I specified. Very annoying. Is there a reason for this? How do I correct it so the window created is actually the size I want instead of being just a little bit bigger? Up till now I have always just gone back and manually adjusted the size a few pixels at a time until I got the result I wanted, but that is getting old. If there was even a formula I could use that would tell me how many pixels I needed to add/subtract from my my variable that would be excellent!
P.S. I don't know if my OS could be a factor in this, but I am using W7X64.
private int windowWidth = 1024;
private int windowHeight = 768;
public SomeWindow() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(windowWidth, windowHeight);
this.setResizable(false);
this.setLocation(0,0);
this.setVisible(true);
}
I want the total frame that Windows
creates to be the exact size I specify
I don't understand your problem. Post your SSCCE that shows the problem.
If I run code like:
frame.setResizable(false);
frame.setSize(1024, 768);
frame.setVisible(true);
System.out.println(frame.getSize());
It displays java.awt.Dimension[width=1024,height=768], is that not what you expect?
If there was even a formula I could
use that would tell me how many pixels
I needed to add/subtract from my my
variable that would be excellent!
Maybe you are referring to the space occupied by the title bar and borders?
import java.awt.*;
import javax.swing.*;
public class FrameInfo
{
public static void main(String[] args)
{
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
Rectangle bounds = env.getMaximumWindowBounds();
System.out.println("Screen Bounds: " + bounds );
GraphicsDevice screen = env.getDefaultScreenDevice();
GraphicsConfiguration config = screen.getDefaultConfiguration();
System.out.println("Screen Size : " + config.getBounds());
JFrame frame = new JFrame("Frame Info");
System.out.println("Frame Insets : " + frame.getInsets() );
frame.setSize(200, 200);
System.out.println("Frame Insets : " + frame.getInsets() );
frame.setVisible( true );
System.out.println("Frame Size : " + frame.getSize() );
System.out.println("Frame Insets : " + frame.getInsets() );
System.out.println("Content Size : " + frame.getContentPane().getSize() );
}
}
When you say the obtained window size is not the asked one, are you talking about the window, with its decorations ?
Indeed, window size is defined without OS specific window decoration.
Try to add
this.setUndecorated(true);
before the
this.setVisible(true);

Categories