Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pack, but don't make it smaller

Tags:

java

swing

pack

I have JFrame with GridBagLayout. User can resize this window. Also, he can perform some editing actions that change window size. I use pack(); repaint(); now after such actions. But, actually I shouldn't make window smaller after such operations - only bigger. What I found as solution is

    Dimension oldSize = getSize();
    pack();
    Dimension newSize = window.getSize();
    setSize(
            (int) Math.max(newSize.getWidth(), oldSize.getWidth()),
            (int) Math.max(newSize.getHeight(), oldSize.getHeight()));
    repaint();

But I don't like this solution at all. Beside ugly code, we set size twice (once by pack and than directly). Is there any other solutions?

like image 655
Stan Kurilin Avatar asked Jun 26 '11 17:06

Stan Kurilin


2 Answers

A simple solution would be to use something like this:

frame.setMinimumSize(frame.getSize());
frame.pack();
frame.setMinimumSize(null);

This will not allow pack() to make the window smaller, only bigger, I think. By resetting the minimum size to null after the pack() we avoid preventing the user on resizing it smaller afterwards.

You should not need a repaint() at the end, the size changing should trigger a repaint by itself. (Of course, make sure that all these actions happen in the event dispatch thread.)

like image 154
Paŭlo Ebermann Avatar answered Nov 10 '22 01:11

Paŭlo Ebermann


An alternative solution to the one proposed by Paŭlo is the following code:

private boolean greater(Dimension left, Dimension right) {
    return left.getHeight() > right.getHeight() || left.getWidth() > right.getWidth();
}

if (greater(window.getPreferredSize(), window.getSize())) {
    window.pack();
}

The advantage of this solution is that pack isn't called unless it is necessary, and it avoids a flicker we observed on Linux with Paŭlo's solution.

like image 1
Gian Avatar answered Nov 10 '22 02:11

Gian