Макеты в java Swing с указанием размера

У меня вопрос, как я могу указать размер деталей на моем макете?
Мне нужно как-то установить размер «частей», не используя preferSize, может быть, в менеджерах компоновки, неважно где - мне нужен только стабильный размер.

Я хочу создать макет для игры. Я уже создал один, но у меня проблема с размером компонентов. Поэтому я подумал, что было бы лучше разработать концепцию моего макета.
Давайте посмотрим на мой черновик.


+-----------+ 
| UPPER     |
+-----+-----+
|  A  |     |
+-----+  C  |
|  B  |     |
+-----+-----+
| Footer    |
+-----------+

A+B+C make together Center.

Основная часть состоит из этих частей дерева:
Верхняя - там будет меню.
Центр - состоит из 3 частей: A, B, C
Нижний колонтитул - там будет строка состояния


Моя идея - установить размер каждый компонент. Весь макет зависит от части C, она может иметь размер 450x450 пикселей или 600x600 пикселей.
Для частей A и B мне нужно указать только ширину, потому что там будет только некоторая текстовая информация - она ​​должна быть около 300 пикселей. < br /> Я попытался использовать GridBagLayout для центральной части, но setSize для C не сработал.
Я делаю части в контейнерах (java.awt.Container) - в них я добавляю содержимое каждой части, а затем добавить Контейнер на верхний уровень.


person user1097772    schedule 08.02.2012    source источник
comment
Вы не должны устанавливать размер компонентов. Компоненты должны знать свой предпочтительный размер и возвращать его при вызове getPreferredSize (). В большинстве макетов используется предпочтительный размер компонентов, чтобы разместить их соответствующим образом.   -  person JB Nizet    schedule 08.02.2012
comment
Хорошо, я обнаружил, что это работа менеджеров по расположению ... Я не хочу устанавливать предпочтительный размер компонента. Могу ли я установить строго размер компонента в Диспетчере макетов (менеджерах)?   -  person user1097772    schedule 08.02.2012
comment
Вы не можете установить размеры элементов управления вручную, если вы полностью не воздержитесь от использования диспетчера компоновки и не сделаете это все вручную. Боюсь, что средней дороги нет.   -  person Andreas Baus    schedule 08.02.2012
comment
Я бы установил предпочтительный размер C, pack() графического интерфейса пользователя и вызвал бы setResizable(false) на фрейме.   -  person Andrew Thompson    schedule 08.02.2012
comment
Привет ... Я сейчас борюсь с этим. Я нахожусь на ранней стадии своего графического интерфейса, и у меня уже возникают проблемы с основной панелью, которая должна расширяться, чтобы заполнить (оставшуюся) доступную область. Это раздражает. Я также внутренне чувствую, что макет ДОЛЖЕН заполнять доступное опубликованное пространство - так же, как типографское происхождение термина связано с публикацией, макет - это макет страницы (в целом)!   -  person will    schedule 06.08.2012
comment
@will Я не понимаю сути вашего комментария ... просто раскачивание макетов - одно большое бесполезное дерьмо. Если у вас такая же проблема и вам нужен удобный и простой макет, используйте miglayout.com.   -  person user1097772    schedule 06.08.2012
comment
Спасибо user1097772, вы правы; вы не понимаете проблемы. MigLayout не работает с JLayeredPane. Это не вина mig, похоже, что JLayeredPane не выполняет слои как панели в направлении z (глядя на источник). Если MigLayout делал слои; это лучшее предложение.   -  person will    schedule 27.08.2012


Ответы (5)


Самый простой способ: использовать BorderLayout для contentPane (который уже есть) - Верхняя панель переходит на север - панель нижнего колонтитула идет на юг - Панели A и B переходят в Panel ab с GridLayout (2,1) - Panel ab и C переходит в Панель abc с GridLayout (1,2) - Панель abc переходит в центр и setPrefferedSize () ваших A, B, C

person xyz    schedule 08.02.2012
comment
Извините, но это не ответ на мой вопрос ... Как установить размер деталей. - person user1097772; 08.02.2012
comment
Установка предпочтительного размера компонента C - это все, что необходимо (в дополнение к общей стратегии xyz) для создания графического интерфейса пользователя с логическим размером. Если вы хотите немного «растушевать», добавьте границы там, где это необходимо. Я собирался создать графический интерфейс, который в основном следовал формуле, обозначенной xyz, пока а) я не увидел, что это уже было сказано, и б) вы заявили, что это не то, что нужно! - person Andrew Thompson; 08.02.2012
comment
Я не согласен, потому что это причина того, что размер ab (соответственно ширина, высота тоже такая же, но это не проблема) будет таким же, как размер C. (Установка предпочтительного размера также на ab тоже не работает ..). - person user1097772; 08.02.2012
comment
Ты прав. тогда вы должны использовать GridBagLayout при добавлении панелей ab и C в другую панель и, конечно же, setPreferredSize из C. - person xyz; 08.02.2012
comment
@xyz Когда я использую GridBagLayout, то preferSize перестает работать на C, и вы не можете видеть только части частей A, B, C ... Это магический круг ... - person user1097772; 08.02.2012

Как правило, GridBagLayout игнорирует значения, которые вы устанавливаете для элементов управления с помощью setSize, вместо этого он запрашивает у элементов управления их предпочтительный размер (путем вызова getPreferredSize) и использует его для расчета общего макета. Не рекомендуется просто устанавливать этот предпочтительный размер самостоятельно, поскольку большинство элементов управления имеют тенденцию пересчитывать эти значения при каждом запуске макета, поэтому вам будет сложно заставить их «закрепиться».

Если вы действительно хотите убедиться, что элемент пользовательского интерфейса C имеет определенный размер, реализуйте его как настраиваемый класс, полученный из подходящей базы (например, JPanel), и переопределите метод getPreferredSize, чтобы он возвращал размер, который вам нужен / нужен для этой части вашего пользовательского интерфейса.

Изменить: Вот небольшой пример оболочки, которая может содержать другой элемент пользовательского интерфейса и может иметь фиксированный размер (с использованием метода setSize, который был переопределен), который должен соблюдаться менеджерами по макету:

import java.awt.BorderLayout;
import java.awt.Dimension;

import javax.swing.JComponent;
import javax.swing.JPanel;

public class FixedSizeComponent extends JPanel {
    private Dimension size;
    private final JComponent content;

    public FixedSizeComponent(JComponent content) {
        super(new BorderLayout());
        this.content = content;
        super.add(content, BorderLayout.CENTER);
    }

    @Override
    public void setSize(Dimension d) {
        size = d;
    }

    @Override
    public void setSize(int width, int height) {
        size = new Dimension(width, height);
    }

    @Override
    public Dimension getSize() {
        if (size != null) return size;
        return content.getSize();
    }

    @Override
    public Dimension getSize(Dimension rv) {
        if (size != null) {
            if (rv == null) rv = new Dimension();
            rv.height = size.height;
            rv.width = size.width;
            return rv;
        }
        return content.getSize(rv);
    }

    @Override
    public Dimension getPreferredSize() {
        if (size != null) return size;
        return content.getPreferredSize();
    }

    @Override
    public Dimension getMaximumSize() {
        if (size != null) return size;
        return content.getMaximumSize();
    }

    @Override
    public Dimension getMinimumSize() {
        if (size != null) return size;
        return content.getMinimumSize();
    }
}
person Andreas Baus    schedule 08.02.2012
comment
Да, и чтобы было действительно, действительно быть уверенным, лучше переопределить методы getMaximumSize и getMinimumSize ... - person Andreas Baus; 08.02.2012
comment
Если вы действительно хотите убедиться, что элемент пользовательского интерфейса C имеет определенный размер, ... переопределите getPreferredSize Некоторые менеджеры компоновки не будут соблюдать предпочтительный размер. И я никогда не понимал преимущества переопределения setPreferredSize(), когда вы можете просто вызвать его из конструктора и предоставить разработчику право выбирать, является ли предпочтительный размер default желаемым размером. - person Andrew Thompson; 08.02.2012
comment
По моему опыту, предпочтительный размер элементов управления имеет тенденцию пересчитываться всякий раз, когда что-либо делает текущий макет недействительным, поэтому, если вы просто установили его один раз во время создания пользовательского интерфейса, пересчет приведет к перезаписи вашего вручную установленного предпочтительного размера и вашего тщательно упорядоченного макет разрушается. - person Andreas Baus; 08.02.2012
comment
Я считаю это весьма сомнительным. При установке предпочтительного размера компонента (вне конструктора или переопределенного метода) этот предпочтительный размер сохраняется независимо от того, что еще происходит в графическом интерфейсе (за исключением другого явного вызова setPreferredSize() в самом компоненте). Это может игнорироваться макетом, но это совершенно отдельный вопрос. - person Andrew Thompson; 08.02.2012

У меня была аналогичная проблема с панелью инструментов состояния внизу, содержащей ряд других компонентов. Моя проблема заключалась в том, что он стал выше. Поэтому я переопределил максимальный размер, установив максимальную высоту как минимальную.

JPanel status = new JPanel( new SpringLayout() ) {
  @Override
  public Dimension getMaximumSize() {
    Dimension max = super.getMaximumSize();
    Dimension min = getMinimumSize();
    return new Dimension( max.width, min.height );
  }
};
person eweb    schedule 09.06.2012

Этот ответ слишком мал и слишком поздно,

(возможно, на момент постановки этого вопроса этого метода не существовало)

как и getPreferredSize, существует также setPreferredSize метод, который принимает объект Dimension.

По умолчанию ваш макет будет игнорировать размеры ваших компонентов (которые вы могли установить с помощью setSize), вместо этого он будет использовать предпочтительные размеры.

Используя setPreferredSize, вы сможете переопределить предпочтительные размеры компонента по умолчанию.

person Navin Israni    schedule 09.08.2016

Надеюсь, мой ответ может вам чем-то помочь. По опыту настройки размера JPanel или JFrame я всегда использовал setPreferredSize(new Dimension(WIDTH,HEIGHT));

person AWb    schedule 08.02.2012
comment
Не поймите меня неправильно, использование нулевого макета - плохая практика; но, конечно, в крайнем случае, когда у вас возникли проблемы с выбором лучшего менеджера компоновки для использования, и ни один из них, похоже, не делает то, что вы хотите? - person AWb; 08.02.2012
comment
Нулевой макет никогда не является ответом. - person mre; 08.02.2012
comment