Java setResizable(false) изменяет размер окна (качели)

У меня странная проблема. Я использую нулевой макет для окна (= JFrame и для окон), и если я использую setResizable (false), размер окна увеличивается (справа и снизу, я бы сказал, около 10 пикселей). Я не знаю, почему.

Два println возвращают одинаковые размеры, что тоже странно...

mainWnd.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWnd.setTitle(wndTitle);
mainWnd.setBounds(wndPosX, wndPosY, wndWidth, wndHeight);
System.out.println(mainWnd.getHeight() + mainWnd.getWidth());
mainWnd.setResizable(false);
System.out.println(mainWnd.getHeight() + mainWnd.getWidth());

У кого-нибудь есть идея? Почему размер окна меняется?

ОБНОВЛЕНИЕ: То же самое здесь (скомпилируйте его с setResizable и без него, и тогда вы сможете его увидеть, если вы перекрываете окна):

import javax.swing.JFrame;
import javax.swing.JPanel;


public class Main
{
    private static JFrame mainWnd = null;

    public static void main(String[] args)
    {
        mainWnd = new JFrame();

        mainWnd.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainWnd.setTitle("asda");
        mainWnd.setBounds(50, 50, 300, 300);

        mainWnd.setResizable(false);

        mainWnd.setVisible(true);
    }
}

person immerhart    schedule 27.06.2012    source источник
comment
Вы получите более качественные и быстрые ответы, если покажете SSCCE.   -  person assylias    schedule 27.06.2012
comment
есть пример, не могу вставить остальное, потому что за ним работает xml-parser и многое другое... и проблема возникает только с вызовом setResizable   -  person immerhart    schedule 27.06.2012
comment
Я не могу воспроизвести поведение. Поэтому постарайтесь избавиться от всех ненужных частей и опубликуйте компилируемый и работающий пример, который ведет себя так, как вы упомянули.   -  person assylias    schedule 27.06.2012
comment
влияет ли «xml-parser» или «многое другое» на размер окна?   -  person user85421    schedule 27.06.2012
comment
jframe является членом, а setBounds() вызывается только в конструкторе. как я уже сказал, я не могу вставить больше, так как есть много классов, которыми я не владею. в любом случае, я вижу, что трудно помочь, но я думал, что у кого-то может быть такая же проблема...   -  person immerhart    schedule 27.06.2012
comment
действительно странно - может воспроизводиться (на Vista), LAF, похоже, не имеет значения, украшение окна имеет одинаковый размер ... понятия не имею, почему ..   -  person kleopatra    schedule 27.06.2012
comment
Наблюдаю аналогичную ошибку в Linux Gnome (AdoptJDK 11). Отслеживание событий контейнера, когда рамка становится видимой, панель содержимого сначала закрашивается на 10 и 7 пикселей, затем приходит другое событие изменения размера и отображение корректно. Раздражающий визуальный глюк. Возможно связано.   -  person 0__    schedule 29.03.2021


Ответы (7)


В моем примере это не меняется, поэтому у вас должно быть что-то еще, что вызывает вашу проблему:

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Test4 {

    protected static void initUI() {
        JFrame frame = new JFrame("test");
        frame.setBounds(0, 0, 300, 200);
        frame.setVisible(true);
        System.err.println(frame.getSize());
        frame.setResizable(false);
        System.err.println(frame.getSize());
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                initUI();
            }
        });
    }
}

РЕДАКТИРОВАТЬ/ОБНОВИТЬ:

Почему-то вставки неверны, когда вы устанавливаете для изменяемого размера значение false (по крайней мере, в Windows 7 и JDK 6). Каким-то образом они меняются с 30,8,8,8 на 25,3,3,3, хотя граница (которую рисует ОС) остается фактически той же. Поскольку вставки являются частью границ фрейма, фрейм на самом деле слишком большой (визуально), когда его размер нельзя изменить. Для меня это похоже на ошибку в вычисляемых вставках, когда размер кадра не изменяется.

person Guillaume Polet    schedule 27.06.2012
comment
я думаю, вы должны запустить оба окна, тогда вы увидите, что неизменяемый размер больше! - person immerhart; 27.06.2012
comment
Почему-то вставки неверны, когда вы устанавливаете для изменяемого размера значение false (по крайней мере, в Windows 7 и JDK 6). Каким-то образом они меняются с 30,8,8,8 на 25,3,3,3, хотя граница фактически остается прежней. Поскольку вставки являются частью границ фрейма, фрейм на самом деле слишком большой (визуально), когда его размер нельзя изменить. Для меня это похоже на ошибку в вычисляемых вставках, когда размер кадра не изменяется. - person Guillaume Polet; 27.06.2012
comment
хороший отслеживание (в вашем комментарии) - вы можете подумать о том, чтобы переместить его в ответ, чтобы я мог проголосовать за него :-) - person kleopatra; 28.06.2012
comment
@Guillaume Polet Извините, это некро, но я наткнулся на это, пытаясь решить эту проблему. Решение состоит в использовании: getContentPane().setPreferredSize(new Dimension(600, 400)); установитьРазмер (ложь); пакет(); В таком порядке, поэтому вам нужно вызвать пакет после того, как вы установите Resizable (false). Не могли бы вы добавить его, чтобы другие могли быстрее найти решение? Спасибо! - person deadfire19; 11.04.2014
comment
@deadfire19 Deadfire19 У меня это не работает, хотя я также хотел бы иметь возможность переключаться между изменяемыми состояниями, не изменяя размер моего фрейма на 10 по ширине и высоте, а также немного перемещая его ... - person salbeira; 14.09.2014

Если вы установите setResizable false перед установкой границ, у вас не будет проблемы. как уже говорил Гергели Силаги, вы избавляетесь от полос прокрутки, но размер окна заблокирован, и поэтому вы получаете 9 или 10 пикселей дополнительного пространства в кадре. У меня была такая же проблема. Спасибо за помощь.

person mapadj    schedule 02.02.2014
comment
Нет, это продолжает давать мне разницу между двумя JFrames. - person WesternGun; 01.06.2017

В зависимости от настройки L&F изменяемый размер (false/true) может изменить оформление границ окна. Нет максимизации, нет стрелки изменения размера. Это само по себе может изменить размер.

person Gergely Szilagyi    schedule 27.06.2012
comment
В моем случае, без другого набора L&F, например, с внешним видом по умолчанию, он также меняет размер окна. - person WesternGun; 01.06.2017

Заменять:

frame.setResizable(false);

to:

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            frame.setResizable(false);
        }
    });
person barwnikk    schedule 11.08.2013
comment
Проблема сохраняется. Это не решение. - person WesternGun; 01.06.2017

Ну, я столкнулся с этой проблемой, и это проблема Look & Feel ...

Почему изменяемый размер рамки имеет вставки (5, 5, 5, 5)? Это наводит меня на мысль, что сделать его изменяемым по размеру добавляет какой-то дополнительный компонент вокруг фрейма, например... какой-то «обработчик», который нужно перетаскивать для изменения размера?

А потом я обнаружил, что если мы используем по умолчанию Java Metal l&f и установим setDefaultLookAndFeelDecorated(true), обработчик будет окрашен и, таким образом, размер рамки не изменится. Но в Nimbus, Motif и Windows L&F этот пункт не реализован, так что это баг. Я сообщу об этом.

Мой собственный вопрос и мой ответ с GIF здесь:

Swing - setResizable (true) сделать строку заголовка JFrame выше, а размер окна меньше

person WesternGun    schedule 01.06.2017

На данный момент лучший патч для этой надоедливой проблемы следующий. Неважно, где вы вызываете метод setResizable(false). Просто добавьте этот фрагмент кода после того, как вы setVisible(true).

private void sizeBugPatch() {
    while (frame.getWidth() > yourWidth) {
        frame.pack();
    }
}

Где yourWidth – это ширина, которую вы установили любым из возможных способов, либо вручную, либо путем переопределения setPreferredSize методов. Объяснение довольно простое, frame.pack() как-то сбрасывает frame.setResizable(boolean b). Вы можете использовать if вместо цикла while, но я предпочитаю while, чтобы исключить случай, когда окно все еще будет увеличено даже после второго pack().

person Andrei Mesh    schedule 21.07.2016

У меня есть 2 подкласса JFrame. Если я запускаю проблемный фрейм в отдельном приложении, размер фрейма правильный. Если я запускаю оба кадра в отдельном приложении, проблемный кадр все еще больше. Я установил setResizable(false) перед упаковкой, но проблема все еще возникает. Мой обходной путь состоял в том, чтобы изменить макет на BorderLayout и поместить панель (изображение) в центр, а затем выполнить setResizable.

person KnowsPicker    schedule 19.08.2016