- How to Set the Look and Feel
- Available Look and Feels
- Programatically Setting the Look and Feel
- Specifying the Look and Feel: Command Line
- Specifying the Look and Feel: swing.properties File
- How the UI Manager Chooses the Look and Feel
- Changing the Look and Feel After Startup
- An Example
- Themes
- The SwingSet2 Demonstration Program
- Windows look and feel for JFileChooser
- 8 Answers 8
- Swing. Десять полезных простых вещей
- Читают сейчас
- Редакторский дайджест
- Похожие публикации
- Автоматическое тестирование Java Swing приложений
- Подписывание Java апплета и некоторые тонкости java security
- JAVA+Swing в 2013. Стоит ли?
- Средняя зарплата в IT
- Минуточку внимания
- Комментарии 56
How to Set the Look and Feel
The architecture of Swing is designed so that you may change the «look and feel» (L&F) of your application’s GUI (see A Swing Architecture Overview). «Look» refers to the appearance of GUI widgets (more formally, JComponents ) and «feel» refers to the way the widgets behave.
Swing’s architecture enables multiple L&Fs by separating every component into two distinct classes: a JComponent subclass and a corresponding ComponentUI subclass. For example, every JList instance has a concrete implementation of ListUI ( ListUI extends ComponentUI ). The ComponentUI subclass is referred to by various names in Swing’s documentation—»the UI,» «component UI,» «UI delegate,» and «look and feel delegate» are all used to identify the ComponentUI subclass.
Most developers never need to interact with the UI delegate directly. For the most part, the UI delegate is used internally by the JComponent subclass for crucial functionality, with cover methods provided by the JComponent subclass for all access to the UI delegate. For example, all painting in JComponent subclasses is delegated to the UI delegate. By delegating painting, the ‘look’ can vary depending upon the L&F.
It is the responsibility of each L&F to provide a concrete implementation for each of the ComponentUI subclasses defined by Swing. For example, the Java Look and Feel creates an instance of MetalTabbedPaneUI to provide the L&F for JTabbedPane . The actual creation of the UI delegate is handled by Swing for you—for the most part you never need to interact directly with the UI delegate. javax.swing package—for example, DefaultButtonModel or JToggleButton.ToggleButtonModel. The Model objects are independent of the L&F installed.
The ComponentUI class in the javax.swing.plaf package is the base class for all UI delegate objects in the Swing pluggable look and feel architecture. The JComponent class invokes methods from this class in order to delegate operations (painting, event handling, etc.) that vary depending on the L&F installed.
A Look and Feel, then, is a set of coordinated UI delegate objects, one for each JComponent used in the GUI.—>
The rest of this section discusses the following subjects:
Available Look and Feels
Sun’s JRE provides the following L&Fs:
CrossPlatformLookAndFeel —this is the «Java L&F» (also called «Metal») that looks the same on all platforms. It is part of the Java API ( javax.swing.plaf.metal ) and is the default that will be used if you do nothing in your code to set a different L&F.
SystemLookAndFeel —here, the application uses the L&F that is native to the system it is running on. The System L&F is determined at runtime, where the application asks the system to return the name of the appropriate L&F.
Synth—the basis for creating your own look and feel with an XML file.
Multiplexing— a way to have the UI methods delegate to a number of different look and feel implementations at the same time.
For Linux and Solaris, the System L&Fs are «GTK+» if GTK+ 2.2 or later is installed, «Motif» otherwise. For Windows, the System L&F is «Windows,» which mimics the L&F of the particular Windows OS that is running—classic Windows, XP, or Vista. The GTK+, Motif, and Windows L&Fs are provided by Sun and shipped with the Java SDK and JRE, although they are not part of the Java API.
Apple provides its own JVM which includes their proprietary L&F.
In summary, when you use the SystemLookAndFeel , this is what you will see:
Platform | Look and Feel |
---|---|
Solaris, Linux with GTK+ 2.2 or later | GTK+ |
Other Solaris, Linux | Motif |
IBM UNIX | IBM* |
HP UX | HP* |
Classic Windows | Windows |
Windows XP | Windows XP |
Windows Vista | Windows Vista |
Macintosh | Macintosh* |
* Supplied by the system vendor.
You don’t see the System L&F in the API. The GTK+, Motif, and Windows packages that it requires are shipped with the Java SDK as:
Note that the path includes java , and not javax .
All of Sun’s L&Fs have a great deal of commonality. This commonality is defined in the Basic look and feel in the API ( javax.swing.plaf.basic ). The Motif and Windows L&Fs are each built by extending the UI delegate classes in javax.swing.plaf.basic (a custom L&F can be built by doing the same thing). The «Basic» L&F is not used without being extended.
In the API you will see four L&F packages:
javax.swing.plaf.basic —basic UI Delegates to be extended when creating a custom L&F
javax.swing.plaf.metal —the Java L&F, also known as the CrossPlatform L&F («Metal» was the Sun project name for this L&F) The current default «theme» (discussed below) for this L&F is «Ocean, so this is often referred to as the Ocean L&F.
javax.swing.plaf.multi —a multiplexing look and feel that allows the UI methods to delegate to a number of look and feel implementations at the same time. It can be used to augment the behavior of a particular look and feel, for example with a L&F that provides audio cues on top of the Windows look and feel. This is a way of creating a handicapped-accessible look and feel.
javax.swing.plaf.synth —an easily configured L&F using XML files (discussed in the next section of this lesson)
You aren’t limited to the L&Fs supplied with the Java platform. You can use any L&F that is in your program’s class path. External L&Fs are usually provided in one or more JAR files that you add to your program’s class path at runtime. For example:
Once an external L&F is in your program’s class path, your program can use it just like any of the L&Fs shipped with the Java platform.
Programatically Setting the Look and Feel
The L&F that Swing components use is specified by way of the UIManager class in the javax.swing package. Whenever a Swing component is created,the component asks the UI manager for the UI delegate that implements the component’s L&F. For example, each JLabel constructor queries the UI manager for the UI delegate object appropriate for the label. It then uses that UI delegate object to implement all of its drawing and event handling.
To programatically specify a L&F, use the UIManager.setLookAndFeel() method with the fully qualified name of the appropriate subclass of LookAndFeel as its argument. For example, the bold code in the following snippet makes the program use the cross-platform Java L&F:
Alternatively, this code makes the program use the System L&F:
You can also use the actual class name of a Look and Feel as the argument to UIManager.setLookAndFeel() . For example,
You aren’t limited to the preceding arguments. You can specify the name for any L&F that is in your program’s class path.
Specifying the Look and Feel: Command Line
You can specify the L&F at the command line by using the -D flag to set the swing.defaultlaf property. For example:
Specifying the Look and Feel: swing.properties File
Yet another way to specify the current L&F is to use the swing.properties file to set the swing.defaultlaf property. This file, which you may need to create, is located in the lib directory of Sun’s Java release (other vendors of Java may use a different location). For example, if you’re using the Java interpreter in javaHomeDirectory\bin , then the swing.properties file (if it exists) is in javaHomeDirectory\lib . Here is an example of the contents of a swing.properties file:
How the UI Manager Chooses the Look and Feel
Here are the look-and-feel determination steps that occur when the UI manager needs to set a L&F:
- If the program sets the L&F before a look and feel is needed, the UI manager tries to create an instance of the specified look-and-feel class. If successful, all components use that L&F.
- If the program hasn’t successfully specified a L&F, then the UI manager uses the L&F specified by the swing.defaultlaf property. If the property is specified in both the swing.properties file and on the command line, the command-line definition takes precedence.
- If none of these steps has resulted in a valid L&F, Sun’s JRE uses the Java L&F. Other vendors, such as Apple, will use their default L&F.
Changing the Look and Feel After Startup
You can change the L&F with setLookAndFeel even after the program’s GUI is visible. To make existing components reflect the new L&F, invoke the SwingUtilities updateComponentTreeUI method once per top-level container. Then you might wish to resize each top-level container to reflect the new sizes of its contained components. For example:
An Example
In the following example, LookAndFeelDemo.java , you can experiment with different Look and Feels. The program creates a simple GUI with a button and a label. Every time you click the button, the label increments.
You can change the L&F by changing the LOOKANDFEEL constant on line 18. The comments on the preceding lines tell you what values are acceptable:
Here the constant is set to «Motif», which is a L&F that will run on any platform (as will the default, «Metal»). «GTK+» will not run on Windows, and «Windows» will run only on Windows. If you choose a L&F that will not run, you will get the Java, or Metal, L&F.
In the section of the code where the L&F is actually set, you will see several different ways to set it, as discussed above:
You can verify that both arguments work by commenting/un-commenting the two alternatives.
Here is a listing of the LookAndFeelDemo source file:
Themes
Themes were introduced as a way of easily changing the colors and fonts of the cross-platform Java (Metal) Look and Feel. In the sample program, LookAndfeelDemo.java , listed above, you can change the theme of the Metal L&F by setting the THEME constant on line 23 to one of three values:
Ocean , which is a bit softer than the pure Metal look, has been the default theme for the Metal (Java) L&F since Java SE 5. Despite its name, DefaultMetal is not the default theme for Metal (it was before Java SE 5, which explains its name). The Test theme is a theme defined in TestTheme.java , which you must compile with LookAndfeelDemo.java . As it is written, TestTheme.java sets the three primary colors (with somewhat bizarre results). You can modify TestTheme.java to test any colors you like.
The section of code where the theme is set is found beginning on line 92 of LookAndfeelDemo.java . Note that you must be using the Metal L&F to set a theme.
The SwingSet2 Demonstration Program
When you download the JDK and JavaFX Demos and Samples bundle and open it up, there is a demo\jfc folder that contains a demonstration program called SwingSet2 . This program has a graphically rich GUI and allows you to change the Look and Feel from the menu. Further, if you are using the Java (Metal) Look and Feel, you can choose a variety of different themes. The files for the various themes (for example, RubyTheme.java ) are found in the SwingSet2\src folder.
This is the «Ocean» theme, which is the default for the cross-platform Java (Metal) Look and Feel:
This is the «Steel» theme, which was the original theme for the cross-platform Java (Metal) Look and Feel:
To run the SwingSet2 demo program on a system that has the JDK installed, use this command:
This will give you the default theme of Ocean.
Windows look and feel for JFileChooser
I’m trying to generate a JFileChooser that has the Windows look-and-feel. I couldn’t find a method to change it, so I created a base class that extends JFileChooser that changes the UI with the following code:
Then, in another class, I call
but the dialog box that comes up has the Java look and feel. Any thoughts on how to change this? Is there a method of the JFileChooser class that I can use instead of this extended class?
8 Answers 8
If you don’t need to change the Look and Feel, could you try putting the UIManager.setLookAndFeel(..) line in the main method of your entry class?
That seems to work for me, though I am at a loss as to why it won’t work the way you have set it upt.
I know you can set the look and feel for the whole application, but what do you do if you like the cross platform look and feel but want the System Look and Feel for the JFileChoosers. Especially since the cross platform doesn’t even have the right file icons (and looks completely cheesy.)
Here is what I did. It is definitely a hack.
The problem is that the Look & Feel was already selected for you when you called super(path) .
Note: If you are going to set the L&F, you should do it as the very first step in your application. Otherwise you run the risk of initializing the Java L&F regardless of what L&F you’ve requested. This can happen inadvertently when a static field references a Swing class, which causes the L&F to be loaded. If no L&F has yet been specified, the default L&F for the JRE is loaded. For Sun’s JRE the default is the Java L&F, for Apple’s JRE the Apple L&F, and so forth.
To remedy, you should do this (explanation located here) — replace your try/catch block with this code:
Swing. Десять полезных простых вещей
Хочу поделиться недавним опытом разработки апплетов на Swing и рассказать про подводные камни, приемы найденные и использованные в процессе работы.
Если вы уже имели дело с библиотекой Swing, то можете сразу переходить ко второй главе.
Три шага для быстрого старта
- Для начала внимательно изучаем документацию по различным Layout менеджерам, без таких базовых знаний будет сложно добиться желаемого отображения.
- Затем внимательно изучаем базовые визуальные компоненты java look and feel или windows look and feel. Как и что использовать в работе можно подсмотреть в учебнике.
- Ставим Eclipse и создаем java проект, создаем апплет и . «дальше напильником»(с).
Для быстрого старта и построения простых интерфейсов этих знаний будет вполне достаточно.
Теперь переходим к самому интересному.
Десять полезных простых вещей
1. Для того чтобы выставить look and feel как в системе (например соответствующий теме windows):
2. Меняем шрифт заданный по умолчанию:
3. Простой вариант модального диалога:
Если требуется более продвинутый диалог, есть вариант с возможностью добавления JComponent:
4. Для быстрой локализации диалогов:
5. Для фильтрации элементов в колонках таблицы JTable есть очень хорошая открытая библиотека Swing Bits с помощью которой можно сделать фильтр «как в Экселе».
6. Для того, чтобы дать пользователю возможность выбирать даты есть отличный компонент jcalendar
7. Для проигрывания звука упакованного в jar архив:
Теперь немного нетривиальных фишек:
8. Для того чтобы встроить в строку таблицы кнопку (с правильным рендером клика):
9. Для того, чтобы изменить компоненты swing из другого потока нужно использовать посредника:
10. И наконец фишка про SwingWorker. В один момент времени может выполняться всего десять SwingWorker потоков, связано это с тем, что пул потоков обработчика SwingWorker имеет максимальный размер десять, так что старайтесь чтобы задачи были не большие. Пример из жизни: в IE можно открыть 10 страниц с апплетами, а 11 будет уже ждать(«висеть») пока осводобится место в ThreadPoolExecutor для обработки данных полученных с сервера в другом потоке.
Послесловие
Читают сейчас
Редакторский дайджест
Присылаем лучшие статьи раз в месяц
Скоро на этот адрес придет письмо. Подтвердите подписку, если всё в силе.
Похожие публикации
Автоматическое тестирование Java Swing приложений
Подписывание Java апплета и некоторые тонкости java security
JAVA+Swing в 2013. Стоит ли?
Средняя зарплата в IT
AdBlock похитил этот баннер, но баннеры не зубы — отрастут
Минуточку внимания
Комментарии 56
6. Для того, чтобы дать пользователю возможность выбирать даты есть отличный компонент jcalendar
Он не отличный. JDateChooser меня разочаровал следующим:
1. не поддерживает выравнивание по базовой линии (baseline)
2. есть проблемы с обнулением даты внутри него
3. нет возможности дать пользователю ввести 1.02.12 и чтобы JDateChooser интерпретировал это как 1.02.2012; такое можно вылечить самому, но это дополнительная подпорка.
4. плохо дружит с различными темами; в частности, у меня были проблемы с Nimbus и substance.
9. Для того, чтобы изменить компоненты swing из другого потока нужно использовать посредника:
Есть базовый механизм запуска произвольного кода в потоке GUI — invokeLater. А всякие SwingWorker’ы — это уже механизмы поверх.
В целом разработка под swing парадовала обилием документации и примеров на все случаи жизни. Если интересно могу еще в том же духе поподробней рассказать про фишки JTable.
2. Не нравятся они мне. Мне нравится свинговый GroupLayout, все остальные не так мощны.
Мне тоже нравился вначале GroupLayout. Но вообще, там внутри концепция мозгоразрывная. А единственный вменяемый дизайнер из Netbeans тоже имеет ряд глюков и иногда перекашивает весь layout, и ничего не поделаешь. Так что теперь склоняюсь к GridBagLayout. Хотя, layout’ы в AWT/Swing кривоваты. Например, у GridBagLayout нельзя задавать промежутки между ячейками (insets — это несколько другое).
Это было сделано давно, до гугла. А сейчас только багфиксы, практически никакого развития. Например, поддержки GXT 3 не будет.
WBP изначально был задуман как two-way: работа только с кодом, никаких промежуточных костылей в виде спец-файлов для форм и т.п.
1. Многие из кучи этих констант трудно было бы отнести к какому-то отдельному классу, поэтому они универсальные. Ну с точки зрения «православного» ООП, стили в виджеты следовало бы передавать через java.util.Set, но это довольно тяжеловесный объект, да и создавать его достаточно многословно. А EnumSet в те времена ещё не существовал.
2. Понятия baseline у стандартных виджетов и layout managers нету, но при необходимости можно реализовать такой менеджер. Свойства для baseline в базовом классе Control не предусмотрено, но к каждому контролу можно прилеплять метаинформацию через setData().
3. Не убогие таблицы есть только в Excel :), но там они не являются нативными контролами.
4. Загрузка иконки стандартными методами
При помощи самописного класса:
5. Глобальный обработчик событий клавиатуры можно повесить на Display методом addFilter().
1. Многие из кучи этих констант трудно было бы отнести к какому-то отдельному классу, поэтому они универсальные. Ну с точки зрения «православного» ООП, стили в виджеты следовало бы передавать через java.util.Set, но это довольно тяжеловесный объект, да и создавать его достаточно многословно. А EnumSet в те времена ещё не существовал.
Ну вообще, никуда константы не надо относить. Под константы, сгруппированные по общему признаку, надо выделять отдельный enum. А то, что проблемы SWT во многом благодаря старой Java — это да.
Понятия baseline у стандартных виджетов и layout managers нету, но при необходимости можно реализовать такой менеджер. Свойства для baseline в базовом классе Control не предусмотрено, но к каждому контролу можно прилеплять метаинформацию через setData().
Ну т.е. допиливание. А из коробки не может. В итоге каждый плодит свой велосипед. Кстати, мне кажется, что setData для этого не очень хорошо подходит. Тем более, что baseline может много от чего меняться.
3. Не убогие таблицы есть только в Excel :), но там они не являются нативными контролами.
Ну не надо так передёргивать. Я понимаю, что юзера с его хотелками можно только excel’ем порадовать. Но когда отсутствуют базовые простейшие вещи и приходится ради них допиливать — это ужас.
4. Загрузка иконки стандартными методами
Опять велосипед, опять допиливание. Из коробки не может.
Глобальный обработчик событий клавиатуры можно повесить на Display методом addFilter().
Я и не спорю что это дело можно автоматизировать 🙂
Просто говорю о том, что это дополнительная задача при работе с апплетами.
А если в целом об апплетах — они конечно могут быть использованы в некоторых отдельных случаях, но мне кажется что они себя практически изжили. Их конечно продолжать поддерживать браузеры, как и многие сайты до сих пор поддерживают древний IE6, но это скорее из уважения к немногим пользующимся. Дело даже не в самих апплетах, а в том, что намного проще сейчас написать приложение со схожей функциональностью на html/js, ведь их возможности уже давно перешли за грань «простых скриптиков». Подобное приложение будет работать на порядок быстрее чем апплет и не будет зазря грузить браузер и ресурсы компьютера, а так же не будет иметь проблем со совместимостью с разными платформами.
Возможно единственный более-менее востребованный вариант применения — быстрый перенос своего Swing-приложения в онлайн. Впрочем там есть свои подводные камни…
Сомневаюсь что из-за простоты разбора. Если только на этом базируется выбор апплетов — банковские разработчики весьма недалёкие люди.
Да, действительно, некоторые платные обфускаторы (которыми мы тоже пользуемся в своих проектах) и даже бесплатные умеют прилично запутать код, обрезать все названия, слить классы в одну большую кишку и сделать множество прочих пакостей для любителей покопаться в исходниках. Но проблемы это не решает — код по прежнему можно разобрать при должной усидчивости и терпении, коими «серьёзные» взломщики, уверен, обладают. Именно поэтому делать ставку на то, что в обфусцированном коде никто ничего не поймёт и можно воротить всё что нравится — крайне неверно. Поймут, найдут и сломают, если для них из этого будет профит (а может даже и просто из любопытства).
При корректной реализации любых банковских операций и должной защите на серверной стороне, как мне кажется, не важно какой будет клиент. Ну увидят исходники и что дальше? Если лазеек в серверной стороне нет — злоумышленники ничего и не смогут сделать.
Если какие-то взломы и происходят, то скорее по вине пользователей (увели логин/пароль от аккаунта, к примеру). От этого сложно защититься. Впрочем именно для этого и созданы различные подтверждения операций через sms, привязка к IP/машине и прочие средства защиты от постороннего доступа/проведения операций.
Не буду спорить, что многие вещи будет проще/быстрее реализовать в апплете, обладающем практически всеми возможностями полноценного десктоп-приложения на Java. Остальные же преимущества апплетов я считаю весьма необоснованными или, как минимум, спорными.
P.S. Или может я не о тех банковских клиентах думаю.
К сожалению, я не знаю, как работает банковский клиент-серверный софт. Но обычно бывает так, что в клиенте после, скажем ввода пароля и использования какого-нить сертификата открывается некоторый путь для общения с сервером. Теперь, после получения этого ключика и сертификата я делаю свое приложение с этими же данными и выкладываю его на гитхаб. И все кто не лень начинают лезть в этот самый сервер и рано или поздно находят дыру — защищенных систем не существует, по крайней мере я в них не верю.
Ну так вот при использовании джаваскрипта достать этот ключик и сертификат куда проще.
Полностью защищённых систем может и нет, но достаточный уровень защиты на серверной стороне обеспечить вполне реально (без критических дыр, открывающих доступ ко всему и вся).
В любом случае, я всё веду к тому, что стоит разумно ограничивать себя при защите приложения, а так же разумно подходить к выбору платформы/языка на котором оно пишется, основываясь не только на защищённости клиента от той же декомпилляции. Всегда есть множество вариантов и защиты и взлома приложения — от всего не уберечься.
Впрочем я лично не занимаюсь написанием банковского софта и точно не знаю как у них принимаются подобные решения. Возможно причина вообще не в том, о чём мы думаем…