Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: immerhartОтветов: 7

У меня странная проблема. Я использую нулевой макет для окна (= 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);
    }
}
  • Вы получите более качественные и быстрые ответы, если покажете SSCCE. assylias 27.06.2012
  • есть пример, не могу вставить остальное, потому что за ним работает xml-parser и многое другое... и проблема возникает только с вызовом setResizable immerhart 27.06.2012
  • Я не могу воспроизвести поведение. Поэтому постарайтесь избавиться от всех ненужных частей и опубликуйте компилируемый и работающий пример, который ведет себя так, как вы упомянули. assylias 27.06.2012
  • влияет ли "xml-parser" или "многое другое" на размер окна? user85421 27.06.2012
  • jframe является членом, а setBounds() вызывается только в конструкторе. как я уже сказал, я не могу вставить больше, так как есть много классов, которыми я не владею. в любом случае, я вижу, что трудно помочь, но я думал, что у кого-то может быть такая же проблема... immerhart 27.06.2012
  • действительно странно - может воспроизводиться (на Vista), LAF, похоже, не имеет значения, украшение окна имеет одинаковый размер ... понятия не имею, почему .. kleopatra 27.06.2012

javawindowswing

Ответы

Ответ 1 · рейтинг 14 · Guillaume Polet

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

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, хотя граница (которую рисует ОС) остается фактически той же. Поскольку вставки являются частью границ фрейма, фрейм на самом деле слишком большой (визуально), когда его размер нельзя изменить. Для меня это похоже на ошибку в вычисляемых вставках, когда размер кадра не изменяется.

Ответ 2 · рейтинг 5 · mapadj

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

Ответ 3 · рейтинг 1 · Gergely Szilagyi

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

Ответ 4 · рейтинг 1 · barwnikk

Заменять:

frame.setResizable(false);

to:

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            frame.setResizable(false);
        }
    });

Ответ 5 · рейтинг 1 · WesternGun

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

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

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

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

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

Ответ 6 · Andrei Mesh

На данный момент лучший патч для этой надоедливой проблемы следующий. Неважно, где вы вызываете метод 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().

Ответ 7 · KnowsPicker

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы