I hope you are having a good day.
NOTE: I have found the issue of this - High DPI Scaling. Since my computer was scaling everything to 250%, setMinimumSize
wasn't working. Here is a bug report on it. Does anyone have a workaround that doesn't use addComponentListener
(reasoning is below).
Today I was working on a Java Swing project when I tried to change the minimum size for the JFrame
window. At first, I tried frame.setMinimumSize(new Dimension(500, 500));
. The problem was (I think this has to do with my screen dimensions) that it did kind of work, but it would let me resize the window way less than 500, 500
(the window would stop resizing at about 100
pixels).
EDIT: Here is the code I used to test this:
import javax.swing.*;
import java.awt.*;
class Test {
public static void main(String[] args) {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setMinimumSize(new Dimension(500, 500));
frame.pack();
frame.setSize(500, 500);
frame.setVisible(true);
}
}
Here is what happens to the frame when I resize it:
After I googled it up, I found out you could do this neat little hack (this is just one of the many versions of the same code that showed up):
import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
class Test {
public static void main(String[] args) {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setMinimumSize(new Dimension(500, 500));
frame.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent evt) {
Dimension size = frame.getSize();
Dimension min = frame.getMinimumSize();
frame.setSize((int) Math.max(min.getHeight(), size.getHeight()),
(int) Math.max(min.getWidth(), size.getWidth()));
}
});
frame.pack();
frame.setSize(500, 500);
frame.setVisible(true);
}
}
Here is what happens when I resize this:
The problem with this was that (even though it worked), it would glitch a lot when I tried to resize past the minimum size as it is not fast enough to change it back before the user resizes it.
After more googling, I found a bug report here. I tried out this code from the comments (yes, I did edit it to use Math.max
):
import javax.swing.*;
import java.awt.*;
class Test {
public static void main(String[] args) {
JFrame frame = new JFrame("Test") {
@Override
public Dimension getPreferredSize()
{
Dimension pSize = super.getPreferredSize();
Dimension mSize = getMinimumSize();
int wid, ht;
wid = Math.max(pSize.width, mSize.width);
ht = Math.max(pSize.height, mSize.height);
return new Dimension(wid, ht);
}
};
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setMinimumSize(new Dimension(500, 500));
frame.pack();
frame.setSize(500, 500);
frame.setVisible(true);
}
}
This had no effect on the window (it behaved exactly like the first setMinimumSize
trick).
EDIT 2: I also tried this (as @camickr suggested):
import javax.swing.*;
import java.awt.*;
class Test {
public static void main(String[] args) {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setMinimumSize(new Dimension(500, 500));
frame.setSize(750, 750);
frame.setVisible(true);
}
}
But it gave the same output as the first trick (setMinimumSize
).
I also removed all setPreferredSize
lines as there is no layout manager (more info here).
I am using Windows 10 and JDK v13.0.2 - here is the output from java -version
:
java version "13.0.2" 2020-01-14
Java(TM) SE Runtime Environment (build 13.0.2+8)
Java HotSpot(TM) 64-Bit Server VM (build 13.0.2+8, mixed mode, sharing)
And the output from javac -version
:
javac 13.0.2
EDIT 3: I have recently tried using JDK 11, but it gave the same results as JDK 13 (Looks like this is computer/platform-specific).
Does anyone know a way to fix this?