******** РЕДАКТИРОВАТЬ: 2011-02-19 ***************
Благодаря статье Гертьян я понял, как сделать полную перерисовку в реальном времени.
На самом деле установка пользовательского интерфейса на другой laf, а затем прямо назад фактически перерисовывает весь пользовательский интерфейс, как я хотел ниже.
public static void updateUI() {
try {
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception ex) {}
UIManager.put(nimbusBlueGrey, YOUR_NEW_COLOR);
SwingUtilities.updateComponentTreeUI(jFrame);
}
Странно, но это работает.
************************************
Оригинальная история:
Я только что вернулся из JFokus в Стокгольм и получил отличную встречу с людьми, разделяющими мой интерес к платформе NetBeans. Возможно, мы были единственными людьми в этом стейк-хаусе в тот вечер, обмениваясь советами NetBeans … На этом ужине у меня была возможность показать и обсудить борьбу моего текущего проекта с принятием Nimbus Look & Feel с тем, что наш арт-директор создал в фотошоп .
Дело в том, что мы хотим, чтобы пользователь мог изменять свои настройки в режиме реального времени, поэтому мы хотим изменять свойства чертежа Nimbus в режиме реального времени.
Обычно это можно сделать так:
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()){
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
UIManager.put("nimbusBase", new Color(21, 21, 21));
UIManager.put("nimbusBlueGrey", new Color(44, 44, 44));
UIManager.put("control", new Color(40, 40, 40));
UIManager.put("textText", Color.WHITE);
jFrame = (JFrame) WindowManager.getDefault().getMainWindow();
SwingUtilities.updateComponentTreeUI(jFrame);
break;
}
}
В моем текущем проекте я выполняю код, аналогичный описанному выше, в моем классе «ModuleInstall», например:
public void restored() {
WindowManager.getDefault().invokeWhenUIReady(new GuiInitialiser());
}
Код выше — это то, что делается в «GuiInitialiser».
Однако, и это моя главная проблема сейчас, этот код ведет себя совершенно по-другому, когда я, вместо программной установки LAF, как указано выше, устанавливаю его, добавляя:
run.args.extra=--laf com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel
… в файле «platform.properties» моего проекта.
Похоже, проблема связана с выполнением полной и чистой перерисовки всего пользовательского интерфейса проекта при его программной настройке.
Чтобы проиллюстрировать это, я создал небольшой проект, который иллюстрирует то, о чем я говорю. Если вы запустите его, вы увидите, что главная строка меню в верхней части экрана выглядит ужасно:
Это потому что я поставил
UIManager.put("nimbusBase", Color.MAGENTA);
UIManager.put("nimbusBlueGrey", Color.CYAN);
… перед обновлением интерфейса в первый раз. Однако изменение тех же свойств после этого не перерисовывает эту часть пользовательского интерфейса.
В этой программе есть несколько предопределенных настроек, которые вы можете попробовать, а также текстовое поле, в котором вы можете попытаться изменить цвет любого другого свойства Nimbus, которое вам может понравиться. Однако из-за логики Nimbus производных цветов (которая, кстати, довольно хорошо проиллюстрирована в вышеприведенном приложении — установите «nimbusBase» на красный и посмотрите, как красный реализован, например, в comboBox), довольно трудно найти свойство цвета, которое мгновенно делает то, что вы хотите / ожидаете.
Так что, если вы заинтересованы в этом, вы можете скачать проект и поиграть с ним. Я надеюсь, что и приложение, и его источник могут кому-то помочь. Очевидно, что это приложение должно было быть представлено с включенным веб-запуском Java, но оно отображалось даже по-другому, о чем кто-то также должен был бы свободно сообщить мне …
Так что, если вам это нравится, загрузите его и поэкспериментируйте. Запустите его «как есть» или с настройкой LAF в файле «platform.properties». Запустите его как JNLP.