Ссылка 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.
FlowLayout
выложит Component
s слева направо (или справа налево), завернув их, если потребуется. Если вы хотите явно задать размер каждого JButton
, вы должны использовать setPreferredSize, а не setSize
, поскольку менеджеры макета обычно используют минимальные, предпочтительные и максимальные размеры при выполнении макета.
Свойства размера весьма запутанны. Здесь есть интересная статья . В частности, обратите внимание:
Сохраняются ли свойства размера?
Некоторые менеджеры макетов, такие как GridLayout, полностью игнорируют свойства размера.
FlowLayout, пытается оценить оба размера preferredSize и, возможно, не нуждается в соблюдении минимального размера или максимального размера.
Во-первых, вы не используете JFrame
правильно: вы не добавляете компоненты непосредственно в фрейм, вы добавляете их в JPanel
, которые затем переходите к кадру с помощью setContentPane()
.
Также: не очень элегантно напрямую подкласс JFrame
просто добавить компоненты. Вместо этого создайте свой кадр как отдельный объект.
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
автоматически перейдите на панель содержимого.