Swing — это библиотека Java для построения оконного графического интерфейса (GUI): окна, кнопки, поля ввода, списки и таблицы. Она входит в набор Java Foundation Classes (JFC), надстроена над более старым пакетом AWT и рисует свои компоненты сама, поэтому одинаково выглядит на Windows, macOS и Linux.
Содержание
Ниже разберем, из чего собирается Swing-приложение (окно JFrame, панель содержимого, менеджеры компоновки), и подробно — работу со списками: обычным JList с моделью и обработкой выбора и выпадающим JComboBox. Все примеры — законченные программы, которые можно скопировать и запустить.
Swing или AWT: что выбрать
AWT (Abstract Window Toolkit) — первый оконный пакет Java. Его компоненты — это обертки над «родными» элементами операционной системы (их называют тяжеловесными). Swing свои компоненты рисует сам средствами Java (легковесные), поэтому дает единый вид на всех платформах и намного больше готовых элементов.
| Признак | AWT | Swing |
|---|---|---|
| Отрисовка компонентов | системные (native) элементы | рисуются самой Java |
| Зависимость от платформы | внешний вид зависит от ОС | одинаковый вид везде |
| Набор компонентов | базовый | широкий (таблицы, деревья, списки) |
| Архитектура модель-представление | нет | есть (модель отделена от вида) |
| Подключаемый вид (look and feel) | нет | есть |
На практике новый оконный код на чистом AWT почти не пишут: берут Swing, а из AWT используют только базовые классы, на которых Swing построен — Container, менеджеры компоновки, классы событий. Полностью заменять Swing на AWT смысла нет.
Важна оговорка про современный Java: Swing по-прежнему поставляется в составе JDK и поддерживается, но новые крупные интерфейсы часто делают на отдельном тулките JavaFX или на вебе. Апплеты (JApplet, Applet) — мертвая ветка: Applet API объявлен устаревшим и намеченным к удалению в JDK 17 (JEP 398), браузеры давно не запускают апплеты, использовать его не нужно.
Каркас Swing-приложения
Любое окно Swing собирается из нескольких обязательных частей:
JFrame— главное окно приложения с рамкой и заголовком (это контейнер верхнего уровня).- панель содержимого (content pane) — область внутри окна, куда добавляют компоненты.
- менеджер компоновки (layout manager) — решает, как расположить компоненты внутри контейнера.
Начнем с минимального полного примера — окна с одной надписью:
import javax.swing.*;
public class Hello {
public static void main(String[] args) {
// Весь код интерфейса выполняем в потоке обработки событий (EDT)
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Первое окно Swing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // крестик закрывает программу
frame.add(new JLabel("Привет, Swing!", SwingConstants.CENTER));
frame.setSize(300, 120);
frame.setLocationRelativeTo(null); // окно по центру экрана
frame.setVisible(true); // без этой строки окно не появится
});
}
}
Что произойдет при запуске: откроется окно 300×120 по центру экрана с надписью «Привет, Swing!». В консоль ничего не выводится — это чисто оконная программа.
Две строки тут критичны для новичка: setVisible(true) показывает окно (без нее программа завершится, ничего не показав), а setDefaultCloseOperation(EXIT_ON_CLOSE) завершает приложение при закрытии окна (иначе процесс останется висеть в памяти).
Про SwingUtilities.invokeLater скажу отдельно ниже — это не украшение, а правило потока.
Менеджеры компоновки
Swing почти никогда не расставляет компоненты по пикселям вручную — за раскладку отвечает менеджер компоновки. Основные из них:
| Менеджер | Как располагает |
|---|---|
FlowLayout |
по строке слева направо, с переносом |
BorderLayout |
пять зон: центр и четыре стороны (север, юг, запад, восток) |
GridLayout |
равные ячейки таблицы |
BoxLayout |
в один ряд по вертикали или горизонтали |
GridBagLayout |
гибкая сетка с разными размерами ячеек |
У JFrame по умолчанию стоит BorderLayout, поэтому в примере со списком ниже мы кладем список в центр, а строку статуса — на юг.
Список JList: модель, выбор, слушатель
JList — это компонент Swing для показа списка элементов, из которых пользователь выбирает один или несколько. Данные и способ их показа в нем разделены на три части, и это ключевая идея Swing:
- модель данных (
ListModel) — что показывать: сами элементы списка. Для типовых случаев берут готовуюDefaultListModel, в которую элементы добавляют и удаляют. - модель выбора (
ListSelectionModel) — что сейчас выделено. По умолчанию уже подключенаDefaultListSelectionModel. - отрисовщик (
ListCellRenderer) — как рисовать элемент; для строк подходит стандартный, менять его нужно только для своего оформления.
У выбора есть три режима, их задают через setSelectionMode:
| Режим | Что позволяет выделить |
|---|---|
SINGLE_SELECTION |
ровно один элемент |
SINGLE_INTERVAL_SELECTION |
один непрерывный диапазон |
MULTIPLE_INTERVAL_SELECTION |
любой набор элементов (режим по умолчанию) |
Чтобы реагировать на выбор, к списку добавляют слушатель ListSelectionListener. Соберем рабочее окно: список языков, а под ним — строка, которая показывает выбранный элемент.
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.BorderLayout;
public class ListDemo {
public static void main(String[] args) {
SwingUtilities.invokeLater(ListDemo::createUi);
}
private static void createUi() {
// Модель данных: что показывать в списке
DefaultListModel<String> model = new DefaultListModel<>();
model.addElement("Python");
model.addElement("Java");
model.addElement("Go");
model.addElement("Rust");
JList<String> list = new JList<>(model);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); // выбираем один элемент
JLabel status = new JLabel("Ничего не выбрано");
list.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
// событие приходит дважды на один клик; берем только устоявшийся выбор
if (!e.getValueIsAdjusting()) {
String value = list.getSelectedValue();
status.setText("Выбрано: " + value);
System.out.println("Выбрано: " + value);
}
}
});
JFrame frame = new JFrame("Список языков");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(list), BorderLayout.CENTER); // список в прокрутке, в центре окна
frame.add(status, BorderLayout.SOUTH); // статус снизу
frame.setSize(300, 220);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Что произойдет: откроется окно со списком из четырех языков. Если кликнуть по строке «Java», надпись внизу станет «Выбрано: Java», и в консоль выведется та же строка:
Выбрано: Java
Здесь заметны два практических момента. Первый: список всегда кладут в JScrollPane — тогда при большом числе элементов появляется полоса прокрутки. Второй: проверка getValueIsAdjusting() отсекает промежуточные срабатывания (на один выбор событие приходит дважды — в начале и в конце), иначе обработчик выполнится лишний раз.
Если разрешить множественный выбор (MULTIPLE_INTERVAL_SELECTION), выбранные элементы берут методом getSelectedValuesList(), который возвращает список значений (он доступен начиная с Java 7). Для одиночного режима удобнее getSelectedValue().
Выпадающий список JComboBox
Когда на экране мало места, а выбрать нужно один вариант, вместо JList берут JComboBox — выпадающий список. В свернутом виде он показывает один выбранный элемент, а остальные раскрываются по клику.
import javax.swing.*;
import java.awt.FlowLayout;
public class ComboDemo {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
String[] items = {"Junior", "Middle", "Senior"};
JComboBox<String> combo = new JComboBox<>(items);
// ActionListener срабатывает при выборе пункта
combo.addActionListener(e ->
System.out.println("Выбран уровень: " + combo.getSelectedItem()));
JFrame frame = new JFrame("Выпадающий список");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(new JLabel("Уровень:"));
frame.add(combo);
frame.setSize(320, 120);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
Что произойдет: в окне будет надпись «Уровень:» и рядом выпадающий список. При выборе пункта «Senior» в консоль выведется:
Выбран уровень: Senior
Разница с JList в интенте, а не в устройстве: JComboBox тоже опирается на модель (ComboBoxModel, наследник ListModel) и подходит для выбора одного значения из компактного перечня; JList показывает элементы сразу и удобнее для множественного выбора и длинных списков.
Почему весь код в invokeLater
Swing не потокобезопасен: обращаться к его компонентам можно только из специального потока обработки событий (Event Dispatch Thread, EDT). Поэтому построение окна оборачивают в SwingUtilities.invokeLater(...) — так код гарантированно выполнится в EDT.
Отсюда же практическое правило: долгую работу (запрос к сети, чтение большого файла) в EDT выполнять нельзя — интерфейс замрет и перестанет отвечать. Такую работу выносят в фоновый поток, обычно через класс SwingWorker, а результат возвращают в EDT для показа.
Если окно ведет себя не так
- Окно не появилось — забыли
setVisible(true)или программа завершилась раньше, чем показала окно. - Компоненты налезают друг на друга или окно пустое — не задан менеджер компоновки или все компоненты попали в одну зону
BorderLayout(по умолчанию — центр). - Список без прокрутки при большом числе элементов —
JListне обернут вJScrollPane. - Интерфейс завис после нажатия — в EDT запущена долгая операция, ее нужно вынести в фоновый поток.
Выводы
- Swing — библиотека Java для оконного GUI поверх AWT: рисует компоненты сама, поэтому дает единый вид на всех платформах и богатый набор элементов.
- Новый оконный код пишут на Swing, из AWT берут только базовые классы; апплеты (
JApplet) — мертвая ветка, Applet API намечен к удалению (deprecated for removal) с JDK 17. - В
JListданные и выбор разделены:ListModel(чащеDefaultListModel) хранит элементы,ListSelectionModel— выделение; реагируют на выбор черезListSelectionListenerс проверкойgetValueIsAdjusting(). JComboBox— выпадающий выбор одного значения;JList— показ элементов сразу и множественный выбор, обычно внутриJScrollPane.- Весь код интерфейса выполняют в потоке EDT (
SwingUtilities.invokeLater), а долгую работу выносят в фоновый поток.
Где применяется и что учить дальше
Swing до сих пор держит десктопные инструменты Java: среды разработки семейства IntelliJ IDEA, клиенты баз данных, внутренние корпоративные приложения. Умение собрать окно, вывести данные списком и обработать выбор пользователя — базовый навык, который нужен и для настольных программ, и как ступень к пониманию событийной модели интерфейсов вообще.
Освойте тему на практике
Если хочется освоить Java системно — от синтаксиса и ООП до работы с интерфейсом и коллекциями, — посмотрите курс Java Developer. Basic. Оценить формат и уровень до старта помогают бесплатные открытые уроки Otus — живые занятия с преподавателями.
FAQ
Swing умер, стоит ли его учить в 2026 году? Swing по-прежнему входит в JDK и поддерживается, на нем работают крупные десктопные приложения. Для нового большого интерфейса чаще берут JavaFX или веб, но Swing остается рабочим инструментом и хорошей базой для понимания оконного GUI.
Чем JList отличается от JComboBox? JList показывает все элементы сразу и позволяет выбрать несколько; JComboBox в свернутом виде показывает один выбранный элемент, а остальные раскрывает по клику, и рассчитан на выбор одного значения.
Как в JList разрешить выбор нескольких элементов? Задать режим setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION) и читать выделенное методом getSelectedValuesList().



