Вот фрагмент кода, который работает на JFrame
, а также на AWT Frame
(который является супертипом JFrame):
public static Dimension getInnerSize(Frame frame) {
Dimension size = frame.getSize();
Insets insets = frame.getInsets();
if (insets != null) {
size.height -= insets.top + insets.bottom;
size.width -= insets.left + insets.right;
}
return size;
}
Осторожно: вставки действительны только после показа рамки.
Вот еще один фрагмент кода для решения этой проблемы:
private static Insets defaultInsets;
public static Insets getInsetsWithDefault(Frame frame) {
// insets only correct after pack() and setVisible(true) has been
// called, so we use some fallback strategies
Insets insets = frame.getInsets();
if (insets.top == 0) {
insets = defaultInsets;
if (insets == null) {
insets = new Insets(26, 3, 3, 3);
// usual values for windows as our last resort
// but only as long as we never saw any real insets
}
} else if (defaultInsets == null) {
defaultInsets = (Insets) insets.clone();
}
return insets;
}
Этот код необходимо вызывать один раз с видимым фреймом. После этого он может правильно предсказать вставки даже для невидимых кадров (из-за кэширования defaultInsets
), предполагая, что они всегда одинаковы.
Конечно, это работает, только если все окна имеют одинаковые художественные оформления окон. Но я не знаю ни одного случая, когда они могли бы отличаться от окна к окну.
Это также может быть полезно:
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent e) {
MyUtilClass.getInsetsWithDefault(frame); // init the defaultInsets
}
});
Он вызовет метод getInsetsWithDefault()
, как только окно станет видимым, и инициализирует правильный defaultInsets
.