Как заставить / заставить использовать GTKLookAndFeel в Java на KDE?
Прежде всего, использование gnome не вариант (но есть возможность установить его библиотеки).
Мне нужно знать, что необходимо для отображения настольного приложения Java Swing, используя текущий установленный внешний вид KDE. В идеале решение должно позволить мне применить внешний вид, который выглядит как базовая оконная система (то есть: Windows LNF для Windows, GTK LNF для Gnome(GTK), QT LNF для KDE (QT), по умолчанию для других платформ.).
Под KDE вы можете настроить его на использование текущей темы KDE и для приложений GTK. Так что, если решение работает с GTK, это нормально.
Когда я запускаю следующий фрагмент кода под Gnome (Ubuntu 8.04), приложение Java выглядит прекрасно. Он очень хорошо интегрируется с остальными приложениями:
try {
// Set System L&F
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch(Exception e) { //Handle it }
Однако, если я запускаю то же самое в Debian (Lenny) с KDE, вызов UIManager.getSystemLookAndFeelClassName() возвращает вызов Java по умолчанию. Если я продолжу и заставлю его использовать GTK LNF, приложение не будет работать. Некоторые поля невидимы, другие становятся неуместны, все непригодно для использования:
try {
//Force the GTK LNF on top of KDE, but **it doesn't work**
UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
} catch (Exception e) { /*Handle it*/ }
Я также попытался поставить следующий код. Это позволяет пользователю выбрать любой из доступных LNF, а затем пытается его установить. Металл и мотив хорошо работают. GTK нет. Слайдер действительно испорчен. Поле со списком выглядит некрасиво и исчезает, но, кажется, работает. Кнопки и меню кажутся нормальными. Соответствующий код показан здесь:
(...)
/** Creates new form SwingFrame */
public SwingFrame() {
initComponents();
//Save all available lafs in a combobox
cbLafs.removeAllItems();
UIManager.LookAndFeelInfo[] lafs=UIManager.getInstalledLookAndFeels();
for (int i=0,t=lafs.length;i<t;i++)
{
cbLafs.addItem(lafs[i]);
System.out.println(lafs[i].getName());
}
}
public void changeLookAndFeel(String laf)
{
//If not specified, get the default one
if (laf==null) {
laf=UIManager.getSystemLookAndFeelClassName();
}
try {
// Set System L&F
UIManager.setLookAndFeel(laf);
}
catch (Exception e) {
// handle exception
e.printStackTrace();
}
SwingUtilities.updateComponentTreeUI(this);
}
private void cbLafsActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
UIManager.LookAndFeelInfo laf=(UIManager.LookAndFeelInfo)cbLafs.getSelectedItem();
if (laf==null)
changeLookAndFeel(null);
else
changeLookAndFeel(laf.getClassName());
}
В этой же системе все приложения GTK работают (например, Firefox), как и ожидалось. Так:
1) Чего не хватает в среде, чтобы приложение Java GTK LNF работало под KDE?
2) Что проверяет JVM, чтобы вернуть GTK в качестве системной темы по умолчанию?
Спасибо за помощь Луису Фернандо
PS-> Я пробовал и другие решения, такие как JGoodies, обычный AWT и SWT. Тем не менее, Swing с GTK LNF был бы лучшим решением, чтобы избежать хлопот с нативными библиотеками SWT и дополнительными банками JGoodies (также JGoodies LNF выглядит не так интегрированно, как Swing GTK под Gnome). AWT выглядит отвратительно (похоже на мотив) и пропускает множество функций.
4 ответа
Вы можете настроить внешний вид из командной строки:
java -Dswing.defaultlaf = com.sun.java.swing.plaf.gtk.GTKLookAndFeel MyApp
Кроме того, SwingSet2.jnlp предоставляет пример демонстрации всех различных вещей, которые могут быть изменены. Источник и другая информация могут быть найдены здесь: текст ссылки
Возможно это работает:
try {
// sure look and feel
UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
// not-so-sure look and feel
System.setProperty("os.name", "Windows");
System.setProperty("os.version", "5.1");
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
}
catch (Exception ex) {
ex.printStackTrace();
}
Цитирование документации:
Если системное свойство
swing.defaultlaf
не является нулевым, используйте его значение в качестве имени класса по умолчанию.Если файл свойств
swing.properties
существует и содержит ключswing.defaultlaf
, используйте его значение в качестве имени класса по умолчанию. Местоположение, которое проверяется наswing.properties
может варьироваться в зависимости от реализации платформы Java. В реализации Sun расположение${java.home}/lib/swing.properties
Обратитесь к примечаниям к выпуску используемой реализации для получения дополнительной информации.
Но я на 99% уверен, что это ваша проблема (снова цитируя документы):
После того, как внешний вид изменился, необходимо вызвать
updateUI
на всеJComponents
, МетодSwingUtilities.updateComponentTreeUI(java.awt.Component)
позволяет легко применять updateUI к иерархии содержимого. Обратитесь к нему за подробностями. Точное поведение не вызывающего updateUI после изменения внешнего вида не определено. Очень возможно получить неожиданные исключения, проблемы с окраской или еще хуже.
Если вы не хотите вызывать updateUI
на все JComponents
обязательно вызовите UIManager.setLookAndFeel
перед каждым другим кодом свинга.
ГТК Лаф, ИМХО, сломанный период. Он не учитывает некоторые случайные настройки. Я считаю, что он не должен соблюдать какие-либо setBackground(), setForeground() или setFont() на большинстве компонентов.
Если вы используете java >1.4.2, я предлагаю использовать MetalLookAndFeel [должно быть UIManager.getCrossPlatformLookAndFeelClassName()]. Если вы используете>1.6.0_u10, вы можете попробовать NautilusLookAndFeel. Я лично считаю, что Металл выглядит лучше.