Почему JPanel не принимает размеры своих внутренних компонентов? [Дубликат]

Ссылка NullReferenceException или Object, не установленная на экземпляр объекта, возникает, когда объект класса, который вы пытаетесь использовать, не создается. Например:

Предположим, что у вас есть класс с именем Student.

public class Student
{
    private string FirstName;
    private string LastName;
    public string GetFullName()
    {
        return FirstName + LastName;
    }
}

Теперь рассмотрим другой класс, в котором вы пытаетесь получить полное имя учащегося.

public class StudentInfo
{      
    public string GetStudentName()
    {
        Student s;
        string fullname = s.GetFullName();
        return fullname;
    }        
}

Как видно из вышеприведенного кода, оператор Student s - объявляет только переменную типа Student, обратите внимание, что класс Student не создается в этой точке. Следовательно, когда выполняется выполнение инструкции s.GetFullName (), она выкинет исключение NullReferenceException.

2
задан There is nothing we can do 29 March 2010 в 14:47
поделиться

3 ответа

FlowLayout выложит Component s слева направо (или справа налево), завернув их, если потребуется. Если вы хотите явно задать размер каждого JButton, вы должны использовать setPreferredSize, а не setSize, поскольку менеджеры макета обычно используют минимальные, предпочтительные и максимальные размеры при выполнении макета.

Свойства размера весьма запутанны. Здесь есть интересная статья . В частности, обратите внимание:

Сохраняются ли свойства размера?

Некоторые менеджеры макетов, такие как GridLayout, полностью игнорируют свойства размера.

FlowLayout, пытается оценить оба размера preferredSize и, возможно, не нуждается в соблюдении минимального размера или максимального размера.

5
ответ дан Adamski 25 August 2018 в 11:02
поделиться
  • 1
    Но почему 3? Если кадр 200, я думал, что будет место только для двух кнопок? – There is nothing we can do 29 March 2010 в 14:50
  • 2
    Извините, я поправлю свой ответ. – Adamski 29 March 2010 в 14:54
  • 3
    Так что в основном ответ ...? – There is nothing we can do 29 March 2010 в 15:16
  • 4
    Нет, ответ заключается в том, что FlowLayout будет уважать предпочтительный размер, поэтому вы должны его использовать. Он игнорирует вызов setSize и просто подбирает каждый JButton в соответствии с его предпочтительнымSize, который продиктован текстом внутри кнопки (потому что вы не задали его явно). – Adamski 29 March 2010 в 15:34

Во-первых, вы не используете JFrame правильно: вы не добавляете компоненты непосредственно в фрейм, вы добавляете их в JPanel, которые затем переходите к кадру с помощью setContentPane().

Также: не очень элегантно напрямую подкласс JFrame просто добавить компоненты. Вместо этого создайте свой кадр как отдельный объект.

-2
ответ дан Anon 25 August 2018 в 11:02
поделиться
  • 1
    Это не отвечает на вопрос ОП. Также нет ничего плохого в написании frame.add (Component). Из документа JFrame: «В качестве добавления добавления и его вариантов remove и setLayout были переопределены для пересылки на контентную панель по мере необходимости. Это означает, что вы можете написать: frame.add (child); & quot ;. Наконец, я не обязательно считаю, что это неправильная практика для подкласса JFrame для вашего фрейма приложения верхнего уровня (как и для подкласса JPanel). В противном случае вы просто получите тонну кода Swing в своем основном классе. – Adamski 29 March 2010 в 15:03
  • 2
    @Adamski - я бы тоже не подклассировал JPanel. Во-первых, это нарушает Принцип замещения Лискова. Также нет причин помещать этот код в ваш основной класс: ваши классы могут управлять своими кадрами / панелями, они просто не должны подклассифицировать JFrame / JPanel. – Anon 29 March 2010 в 15:15
  • 3
    Почему это нарушает принцип? JPanel - это просто пустой компонент, и, следовательно, если я подклассифицирую его как MyPanel, а затем заменяю в использовании MyPanel, мое приложение некорректно? Все методы JPanel будут по-прежнему вести себя так, как ожидалось. Этим признаком JFileChooser и JColorChooser также нарушили принцип, потому что они подклассы JComponent. – Adamski 29 March 2010 в 15:43
  • 4
    @Adamski - возьмите свой подкласс и передайте его в некоторый код, который ожидает пустую панель. Является ли он заменяемым? – Anon 29 March 2010 в 15:47
  • 5
    Это то же самое, что и расширение Thread, а не внедрение Runnable. Вы не меняете функциональность JPanel, вы просто добавляете в нее компоненты. – Anon 29 March 2010 в 15:49

FlowLayout просто помещает компонент один рядом с другим в порядке слева направо. Когда ширина достигает одного из контейнеров, которые имеют этот макет, он просто переносится на другую строку.

Если вы хотите разместить их в макете в виде сетки (как вам кажется, вы хотите), вы можете использовать GridLayout, который позволяет указать количество столбцов и строк:

component.setLayout(new GridLayout(2,2))

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

Если вам действительно нужно больше энергии, переходите к GridBagLayout, очень настраиваемому, но с более крутым

Вероятно, проблема вашего размера связана с тем, что вы используете setSize, но в Swing эти вещи имеют странное поведение, вы должны попробовать, установив setPreferredSize(200,200) вместо setSize. Но не спрашивайте меня, почему!

ПРИМЕЧАНИЕ: вы должны ВСЕГДА обращаться к области содержимого фрейма, а не к кадру. Когда вы устанавливаете макет, вы должны делать getContentPane().setLayout(..), когда вы добавляете элементы, которые вы должны делать getContentPane().add(..) и т. Д.

Исправлены: теперь каждый JFrame add, remove, setLayout автоматически перейдите на панель содержимого.

0
ответ дан Jack 25 August 2018 в 11:02
поделиться
  • 1
    Теперь больше не нужно обращаться непосредственно к области содержимого JFrame, поскольку добавление, удаление и setLayout были отменены для перенаправления этих вызовов на панель содержимого. – Adamski 29 March 2010 в 15:05
  • 2
    Да, я уже проверил его и отредактировал перед вашим комментарием :) – Jack 29 March 2010 в 15:21
Другие вопросы по тегам:

Похожие вопросы: