Перейти к основному содержимому

Практикум Swing — XML-валидатор

Разработчику Начальный уровень

О практикуме

Соберём десктопное приложение "XML Validator" на Swing и Maven — два редактора (XML и XSD), кнопка "Проверить", панель результата с номерами строк и столбцов ошибок. Пользователь может выбрать файлы через диалог или вставить текст прямо в окно — типичный сценарий утилиты поддержки, когда нужно быстро проверить фрагмент конфигурации или целый документ.

Стек проекта:

  • Maven JAR — стандартная структура Java-проекта (структура и сборки);
  • Swing (javax.swing) — окно, панели, кнопки, JTextArea, JFileChooser (обзор GUI, рецепты элементов);
  • javax.xml.validation — валидация XML по XSD из JDK, без сторонних библиотек (общая база по разметке — XML);
  • SwingWorker — проверка в фоне, чтобы UI не "замирал" (EDT и потоки).
Swing в 2026 — зачем этот практикум

Для новых desktop-проектов чаще берут JavaFX, но Swing остаётся в JDK, встречается в legacy-утилитах и internal tools. Здесь — полноценный Maven-проект с разделением model / service / ui, фоновой задачей и работой с XML. Те же идеи переносятся на JavaFX: Task вместо SwingWorker, Platform.runLater вместо SwingUtilities.invokeLater — см. Swing и потоки.

Well-formed и valid — два уровня проверки XML

Прежде чем писать код, разделим два понятия из раздела про XML:

УровеньВопросКто отвечает
Well-formedДокумент синтаксически корректен? (закрытые теги, одна корневая нода)SAX-парсер
ValidДокумент соответствует схеме (XSD)?Validator из javax.xml.validation

Наш валидатор проверяет valid относительно загруженной XSD. Если XML вообще не парсится, SAX вернёт fatal-ошибку — мы покажем её так же, как ошибку схемы.

XML Schema (XSD) — язык описания структуры — имена элементов, типы полей, обязательные атрибуты, кардинальность (maxOccurs="unbounded"). Валидатор компилирует XSD в объект Schema, создаёт Validator и прогоняет через него XML. При нарушении правил вызывается ErrorHandler с номером строки и столбца — именно эти координаты мы выводим пользователю.

Архитектура приложения

В нашем приложении три слоя — упрощённый layered architecture, близкий к MVC:

СлойРольКлассыЗависит от
ModelРезультат проверки, без UIValidationResultтолько JDK
ServiceЛогика XSD-валидацииXsdValidatorServicemodel, javax.xml.*
UI (View + Controller)Окно, ввод, реакция на кнопкиXmlValidatorFrame, FilePanel, ResultPanelmodel, service, Swing

Точка входа — XmlValidatorApp.main, как в первой программе и точке входа JVM. UI не импортирует SAX напрямую — frame вызывает сервис, сервис возвращает ValidationResult, панель результата только отображает данные. Так проще тестировать сервис без Swing и позже заменить UI на JavaFX, не трогая валидацию.

Пользователь → FilePanel / кнопки → XmlValidatorFrame

▼ (SwingWorker, фон)
XsdValidatorService


ValidationResult → ResultPanel

Ключевые термины

  • Swing — графическая библиотека JDK (javax.swing); рисует "лёгкие" компоненты на Java, не зависит от нативных виджетов ОС. Обзор — JavaFX и GUI, экосистема Java.
  • EDT (Event Dispatch Thread) — единственный поток, где безопасно создавать и менять Swing-компоненты. Старт UI — через SwingUtilities.invokeLater. Подробнее — Особенности разработки десктопных приложений.
  • SwingWorker — шаблон "долгая работа в фоне → результат в EDT"; doInBackground() не трогает UI, done() обновляет виджеты.
  • JFrame — главное окно приложения; содержит contentPane с layout-менеджерами.
  • SchemaFactory / Validator — API javax.xml.validation: фабрика компилирует XSD, валидатор проверяет XML.
  • ErrorHandler (SAX) — интерфейс обратных вызовов warning, error, fatalError с координатами SAXParseException.
  • JFileChooser — диалог выбора файла; фильтр расширений — FileNameExtensionFilter (Справочник по JavaFX и Swing — элементы UI — JFileChooser).
  • JSplitPane — разделитель между областями; пользователь тянет границу мышью.
  • Look-and-Feel (L&F) — тема оформления Swing (Metal, Nimbus, System); задаётся через UIManager.setLookAndFeel.

Почему именно этот проект

  • охватывает сценарий форма + фоновая операция + structured errors — основа многих desktop-утилит;
  • Swing без внешних GUI-зависимостей — только JDK;
  • сочетает I/O файлов (Ввод-вывод и файлы в Java) и XML API стандартной библиотеки;
  • показывает разделение слоёв — навык из культуры кода;
  • компактен для одного вечера (2–3 часа), но близок к реальным internal tools;
  • после прохождения проще читать JavaFX и GUI и Lab — Swing.

Предварительные знания:

Готовый проект для сверки: F:\Projects\JVM\Java\JavaXMLValidator.

Что получится

Действие пользователяКомпонент SwingЧто происходит
"Обзор…" для XML/XSDJFileChooser, JTextAreaФайл читается в редактор
Вставить текст вручнуюJTextAreaВалидация по строкам, без файла на диске
"Проверить"JButton, SwingWorkerXSD проверяет XML, результат внизу
"Очистить"JButtonСброс полей и статуса
Невалидный XMLResultPanelСписок ошибок с [error], строка, столбец
Enter в формеgetRootPane().setDefaultButtonТот же сценарий, что и клик "Проверить"

Карта этапов

ЭтапФокусРезультат
0Каркас MavenПустая структура каталогов
1pom.xmlJAR, mainClass, shade
2ValidationResultМодель результата
3XsdValidatorServiceВалидация по файлу и строкам
4FilePanelРедактор + выбор файла
5ResultPanelСтатус и список ошибок
6XmlValidatorFrameКомпоновка, SwingWorker
7XmlValidatorAppТочка входа, Look-and-Feel
8Примеры XML/XSDТестовые данные в examples/
9Запуск и проверкаmvn package, GUI, сценарии

После каждого этапа имеет смысл mvn -q compile — привычка из разработки и отладки: маленькие шаги, частая проверка.


Этап 0 — каркас проекта

Цель этапа — создать стандартную структуру JAR-проекта Maven и разложить пакеты по слоям.

Desktop vs web — другая точка входа

В отличие от JSF (практикум "Список задач"), desktop-приложение начинается с public static void main. JVM загружает класс XmlValidatorApp, вызывает main, тот делегирует создание окна методу XmlValidatorFrame.launch(). Контейнер servlet'ов не нужен — процесс живёт, пока открыто окно (или пока не завершатся не-daemon потоки). См. точку входа JVM и архитектуру десктопа.

Maven для таких проектов использует packaging jar и каталог src/main/java — подробно в Структура и сборки Java-проектов.

Создание каталогов

Корневая папка:

mkdir java-xml-validator && cd java-xml-validator

Windows PowerShell:

New-Item -ItemType Directory -Force -Path `
src/main/java/com/xmlvalidator/model, `
src/main/java/com/xmlvalidator/service, `
src/main/java/com/xmlvalidator/ui, `
src/test/java/com/xmlvalidator/service, `
examples

Итоговая схема:

java-xml-validator/
├── pom.xml
├── examples/
│ ├── book.xsd
│ ├── book-valid.xml
│ └── book-invalid.xml
└── src/
├── main/java/com/xmlvalidator/
│ ├── XmlValidatorApp.java
│ ├── model/ValidationResult.java
│ ├── service/XsdValidatorService.java
│ └── ui/
│ ├── XmlValidatorFrame.java
│ ├── FilePanel.java
│ └── ResultPanel.java
└── test/java/com/xmlvalidator/service/
└── XsdValidatorServiceTest.java

Разбор структуры

  • src/main/java — компилируемый код; путь папок = имя пакета (com.xmlvalidator.service).
  • model — plain Java, без Swing и без javax.xml; удобно покрыть unit-тестами.
  • service — доменная логика валидации; UI только вызывает validate(...).
  • ui — только Swing; классы FilePanel и ResultPanel package-private — детали реализации, наружу торчит XmlValidatorFrame.launch().
  • examples — образцы для ручной проверки и тестов; не в classpath, путь относительно корня проекта при mvn test.
  • src/test/java — зеркало production-пакетов; тестируем сервис без поднятия GUI.

Этап 1 — pom.xml

Цель этапа — описать координаты артефакта, Java 17, JUnit для тестов и исполняемый JAR.

Зависимости и JDK-модули

Swing (javax.swing, java.awt) и XML Validation (javax.xml.validation, org.xml.sax) входят в JDK — в <dependencies> для runtime ничего не кладём. Это отличие от JavaFX, где OpenJFX подключают отдельно.

Единственная зависимость — JUnit 5 со scope test: GUI мы проверяем вручную, сервис — автоматически.

Плагин maven-shade-plugin соберёт "fat JAR" — один файл со всеми классами и манифестом Main-Class, удобно передать коллеге без IDE.

Создайте pom.xml в корне:

Код ITЗагрузка примера кода…

Разбор pom.xml

ЭлементНазначение
groupId / artifactId / versionКоординаты артефакта в Maven-репозитории
project.build.sourceEncoding UTF-8Кириллица в строках и XML без "кракозябр"
maven.compiler.release 17Язык и API JDK 17; в модели используем record
maven-jar-plugin + mainClassТонкий JAR: java -jar target/java-xml-validator-1.0.0.jar
maven-shade-pluginFat JAR после mvn package — один файл для раздачи
maven-surefire-pluginЗапуск JUnit 5 на фазе test
JUnit 5 (scope test)Только тесты; не попадает в production JAR

Проверка синтаксиса POM:

mvn -q validate

Если Maven не находит артефакты — проверьте интернет и настройки репозитория (первая программа на Java).


Этап 2 — модель ValidationResult

Цель этапа — описать результат валидации в типах Java — успех, список ошибок с координатами, краткий summary для заголовка панели.

Зачем отдельная model, а не boolean

UI мог бы интерпретировать true/false, но реальным пользователям нужны детали — сколько ошибок, на какой строке, warning или error. Модель инкапсулирует три случая:

  • документ валиден;
  • документ не валиден, список ValidationError;
  • ошибка конфигурации (пустой ввод, битая XSD, файл не найден) — не путать с нарушением схемы в XML.

Файл src/main/java/com/xmlvalidator/model/ValidationResult.java:

Код ITЗагрузка примера кода…

Построчный разбор

ФрагментСмысл
public final classКласс не наследуют; явный value-object для результата
Приватный конструктор + фабрики success / failure / configurationErrorЕдиные точки создания; снаружи нельзя собрать неконсистентное состояние
List.copyOf(errors)Иммутабельная копия — UI не испортит список после получения
record ValidationErrorКомпактный DTO (современный синтаксис); поля Integer, а не int, чтобы отличать "нет координаты" от нуля
formatted()Presentation-логика для JTextArea; сервис не знает про Swing
Вложенный BuilderSAX вызывает ErrorHandler многократно; накапливаем ошибки, в конце build()

На этом этапе:

mvn -q compile

Этап 3 — сервис XsdValidatorService

Цель этапа — реализовать валидацию по путям файлов и по строкам из редакторов, скрыв детали SAX/XML API от UI.

Цепочка API javax.xml.validation

Типичный pipeline (см. также JAXP в документации JDK):

  1. SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI) — фабрика для XSD 1.0.
  2. factory.newSchema(xsdSource) — компиляция XSD; синтаксическая ошибка в схеме → SAXException здесь.
  3. schema.newValidator() — экземпляр валидатора для этой схемы.
  4. validator.setErrorHandler(...) — куда стекаются warning/error/fatal.
  5. validator.validate(xmlSource) — один проход по XML.

Источники — javax.xml.transform.Source; для файлов удобен StreamSource, для строк из редактора — ByteArrayInputStream + UTF-8.

Два публичных метода validate

МетодКогда используется
validate(Path xml, Path xsd)Текст в редакторе совпадает с файлом на диске — читаем напрямую с systemId = URI файла
validate(String xml, String xsd)Пользователь редактировал текст или не выбирал файл

Frame (этап 6) решает, какой overload вызвать, сравнивая textArea.getText() с Files.readString(path).

Файл src/main/java/com/xmlvalidator/service/XsdValidatorService.java:

Код ITЗагрузка примера кода…

Разбор сервиса

Проверки на входе (Path)

  • Files.isRegularFile — отсекаем каталоги и несуществующие пути до SAX; возвращаем configurationError с понятным текстом для UI.

setSystemId

  • Для файла — URI файла; для inline — псевдо-имя inline.xml. Без systemId сообщения SAX иногда бесполезны ("unknown location").

ACCESS_EXTERNAL_DTD / ACCESS_EXTERNAL_SCHEMA

  • Начиная с JDK 8+ ужесточили загрузку внешних сущностей (XXE). Пустая строка запрещает DTD из сети; "file" для schema — разумный компромисс для локальных XSD.

CollectingErrorHandler

  • warning — замечание, валидация может продолжиться;
  • error — нарушение схемы;
  • fatalError — записываем и пробрасываем SAXException (контракт SAX); дублирующий catch для SAXParseException в validate подстраховывает обрыв с одной fatal-ошибкой.

Pattern matching instanceof SAXParseException parseEx

Проверка:

mvn -q compile

Этап 4 — панель FilePanel

Цель этапа — переиспользуемый блок — путь к файлу, кнопка "Обзор…", моноширинный редактор текста.

Компоненты Swing в этой панели

КлассРоль в UI
JPanelКонтейнер с BorderLayout
JTextFieldRead-only путь к выбранному файлу
JButtonОткрывает JFileChooser
JTextAreaМногострочный редактор XML/XSD
JScrollPaneПрокрутка длинного текста
JLabelПодсказка пользователю

Один класс FilePanel параметризуется заголовком и расширением — DRY: две панели (XML и XSD) без копипасты. Подробнее про виджеты — Справочник по JavaFX и Swing — элементы UI — Swing.

Файл src/main/java/com/xmlvalidator/ui/FilePanel.java:

Код ITЗагрузка примера кода…

Разбор компоновки и поведения

Layout

Шрифт и перенос

  • Font.MONOSPACED — выравнивание вложенных тегов; setTabSize(2) — два пробела на уровень отступа.
  • setLineWrap(false) — XML обычно не переносят по словам; горизонтальная прокрутка через JScrollPane.

chooseFile()

  • showOpenDialog(this) — модальный диалог относительно панели.
  • FileNameExtensionFilter — в списке только .xml или .xsd.
  • Files.readString — Java 11+, UTF-8 по умолчанию (Ввод-вывод и файлы в Java).
  • Ошибки чтения — JOptionPane с ERROR_MESSAGE, не silent fail.

Инкапсуляция

  • final class, package-private — снаружи пакета ui виден только frame; методы getText / clear без модификатора — API для XmlValidatorFrame.

Этап 5 — панель ResultPanel

Цель этапа — показать статус (цвет + краткий текст) и детали ошибок в читаемом виде.

Машина состояний UI

Панель результата проходит четыре состояния:

СостояниеМетодЧто видит пользователь
Готовreset()Серый текст "Готов к проверке", пустая область деталей
Идёт проверкаshowPending()"Проверка…", кнопки disabled (управляет frame)
РезультатshowResult(ValidationResult)✓ зелёный или ✗ красный + список ошибок
Сбой workershowError(String)✗ "Ошибка" + текст исключения

Такой паттерн описан в Особенности разработки десктопных приложений для любых long-running операций в desktop.

Файл src/main/java/com/xmlvalidator/ui/ResultPanel.java:

Код ITЗагрузка примера кода…

Разбор

  • JLabel + JTextArea — заголовок статуса крупнее (deriveFont(BOLD, 14f)), детали — моноширинный многострочный блок.
  • setEditable(false) — область только для чтения; пользователь копирует текст ошибки в буфер.
  • setLineWrap(true) в details — длинные сообщения SAX переносятся; в редакторах XML wrap выключен намеренно.
  • Нумерация 1. 2. 3. — удобно ссылаться при разборе с коллегой ("смотри ошибку 2").
  • setCaretPosition(0) — после обновления прокрутка в начало, а не в конец.

Этап 6 — главное окно XmlValidatorFrame

Цель этапа — собрать layout, обработчики кнопок и SwingWorker для валидации без блокировки EDT.

Иерархия компонентов окна

JFrame "XML Validator — проверка по XSD"
└── content (BorderLayout)
├── CENTER: JSplitPane (VERTICAL)
│ ├── TOP: JPanel GridLayout(1,2)
│ │ ├── FilePanel "XML-документ"
│ │ └── FilePanel "XSD-схема"
│ └── BOTTOM: ResultPanel
└── SOUTH: JPanel FlowLayout — [Очистить] [Проверить]

Layout-менеджеры (теория — JavaFX и GUI — геометрия Swing):

  • BorderLayout — якорные зоны frame;
  • GridLayout(1, 2) — два редактора одинаковой ширины;
  • JSplitPane.VERTICAL_SPLIT — пользователь меняет долю места редакторам и результату;
  • FlowLayout(RIGHT) — кнопки прижаты к правому краю, порядок "Очистить" → "Проверить".

Почему SwingWorker, а не голый Thread

Валидация большого XML может занять секунды. Если вызвать validator.validate прямо в ActionListener, EDT занят — окно не перерисовывается, курсор "часики", пользователь думает, что приложение зависло.

SwingWorker:

  1. doInBackground() — worker-поток; здесь только сервис и чтение текста.
  2. done() — снова EDT; включаем кнопки, вызываем resultPanel.showResult(get()).

Аналог в JavaFX — Task + Platform.runLater (Первая программа на JavaFX).

Файл src/main/java/com/xmlvalidator/ui/XmlValidatorFrame.java:

Код ITЗагрузка примера кода…

Разбор ключевых решений

РешениеПояснение
EXIT_ON_CLOSEJVM завершится при закрытии окна — иначе процесс может висеть (JavaFX и GUI — типичные ошибки)
setMinimumSize(960, 640)Два редактора + результат не сжимаются в нечитаемую полоску
setLocationRelativeTo(null)Окно по центру экрана при первом показе
resizeWeight(0.72)При ресайзе окна ~72% высоты split — редакторам
continuousLayout(true)Панели перерисовываются во время перетаскивания разделителя
Сравнение текста с файломЕсли пользователь правил текст после "Обзор…", валидируем строки, а не устаревший файл на диске
setDefaultButton(validateButton)Enter в форме = "Проверить"
setMnemonic Alt+V / Alt+CКлавиатурная доступность
Nimbus → System L&FЕдиный современный вид; если Nimbus нет — native (Справочник по конфигурациям в Java — swing.defaultlaf)
Не блокируйте EDT

Вызов validator.validate(...) напрямую в ActionListener на больших файлах "подвесит" окно. Всегда выносите тяжёлую работу в SwingWorker или фоновый поток + SwingUtilities.invokeLater — см. Swing и потоки и 112.md.

Замечание про потоки и UI: в doInBackground() мы читаем getText() из Swing-компонентов. Формально Swing не потокобезопасен; здесь worker стартует сразу после клика, до параллельного редактирования — для учебного проекта достаточно. В production надёжнее снимать snapshot строк в EDT перед worker.execute() и передавать их в worker через constructor — см. JVM и потоки.


Этап 7 — точка входа XmlValidatorApp

Цель этапа — минимальный main, делегирующий запуск окну; отделить bootstrap от UI-кода.

Роль класса с main

ОбязанностьГде живёт
Точка входа JVMXmlValidatorApp.main
EDT + L&F + setVisibleXmlValidatorFrame.launch()
Разметка и событияконструктор XmlValidatorFrame

Так Maven shade-plugin, IDE Run Configuration и документация ссылаются на одно имя класса — com.xmlvalidator.XmlValidatorApp.

Файл src/main/java/com/xmlvalidator/XmlValidatorApp.java:

package com.xmlvalidator;

import com.xmlvalidator.ui.XmlValidatorFrame;

public final class XmlValidatorApp {

public static void main(String[] args) {
XmlValidatorFrame.launch();
}
}

Почему не main прямо во frame

  • JFrame не обязан знать про main — проще тестировать и переиспользовать frame из другого launcher'а.
  • launch() вызывают до любого Swing-кода — сначала L&F, потом invokeLater.
  • Соответствует рекомендациям по структуре — тонкий entry point.

Запуск:

  • IDE — Run на XmlValidatorApp (отладка);
  • Maven (если добавите exec-maven-plugin):
mvn -q exec:java -Dexec.mainClass=com.xmlvalidator.XmlValidatorApp

В эталонном проекте достаточно Run в IDEA или java -jar после package.


Этап 8 — примеры XML и XSD

Цель этапа — добавить файлы для ручной проверки, разбора схемы и unit-тестов.

Схема book.xsd

Описывает каталог книг: корень library, внутри ноль или больше book. У каждой книги обязательны title, author, year (положительное целое) и атрибут isbn.

Код ITЗагрузка примера кода…

Разбор XSD

  • xmlns:xs="http://www.w3.org/2001/XMLSchema" — префикс xs: для встроенных типов (string, positiveInteger).
  • complexType + sequence — дочерние элементы в фиксированном порядке.
  • maxOccurs="unbounded" — список книг любой длины.
  • use="required" на атрибуте — без isbn элемент book invalid.

Валидный документ book-valid.xml

<?xml version="1.0" encoding="UTF-8"?>
<library>
<book isbn="978-0-123456-78-9">
<title>Java XML Processing</title>
<author>Jane Doe</author>
<year>2024</year>
</book>
</library>

Все элементы на месте, year > 0, атрибут isbn задан — ожидаем ✓ в UI.

Невалидный документ book-invalid.xml

<?xml version="1.0" encoding="UTF-8"?>
<library>
<book>
<title>Missing ISBN and bad year</title>
<author>John Smith</author>
<year>-1</year>
</book>
</library>

Две ошибки схемы

  • нет обязательного атрибута isbn;
  • -1 не укладывается в xs:positiveInteger.

Валидатор может вернуть несколько записей в ValidationResult — проверьте нумерацию в ResultPanel.

Unit-тест сервиса

GUI не гоняем в JUnit — тестируем сервис (Артефакты качества в проекте — тестирование). Три сценария — valid file, invalid file, inline strings (text blocks Java 15+).

Файл src/test/java/com/xmlvalidator/service/XsdValidatorServiceTest.java:

Код ITЗагрузка примера кода…

Разбор тестов

  • examplesDir = Path.of("examples").toAbsolutePath() — работает, если mvn test запускают из корня проекта (рабочая директория Maven = каталог с pom.xml).
  • @BeforeEach — новый сервис на каждый тест, без shared state.
  • Третий тест — минимальная XSD "корень = строка"; проверяет overload validate(String, String) без файлов.
mvn -q test

Этап 9 — сборка, запуск и проверка

Цель этапа — убедиться, что JAR собирается и все пользовательские сценарии в GUI работают.

mvn clean package
java -jar target/java-xml-validator-1.0.0.jar

После package в target/ появятся и обычный JAR, и shaded (fat) — оба с Main-Class в манифесте.

Чек-лист ручного тестирования

  1. Окно открывается 960×640, заголовок "XML Validator — проверка по XSD".
  2. "Обзор…" для XML и XSD — загружаются book-valid.xml и book.xsd → "Проверить" → зелёный ✓.
  3. Заменить XML на содержимое book-invalid.xml (вставкой или вторым файлом) → "Проверить" → список ошибок с номерами строк.
  4. "Очистить" — поля и статус "Готов к проверке".
  5. Вставить минимальный XML/XSD без выбора файла → проверка по строкам работает.
  6. Пустой XML → сообщение "XML не может быть пустым" (configurationError, не SAX).
  7. Во время проверки кнопки неактивны, статус "Проверка…" — UI отзывчив (можно двигать разделитель split).
  8. Alt+V / Enter — запуск проверки (mnemonic и default button).
Отладка в IDE

Импортируйте Maven-проект в IntelliJ IDEA. Полезные breakpoint'ы: XsdValidatorService.validate (логика XSD), CollectingErrorHandler.add (каждая SAX-ошибка), SwingWorker.done (граница фон / UI). Общие приёмы — Отладка Java-кода в IDE.

Схема потока данных

[XmlValidatorApp.main]


XmlValidatorFrame.launch() ──► EDT + Nimbus L&F


Пользователь: XML + XSD (файл или текст)


SwingWorker.doInBackground()


XsdValidatorService.validate(...)

├── SchemaFactory.newSchema(XSD)
├── Validator.validate(XML)
└── ErrorHandler → ValidationResult.Builder


SwingWorker.done() → ResultPanel.showResult()

Что вы освоили за практикум


Частые ошибки

СимптомВероятная причинаЧто проверить
Окно не появляетсяUI создан не в EDTSwingUtilities.invokeLater в launch()
UI "замирает" при проверкеВалидация в ActionListenerПеренести в SwingWorker
UnsupportedOperationException на L&FNimbus недоступенFallback на system L&F уже в коде
Тесты не находят examples/Запуск не из корня проектаmvn test из каталога с pom.xml
Кракозябры в XMLНе UTF-8Кодировка файлов и project.build.sourceEncoding
Пустой список ошибок при невалидном XMLПустая XSD или не та схемаСодержимое панели XSD
JVM не завершается после закрытияНе EXIT_ON_CLOSEsetDefaultCloseOperation в конструкторе frame
"Ошибка схемы" при валидном XMLXSD syntactically brokenОткройте XSD отдельно, проверьте well-formed
Разные результаты file vs pasteТекст в редакторе ≠ файлЛогика сравнения в runValidation()

Куда развивать дальше

  1. Меню "Файл" — открыть/сохранить XML, недавние файлы (Справочник по JavaFX и Swing — элементы UI — JMenuBar).
  2. Подсветка строки с ошибкойHighlighter / DefaultHighlighter в JTextArea XML-панели.
  3. Snapshot текста в EDT — передавать строки в SwingWorker через constructor (потокобезопасность).
  4. DTD и Relax NG — другие grammar / сторонние библиотеки; XSD остаётся стандартом для конфигов (XML — обзор).
  5. Drag-and-dropTransferHandler для .xml / .xsd на панели.
  6. JavaFX-версия — те же model/service, UI на TextArea + Task (Первая программа на JavaFX).
  7. CImvn test в pipeline (Gradle — практический старт).

Связанные статьи


Десктоп на JavaJavaFX и GUI, Первая программа на JavaFX, Практикум Swing — XML-валидатор, Lab — Swing, Архитектура десктопа.

Содержание