Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Почему setResizable() меняет размер фрейма!? 
V
    Опции темы
freshAngel
  Дата 20.3.2009, 17:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 248
Регистрация: 1.10.2008

Репутация: нет
Всего: нет



Привет, очень интересно почему происходит следующая вещь.
Простой пример программы. 
Код

 import javax.swing.*;   
 import javax.swing.JPanel;   
 import javax.swing.BoxLayout;   
 import javax.swing.border.LineBorder;   
 import javax.swing.border.EmptyBorder;   
 import javax.swing.border.CompoundBorder;   
 import javax.swing.border.TitledBorder;   
 import java.awt.*;   
    
 public class Main {   
    
     /**  
      * @param args the command line arguments  
      */   
    
     public static void main(String[] args) {   
         MyFrame frame = new MyFrame();   
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
         frame.show();   
     }   
    
 } // End class Main   
    
 class MyFrame extends JFrame   
 {   
     public MyFrame()   
     {   
         setTitle("App");   
         MyPanel panel = new MyPanel();   
         setResizable(false);    
         setContentPane(panel);   
            
         System.out.println(getSize());   
         System.out.println(this.getPreferredSize());   
    
         pack();   
    
         System.out.println(getSize());   
         System.out.println(this.getPreferredSize());   
     }   
    
 } // End class MyFrame   
    
 class MyPanel extends JPanel   
 {   
     public MyPanel()   
         {   
 // Заполняем Panel   
          }   
 }   


Интересная вещь.
Если поставить setResizable(false) выдается одно значение размеров окна, в моем случае например:

java.awt.Dimension[width=374,height=296]
java.awt.Dimension[width=374,height=296]

А если setResizable(true) размер окна увеличивается:

java.awt.Dimension[width=384,height=306]
java.awt.Dimension[width=384,height=306]

Хотя само окно ни коем образом не меняется!
С чем это связано!?
Я конечно понимаю, что если использовать pack(), устанавливающий все размеры объектов на форме в PrefferedSize - то все сухо и прекрасно Smile
Но мне во первых хочется понять почему так, а во вторых я использую
setBounds() для установки размеров окна.

PM MAIL   Вверх
Turinets
Дата 21.3.2009, 09:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 24.2.2009

Репутация: нет
Всего: нет



Ну если приглядеться, то можно увидеть, что границы фрейма с изменяющимися размерами больше, чем у стационарного. Другими словами фрейм в Шубе будет больше чем в майке.

А вот что меня удивляет, так это то, что меняется и внутренняя часть:

Код

System.out.println(this.getContentPane().getSize());


А ведь размеры внутренней части ДОЛЖНЫ оставаться неизменными. В соседнем топике парень хотел сделать фрейи с заданными размерами внутренней части фрейма. У меня на винде такая вещь выходит: что при setResizeable(false) получается правильные размеры 200,200. А без него 202,202.
И вот это я совсем не понимаю.

Тебя не должны интересовать размеры фрейма, тебе нужны размеры именно внутренней части, а сам фрейм - это просто обводка вокрух них.
PM MAIL   Вверх
freshAngel
  Дата 21.3.2009, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 248
Регистрация: 1.10.2008

Репутация: нет
Всего: нет



Цитата(Turinets @ 21.3.2009,  09:31)
Ну если приглядеться, то можно увидеть, что границы фрейма с изменяющимися размерами больше, чем у стационарного. Другими словами фрейм в Шубе будет больше чем в майке.

 smile 
Все - же хорошо, что есть pack()
Выход из положения придумал такой:
Код

class MyFrame extends JFrame
{
    public MyFrame()
    {
        setTitle("App");
        MyPanel panel = new MyPanel();
        this.setResizable(true); // Запрещаем менять размер
        setContentPane(panel);

     /*
    Если нужно жестко задать размеры окна, независимо от setResizable(), меняем желаемый размер.
    */
   
     //this.setPreferredSize(new Dimension(100,100));

    pack();

    System.out.println("Size "+panel.getSize().getWidth()+"  "+panel.getSize().getHeight());
    System.out.println("Size "+this.getContentPane().getSize().getWidth()+"  "+this.getContentPane().getSize().getHeight());
    System.out.println(getSize());
    System.out.println(this.getPreferredSize());
    }

} // End class MyFrame


А еще интересно почему вместо pack() не работает такая конструкция:
Код

setSize(this.getPreferredSize());


PM MAIL   Вверх
Turinets
Дата 21.3.2009, 11:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 24.2.2009

Репутация: нет
Всего: нет



А зачем тебе фиксированный размер окна?

Если нужен именно фиксированный размер фрейма, то тут кроме setSize() ничего и не нужно. pack() использовать смысла нет. Вроде если менять размер, то все внутреннии контейнеры выровняются "по линии" как надо (как компоновщик скажет), если надо вызвать самому, то getContentPane().doLayuot();

А что зачит не работает? Какой эффект должен быть по вашему, которого нет?
PM MAIL   Вверх
freshAngel
  Дата 21.3.2009, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 248
Регистрация: 1.10.2008

Репутация: нет
Всего: нет



Цитата(Turinets @ 21.3.2009,  11:07)
А что зачит не работает? Какой эффект должен быть по вашему, которого нет?

Почему pack() != setSize(this.getPreferredSize());
Ведь это одно и тоже.

Что касается фиксированного размера фрейма, тут тоже странно.
Например, setSize(200,200) при setResizable(true) дает лишние отступы примерно в 2px по краям фрейма. Хотя я задал фиксированный размер!

При использовании pack(), размер фрейма автоматически подстраивается под нужный. 
PM MAIL   Вверх
Turinets
Дата 21.3.2009, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 24.2.2009

Репутация: нет
Всего: нет



А разве это должно быть одним и темже?

getPrefferedSize() даёт установленные тобой  "Предпочтительный" размер. pack() опрашивает внутренние контейнеры и на основании их предпочтительных размеров (или минимальных точно не помню) будет и подгоняться внешний компонент. Т.е. если у тебя предпочтительный размер фрейма 300,300 , а у панели предпочтительный 400,400 , то pack()  сделает размеры примерно 400,400, а вот setSize(getPrefferedSize()) сделает размеры близкие к 300,300.

pack() - это очень хитрая вещь. Согласись, что "подстроить под нужный" двумя строчками кода нельзя. Там хитрый алгоритм. pack() старается сжать внешние контейнеры исходя из размеров внутренних.
PM MAIL   Вверх
freshAngel
  Дата 21.3.2009, 18:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 248
Регистрация: 1.10.2008

Репутация: нет
Всего: нет



Цитата(Turinets @ 21.3.2009,  17:03)
 Т.е. если у тебя предпочтительный размер фрейма 300,300 , а у панели предпочтительный 400,400 , то pack()  сделает размеры примерно 400,400, а вот setSize(getPrefferedSize()) сделает размеры близкие к 300,300.

Хмм.
А разве размер фрейма не должен принимать предпочтительные размеры панели установленной в него методом setContentPane()
Тогда почему не работает такая конструкция:

setSize(panel.getPrefferedSize()) != this.pack();

setSize() - в данном случае содержит именно предпочтительные размеры панели.
PM MAIL   Вверх
Turinets
Дата 21.3.2009, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 24.2.2009

Репутация: нет
Всего: нет



Пусть ты сделал так:

panel.setPreferredSize(new Dimension(300,300));

Теперь если Ты сделаешь так:

frame.setSize(panel.getPreferredSize())

то фрейм примет размеры (300,300), а если так:

frame.pack()

фрейм станет скажем (306, 326).

Код

import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class AlfaFrame {

    public static void main(String[] args) {
        JFrame frame = new JFrame("Sample");
        JPanel panel = new JPanel() {
        };

        panel.setPreferredSize(new Dimension(300, 300));
        frame.getContentPane().add(panel);

        frame.setResizable(false);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        System.out.println("Size panel " + panel.getSize().getWidth() + "  " + panel.getSize().getHeight());
        System.out.println("Size frame " + frame.getSize().getWidth() + "  " + frame.getSize().getHeight());
        System.out.println("setSize");
        
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ex) {
        }
        frame.setSize(panel.getPreferredSize());

        System.out.println("Size panel " + panel.getSize().getWidth() + "  " + panel.getSize().getHeight());
        System.out.println("Size frame " + frame.getSize().getWidth() + "  " + frame.getSize().getHeight());
        System.out.println("Size pane " + frame.getContentPane().getSize().getWidth() + "  " + frame.getContentPane().getSize().getHeight());
    }
}


У меня этот код выдает:
Код

Size panel 300.0  300.0
Size frame 306.0  327.0
setSize
Size panel 294.0  273.0
Size frame 300.0  300.0
Size pane 294.0  273.0



Из чего видим, что  в первом случае pack() ОБВОРАЧИВАТ панель с размерами, а во втором случае сам принимает такие размеры, из-за чего внутренней панели приходиться немного уменьшется.

Пойми, что сам фрейм имеет не нулевую толщину границ, например 306 получается путём добавление к 300 пикселам панели 2 границы по 3 пиксела с двух сторон, а 327 получается потому, что у фрейма есть вверху TitleBar. В любом случае Размеры самого фрейма будут больше, чем размеры внутренней панели. и они отличаются на толщину гранищы. Размер фрейма = размер левой границы + размер панели + размер правой границы. Т.е. размер фрейма != размеру панели и это очевидно.

Точно так же, как обхват талии девушки в шубе будет больше, чем без шубы, потому что сама шуба имеет не нулевую толщину.

Если ты про это. 
Предположим талия у КАТИ условно 60 см. ШУБА.pack() придаст шубе такой размер, который удобен для девушки, т.е. 60см+5см = 65см. А ШУБА.setSize(КАТЯ.getPreferredSize()) заставит Катю немного похудеть.
PM MAIL   Вверх
freshAngel
  Дата 21.3.2009, 23:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 248
Регистрация: 1.10.2008

Репутация: нет
Всего: нет



Цитата(Turinets @ 21.3.2009,  20:45)
Точно так же, как обхват талии девушки в шубе будет больше, чем без шубы, потому что сама шуба имеет не нулевую толщину.

Если ты про это. 
Предположим талия у КАТИ условно 60 см. ШУБА.pack() придаст шубе такой размер, который удобен для девушки, т.е. 60см+5см = 65см. А ШУБА.setSize(КАТЯ.getPreferredSize()) заставит Катю немного похудеть.

Пример с Катей удался  smile 
Проверил, осознал!
Спасибо.

Если касаться основного вопроса, то получается setResizable(true) либо setResizable(false), дополнительно увеличивает либо уменьшает границы фрейма соотвественно!?

Цитата(Turinets @ 21.3.2009,  09:31)

Ну если приглядеться, то можно увидеть, что границы фрейма с изменяющимися размерами больше, чем у стационарного. Другими словами фрейм в Шубе будет больше чем в майке.


Понял!

Спасибо большое, разобрался!  smile 


Это сообщение отредактировал(а) freshAngel - 21.3.2009, 23:35
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   jk1
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, jk1.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: GUI и Java FX приложения | Следующая тема »


 




[ Время генерации скрипта: 0.0743 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.