Java Swing — окна и кнопки

Приветствую! Здесь вы наверняка найдете, что ищете. Примеры в лаборатории рассчитаны на то, что мы разбираем что-то конкретное.

Текущая статья посвящена примерам: Swing на Java с построчным разбором.

Поэтому за теорией по текущей теме вам — в энциклопедию. Если ещё не погружались, то маршрут прост:

  1. Основы
  2. Система и сеть
  3. Данные и разметка
  4. Код и разработка
  5. Языки
  6. Искусственный интеллект
  7. Проект
  8. Инфраструктура и безопасность
  9. Спин-офф

Обязательно пройдитесь.

А теперь приступим к нашему предмету.

Теория и соседние материалы

Обзор GUI — JavaFX и GUI (там же сравнение со Swing).

Рецепты по элементам — справочник JavaFX и Swing.

Короткие примеры в энциклопедии — Простые приложения.

Аналог на Python — Tkinter — окна и виджеты.

Мобильный UI — Flutter — готовые виджеты.

Поток UI и «зависание» окна — особенности десктопа.


Подборка готовых программ на Java Swing с построчным разбором — «что написано» и «зачем так».


Навигация по примерам

Раздел Тема
Каркас Swing java swing tutorial, jframe example, SwingUtilities invokeLater
Окно с меткой jlabel example java, java gui hello world
Кнопка и диалог jbutton click listener java, joptionpane showmessagedialog
Поле ввода jtextfield get text, java gui input dialog
Конвертер °C java temperature converter gui, jtextfield parse double
Чекбоксы и радио jcheckbox jradiobutton example, ButtonGroup java
Список задач jlist add element, DefaultListModel java
Ползунок jslider example, ChangeListener java swing
Форма входа gridlayout jpanel, jpasswordfield example
Меню jmenubar example, jmenuitem actionlistener
Калькулятор java calculator swing, gridbaglayout example
Популярные запросы java gui calculator, swing login form, jframe set size
Частые ошибки jvm not exiting, swing ui thread, could not find main class

Из чего состоит окно на Swing

Любая учебная программа с GUI строится из трёх слоёв:

  1. ОкноJFrame (рамка, заголовок, кнопка закрытия).
  2. КонтейнерJPanel с менеджером компоновки (FlowLayout, BorderLayout, GridLayout…).
  3. ВиджетыJLabel, JButton, JTextField и остальные элементы.
JFrame  «Моё приложение»
  └── ContentPane (по умолчанию BorderLayout)
        ├── NORTH  → JToolBar (кнопки «Новый», «Сохранить»)
        ├── CENTER → JPanel + поля ввода
        └── SOUTH  → JLabel «Готово» (строка состояния)
Консольная программа Swing-приложение
Scanner читает из терминала JTextField.getText() читает из поля
System.out.println JLabel.setText или JOptionPane
Программа ждёт Enter в консоли Программа ждёт клик или событие в окне
Завершение после main Окно живёт, пока пользователь не закроет крестик
Консоль Java Swing Tkinter (Python)
Библиотека в JDK в JDK (javax.swing) в CPython
Главное окно нет JFrame tk.Tk()
Цикл событий нет EDT (поток Swing) mainloop()
Кнопка нет JButton + ActionListener Button + command=

Поток EDT — почему окно «живёт» само

Swing рисует интерфейс в Event Dispatch Thread (EDT). Все создание и изменение кнопок, надписей, размеров окна должны происходить в этом потоке.

flowchart LR
  A[javac + java] --> B[main]
  B --> C[SwingUtilities.invokeLater]
  C --> D[Создать JFrame и виджеты]
  D --> E[setVisible true]
  E --> F{Событие в EDT?}
  F -->|Клик JButton| G[ActionListener]
  F -->|Крестик| H[EXIT_ON_CLOSE]
  G --> F

Пока окно открыто, метод main уже завершился, но процесс Java не заканчивается — работает EDT. Если в обработчике кнопки считать факториал миллиона секунд, окно замрёт — для долгих задач нужен SwingWorker (Особенности разработки десктопных приложений).


Обязательный каркас Swing

Любой пример ниже повторяет этот шаблон.

Разбор построчно:

Строка Смысл
import javax.swing.* Пакет Swing: JFrame, JButton, JLabel, JOptionPane… Звёздочка импортирует часто используемые классы.
public class AppFrame Имя класса = имя файла AppFrame.java.
public static void main Точка входа JVM — как в консоли.
SwingUtilities.invokeLater(() -> { .. }) Запланировать создание UI в EDT. Без этого на части ОС IDE предупреждает о небезопасном доступе к Swing.
() -> { .. } Лямбда — короткая анонимная функция без имени; тело в фигурных скобках.
new JFrame("Моё приложение") Главное окно; строка в заголовке окна.
setDefaultCloseOperation(EXIT_ON_CLOSE) Крестик завершает JVM. Без этого окно исчезнет, а процесс java может остаться в диспетчере задач.
setSize(400, 300) Ширина и высота клиентской области в пикселях.
setLocationRelativeTo(null) Центр экрана. null значит «относительно всего дисплея».
setVisible(true) Показать окно. До этого пользователь ничего не увидит.

Компиляция и запуск:

javac AppFrame.java
java AppFrame
Симптом Причина
Could not find or load main class Запускаете не из той папки или имя класса в java не совпадает с файлом
Окно мелькнуло Нет invokeLater + сразу конец main без EXIT_ON_CLOSE и видимого окна
javac is not recognized JDK не установлен или не в PATH

Стартовые окна

Простые программы «с нуля» — с них. У каждого блока: файл, код, таблица строк, что увидите на экране.


Минимальное окно с меткой

Запрос: java swing hello world, jlabel center.

Задача: доказать, что JDK и Swing работают — одно окно с текстом.

Файл: HelloLabel.java

Разбор построчно:

Строка Смысл
JLabel label = new JLabel(..) Виджет только для текста — пользователь в него не печатает.
"Окно работает!" Строка на экране.
SwingConstants.CENTER Выравнивание текста по центру области метки.
frame.add(label) JFrame по умолчанию использует BorderLayoutadd без зоны кладёт виджет в CENTER (центр окна).

Что увидите: окно ~320×160, по центру надпись «Окно работает!».

Частая ошибка: ожидать, что JLabel сам «появится» без frame.add — виджет должен быть добавлен в контейнер.

Что попробовать: label.setFont(label.getFontderiveFont(18f)) перед frame.add — крупнее шрифт.


Кнопка и диалог JOptionPane

Запрос: jbutton actionlistener lambda, joptionpane example.

Задача: по клику показать всплывающее сообщение — основа калькулятора, форм, меню.

Файл: HelloButton.java

Разбор построчно:

Строка Смысл
JButton btn = new JButton("Нажми меня") Кнопка с подписью на лицевой стороне.
addActionListener(e -> ..) Подписка на событие «нажали». e — объект события (ActionEvent), здесь не используется.
e -> JOptionPane.. Лямбда: при клике выполнить тело один раз.
JOptionPane.showMessageDialog(frame, ..) Модальное окно поверх frame; пока не нажали OK, фокус не уйдёт.
INFORMATION_MESSAGE Иконка «i» в диалоге (стиль зависит от ОС).

Сравнение с Tkinter: там command=on_click без скобок. В Java в addActionListener передают функцию e -> .., а не результат вызова.

Что попробовать: JOptionPane.showConfirmDialog — возвращает YES_OPTION / NO_OPTION, можно ветвить if.


Поле ввода и приветствие

Запрос: jtextfield example, java gui get user input.

Задача: прочитать имя из поля, проверить пустоту, показать диалог.

Файл: HelloForm.java

Разбор построчно:

Строка Смысл
JPanel panel = new JPanel(new GridLayout(2, 2, 8, 8)) Панель-контейнер; сетка 2 строки × 2 столбца, отступ между ячейками 8 px.
BorderFactory.createEmptyBorder(16, 16, 16, 16) Внутренний отступ панели от края окна (верх, лево, низ, право).
new JTextField(16) Однострочное поле; 16 — «примерная ширина в символах».
getTexttrim() Взять строку из поля и убрать пробелы по краям.
name.isEmpty() Проверка «пользователь ничего не ввёл».
greetBtn.doClick() Программно «нажать» кнопку — срабатывает тот же ActionListener.
nameField.addActionListener(e -> greetBtn.doClick()) Клавиша Enter в поле = тот же код, что у кнопки.
frame.pack() Подогнать размер окна под содержимое после GridLayout.

Что увидите: компактная форма; пустое имя → жёлтое предупреждение; иначе приветствие.

Что попробовать: второе поле «Фамилия» — расширьте GridLayout до 3 строк.


Конвертер °C → °F

Запрос: java gui temperature converter, parse double jtextfield.

Задача: классическая лабораторная — число, формула, результат в интерфейсе.

Файл: TempConverter.java

Разбор построчно:

Строка Смысл
replace(',', '.') В русской локали часто печатают 25,5 — для parseDouble нужна точка.
Double.parseDouble(raw) Строка → число; при буквах бросает NumberFormatException.
celsius * 9 / 5 + 32 Формула Фаренгейта.
resultLabel.setText(..) Обновить надпись без пересоздания виджета.
Runnable convert = () -> { .. } Именованный блок логики; кнопка и Enter вызывают convert.run().

Вход / выход (пример):

Ввод в поле На экране в resultLabel
0 0,0 °C = 32,0 °F
100 100,0 °C = 212,0 °F
abc Диалог «Введите число…»

Что попробовать: кнопка «Очистить» — celsiusField.setText("") и resultLabel.setText("—").


Флажок и переключатели

Запрос: jcheckbox jradiobutton, ButtonGroup swing.

Файл: SettingsPanel.java

Разбор построчно:

Строка Смысл
JCheckBox(.., true) Второй аргумент — начальное состояние «включено».
JRadioButton + ButtonGroup В группе только одна кнопка может быть выбрана.
isSelected() true, если галочка / радио активны.
BoxLayout.Y_AXIS Виджеты столбиком сверху вниз.
Box.createVerticalStrut(12) Пустой промежуток 12 px между блоками.
updateStatus.run() при старте Сразу показать строку статуса, не ждать первого клика.

Список задач (JList)

Запрос: jlist add item java, java todo list swing.

Файл: TodoList.java

Разбор построчно:

Строка Смысл
DefaultListModel<String> Модель данных списка — сюда добавляют и удаляют строки.
JList<>(model) Виджет отображает то, что в модели.
model.addElement(text) Строка в конец списка.
list.getSelectedIndex() Индекс выделенной строки или −1, если ничего не выбрано.
model.remove(idx) Удалить по индексу.
new JScrollPane(list) Полосы прокрутки, если задач больше, чем помещается.
BorderLayout.NORTH / CENTER Поле сверху, список занимает остаток окна.

Мини-проект для отчёта: этот файл + скриншот окна = готовая «программа учёта задач».


Ползунок громкости

Запрос: jslider changelistener, java swing slider example.

Файл: VolumeSlider.java

Разбор построчно:

Строка Смысл
new JSlider(0, 100, 50) Минимум 0, максимум 100, старт 50.
setMajorTickSpacing(25) Деления на шкале каждые 25 единиц.
ChangeListener Срабатывает при каждом движении ползунка (не только по клику).
getValueIsAdjusting() Пока пользователь тянет мышью — true; можно не обновлять текст на каждом пикселе.
slider.getValue() Текущее число на шкале.

Примеры окон и компонентов

Тематические блоки для курсовой: компоновка, текст, меню, диалоги, мини-приложения.


Форма входа (GridLayout + пароль)

Запрос: jpasswordfield example, java login form swing.

Файл: LoginGrid.java — см. код в справочнике 3112; ниже полная программа.

Разбор:

Элемент Смысл
JPasswordField Символы скрыты точками; getPassword() возвращает char[], не String
Пустая JLabel в сетке Заглушка, чтобы кнопка «Войти» встала во второй столбец третьей строки

Меню и строка состояния

Запрос: jmenubar jmenuitem example.

Файл: MenuDemo.java

Разбор: setJMenuBar — полоса «Файл / Справка»; addSeparator() — линия между пунктами; BorderLayout.SOUTH — статус внизу, как в блокноте.


Простой калькулятор (+ и −)

Запрос: java swing calculator code, gridbaglayout example.

Файл: MiniCalc.java — два поля, кнопки «+» и «−», результат в JLabel.

Разбор: GridBagLayout — гибкая таблица (сложнее GridLayout, зато ячейки разного размера). calc.run("+") — одна функция на две кнопки.


Счётчик (кнопка меняет JLabel)

Классика из Простые приложения на Java — здесь с таблицей строк.

Файл: CounterApp.java

Разбор построчно:

Строка Смысл
int[] counter = {0} Массив из одного элемента — обход правила «переменная в лямбде должна быть effectively final».
counter[0]++ Увеличить значение при каждом клике.
label.setText(..) Обновление UI в EDT — здесь это безопасно, обработчик кнопки уже в EDT.

В курсовой чаще делают поле класса private int counter = 0; — тот же смысл, чище для ООП.


Типовые задачи

Короткие фрагменты, которые часто вставляют в готовую лабораторную.

Только JFrame по центру экрана

JFrame f = new JFrame("Заголовок");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(500, 400);
f.setLocationRelativeTo(null);
f.setVisible(true);

Текст кнопки и отключение кнопки

JButton b = new JButton("Старт");
b.setText("Стоп");
b.setEnabled(false);

Диалог «Да / Нет»

int ans = JOptionPane.showConfirmDialog(frame, "Удалить запись?", "Подтверждение", JOptionPane.YES_NO_OPTION);
if (ans == JOptionPane.YES_OPTION) { /* удалить */ }

Добавить элемент в JComboBox

JComboBox<String> combo = new JComboBox<>(new String[]{"A", "B"});
combo.addItem("C");
String x = (String) combo.getSelectedItem();

JTextArea с прокруткой

JTextArea area = new JTextArea(10, 30);
area.setLineWrap(true);
frame.add(new JScrollPane(area), BorderLayout.CENTER);

Частые ошибки новичка

Симптом Причина Решение
Окно не появляется Нет setVisible(true) Вызвать после add всех виджетов
JVM не завершается Нет EXIT_ON_CLOSE frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
Окно «зависло» Долгий цикл в ActionListener Вынести в фон + SwingUtilities.invokeLater для UI
UI странный из другого потока Обновление не в EDT Обернуть в invokeLater
Could not find main class Неверное имя при java X Имя класса = имя файла без .java
Пустое окно Всё ушло в NORTH, CENTER пуст Проверить зоны BorderLayout
Кнопка «сработала» при старте Вызвали метод вместо лямбды addActionListener(e -> fn()), не addActionListener(fn()) если fn уже вызывается
parseDouble падает Запятая или буквы replace(',', '.') и try/catch
IntelliJ IDEA
File → New → Project → Java, класс с main, зелёная стрелка Run. Если JDK не подхватился — File → Project Structure → SDK. Ошибки компиляции смотрите во вкладке Build.

Мини-проект: форма входа за один проход

Соберите одно окно «Учёт задач»:

  1. TodoList — список с добавлением и удалением (раздел).
  2. Меню Файл → Выход (MenuDemo).
  3. Строка состояния «Задач: N» — в addBtn после addElement обновляйте statusLabel.
  4. При закрытии крестика — showConfirmDialog (подтверждение выхода).

Скриншот окна + листинг = готовый отчёт по лабораторной «GUI на Java».


Маршрут изучения

Шаг Пример в статье Дальше
1 Каркас Первая программа
2 Метка + кнопка Поле ввода
3 Конвертер Список задач
4 Меню, диалоги Справочник UI
5 Калькулятор JavaFX для новых проектов

Куда дальше