JFrame shrinks when given its own bounds.

N

Nelson Ashton

I have a window that sometimes displays fairly large amounts of data.
When this happened, the window would end up larger than the screen, so
I shoehorned everything into a JScrollPane, which didn't make any
difference. I then tried

frame.setMaximumSize(Toolkit.getDefaultToolkit().getScreenSize());

without any effect. Apparently JFrame ignores its own maximum size
when pack() is called.

Which led to:

frame.pack();
Rectangle bounds = frame.getBounds();
if (bounds.width > maxWidth || bounds.height > maxHeight) {
frame.setBounds(0, 0,
(bounds.width < maxWidth) ? bounds.width : maxWidth,
(bounds.height < maxHeight) ? bounds.height : maxHeight);
}
frame.setLocationRelativeTo(null);

Here, maxWidth and maxHeight come from getScreenSize() as above. It
works -- sort of. When the packed frame tries to be too large, the
above code forces it to fit on the screen, without enlarging any
dimension. And, as hoped, the lost space is taken from the
JScrollPane, which then displays its scrollbars and provides a
scrolling view on the huge contents.

Unfortunately, the above does not quite work perfectly because it
always shrinks both dimensions of the JFrame, even if one was less
than its maximum! In particular, this implies that
frame.setBounds(frame.getBounds()) would not be a no-op but would
shrink the frame slightly. The shrinkage is only 10-20 pixels or so in
each dimension, but it's troublesome.

Either getBounds() is not reporting the true size of the frame, or
setBounds() trims some off.

Any suggestions on how to get rid of this shrinkage, so that each
dimension is the smaller of the dimension it has immediately after
pack() or maxFoo?
 
K

Knute Johnson

Nelson said:
I have a window that sometimes displays fairly large amounts of data.
When this happened, the window would end up larger than the screen, so
I shoehorned everything into a JScrollPane, which didn't make any
difference. I then tried

frame.setMaximumSize(Toolkit.getDefaultToolkit().getScreenSize());

without any effect. Apparently JFrame ignores its own maximum size
when pack() is called.

Which led to:

frame.pack();
Rectangle bounds = frame.getBounds();
if (bounds.width > maxWidth || bounds.height > maxHeight) {
frame.setBounds(0, 0,
(bounds.width < maxWidth) ? bounds.width : maxWidth,
(bounds.height < maxHeight) ? bounds.height : maxHeight);
}
frame.setLocationRelativeTo(null);

Here, maxWidth and maxHeight come from getScreenSize() as above. It
works -- sort of. When the packed frame tries to be too large, the
above code forces it to fit on the screen, without enlarging any
dimension. And, as hoped, the lost space is taken from the
JScrollPane, which then displays its scrollbars and provides a
scrolling view on the huge contents.

Unfortunately, the above does not quite work perfectly because it
always shrinks both dimensions of the JFrame, even if one was less
than its maximum! In particular, this implies that
frame.setBounds(frame.getBounds()) would not be a no-op but would
shrink the frame slightly. The shrinkage is only 10-20 pixels or so in
each dimension, but it's troublesome.

Either getBounds() is not reporting the true size of the frame, or
setBounds() trims some off.

Any suggestions on how to get rid of this shrinkage, so that each
dimension is the smaller of the dimension it has immediately after
pack() or maxFoo?

Usually you either want to pack your components into the smallest frame
or you know the size you want to make your frame. When you want to
display really big things sometimes you need to make the frame fit the
screen.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class test66 extends JFrame {
public test66() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel p = new JPanel();
p.setPreferredSize(new Dimension(1600,1200));
JScrollPane sp = new JScrollPane(p);
add(sp);
pack();
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
if (getWidth() > d.width)
setSize(d.width,getHeight());
if (getHeight() > d.height)
setSize(getWidth(),d.height);
setVisible(true);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new test66();
}
});
}
}
 
N

Nelson Ashton

         Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
         if (getWidth() > d.width)
             setSize(d.width,getHeight());
         if (getHeight() > d.height)
             setSize(getWidth(),d.height);

Same problem. If only the height should be changed, the width shrinks
slightly instead of remaining unchanged. The decrease is only by about
15 pixels, but it's rather annoying.
 
N

Nelson Ashton

Same problem. If only the height should be changed, the width shrinks
slightly instead of remaining unchanged. The decrease is only by about
15 pixels, but it's rather annoying.

Solved. The scroll pane scrollbars were the culprit. Specifically,
after pack and before programmatic resize there was no vertical
scrollbar. Then the same horizontal size of frame is used, but the
vertical scrollbar eats about 16 pixels of the horizontal space in the
scroll pane, which makes the scroll pane's client area just too narrow
for its contents, and then the horizontal scrollbar also pops up and
eats some *vertical* space.

Forcing the scrollpane to always display its scrollbars before the
pack fixes everything.
 
K

Knute Johnson

Nelson said:
Same problem. If only the height should be changed, the width shrinks
slightly instead of remaining unchanged. The decrease is only by about
15 pixels, but it's rather annoying.

Are you talking about the left and right frame border that doesn't exist
in a maximised frame?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top