Для Swing существует несколько коммерческих и бесплатных библиотек LookAndFeel. Использование LAF позволяет менять внешний вид приложений и добавлять поддержку тем оформления практически без кодирования.
Одной из наиболее качественных LAF-библиотек является Substance. Она включает в себя хорошо прорисованные стандартные компоненты и более десятка скинов:

Рассмотрим как можно с помощью Substance добавить в приложение возможность выбора скинов пользователем.
— нужно инициализировать Substance при старте приложения примерно так:
— нужно отключить системную декорацию окон с помощью кода
— нужно разрешить Substance показывать в системном оконном меню список установленных тем:
В результате, в запущенном приложении, пользователь может кликнуть иконку окна и выбрать тему из списка:

Установить скин Substance можно по имени класса темы методом setSkin. Получить имя класса текущей темы можно вызовом SubstanceLookAndFeel.getCurrentSkin().getClass().getCanonicalName(). Остаётся только сохранять эту информацию в файл при завершении приложения.
Для сохранения можно использовать стандартный класс Properties, файл настроек можно разместить в домашней директории пользователя а саму функцию сохранения желательно добавит в hook на shutdown, чтобы она вызывалась автоматически при завершении приложения.
В результате в домашней папке будет сохраняться файл примерно такого вида:

как видно, код минимален и практически не требует изменений в приложении.
Откомпилированный пример с библиотекой Substance и исходный код можно скачать здесь.
Исходный код Substance и всех сопутствующих библиотек можно скачать здесь.
Для чего нужно позволять пользователям выбирать скины самим?
— для повышения лояльности. Обычно людям нравится когда у них есть возможность настроить что-то «под себя»
Должен ли интерфейс выглядеть «нативно»?
— так говорят по инерции. Например, Microsoft Office, в каждой версии собственные темы оформления не совпадающие с системными окнами:

Одной из наиболее качественных LAF-библиотек является Substance. Она включает в себя хорошо прорисованные стандартные компоненты и более десятка скинов:

Рассмотрим как можно с помощью Substance добавить в приложение возможность выбора скинов пользователем.
Подключение Substance
— нужно инициализировать Substance при старте приложения примерно так:
SubstanceLookAndFeel laf = new SubstanceGeminiLookAndFeel(); UIManager.setLookAndFeel(laf);
— нужно отключить системную декорацию окон с помощью кода
JFrame.setDefaultLookAndFeelDecorated(true); JDialog.setDefaultLookAndFeelDecorated(true);
— нужно разрешить Substance показывать в системном оконном меню список установленных тем:
UIManager.put(SubstanceLookAndFeel.SHOW_EXTRA_WIDGETS, Boolean.TRUE);
В результате, в запущенном приложении, пользователь может кликнуть иконку окна и выбрать тему из списка:

Хранение настроек
Установить скин Substance можно по имени класса темы методом setSkin. Получить имя класса текущей темы можно вызовом SubstanceLookAndFeel.getCurrentSkin().getClass().getCanonicalName(). Остаётся только сохранять эту информацию в файл при завершении приложения.
Для сохранения можно использовать стандартный класс Properties, файл настроек можно разместить в домашней директории пользователя а саму функцию сохранения желательно добавит в hook на shutdown, чтобы она вызывалась автоматически при завершении приложения.
В результате в домашней папке будет сохраняться файл примерно такого вида:

Полный код поддержки скинов
package insubstantial; import javax.swing.*; import java.awt.*; import org.pushingpixels.substance.api.*; import org.pushingpixels.substance.api.skin.*; import java.util.*; import java.io.*; public class Insubstantial { public static void setupSubstance() { try { final String fileName = System.getProperty("user.home") + System.getProperty("file.separator") + "insubstantial.txt"; final Properties properties = new Properties(); org.pushingpixels.substance.api.SubstanceLookAndFeel laf = new SubstanceGeminiLookAndFeel(); UIManager.setLookAndFeel(laf); UIManager.put(SubstanceLookAndFeel.SHOW_EXTRA_WIDGETS, Boolean.TRUE); JFrame.setDefaultLookAndFeelDecorated(true); JDialog.setDefaultLookAndFeelDecorated(true); Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { try { String skinClassName = SubstanceLookAndFeel.getCurrentSkin().getClass().getCanonicalName(); properties.setProperty("skinClassName", skinClassName); properties.store(new FileOutputStream(fileName), fileName); } catch (Throwable t) { t.printStackTrace(); } } }); properties.load(new FileInputStream(fileName)); String skinClassName = properties.getProperty("skinClassName"); laf.setSkin(skinClassName); } catch (Throwable t) { t.printStackTrace(); } } public static void main(String[] args) { setupSubstance(); EventQueue.invokeLater(new Runnable() { @Override public void run() { new TestGUI().setVisible(true); } }); } }
как видно, код минимален и практически не требует изменений в приложении.
Откомпилированный пример с библиотекой Substance и исходный код можно скачать здесь.
Исходный код Substance и всех сопутствующих библиотек можно скачать здесь.
Дополнительно
Для чего нужно позволять пользователям выбирать скины самим?
— для повышения лояльности. Обычно людям нравится когда у них есть возможность настроить что-то «под себя»
Должен ли интерфейс выглядеть «нативно»?
— так говорят по инерции. Например, Microsoft Office, в каждой версии собственные темы оформления не совпадающие с системными окнами:

