150 |
ГЛАВА 6 |
Таблица 6.3 (продолжение) |
|
|
|
Вид модальности |
Описание |
|
|
APPLICATION_MODAL |
При создании и выводе такого диалогового окна все окна, уже соз- |
|
данные приложением (формально, тем же экземпляром виртуаль- |
|
ной машины), будут заблокированы для пользователей. Дочерние |
|
диалоги и окна, создаваемые модальным диалогом, доступны |
|
пользователю |
DOCUMENT_MODAL |
Блокирует работу окон, принадлежащих к одному родительскому |
|
окну или иерархии окон, создавших друг друга, от самого первого |
|
родителя. Другие окна не из этой иерархии не блокируются. |
TOOLKIT_MODAL |
Предназначено для апплетов, блокирует все окна, созданные ап- |
|
плетами из одной страницы, даже если сами апплеты раздельные |
Кроме того, что вы можете создавать собственные диалоговые окна, используя класс JDialog, библиотека Swing предоставляет вам богатый набор стандартных диалоговых окон, используемых для получения и вывода несложной информации. Стандартные диалоговые окна хороши тем, что пользователи быстро привыкают к ним, их легко настраивать и применять в своих приложениях. Так что прежде чем создавать собственное диалоговое окно, всегда стоит подумать о возможности использовать стандартное. Стандартные диалоговые окна Swing мы будем обсуждать в главе 14.
Специальное оформление окон
Окна Swing предоставляют вам возможность настраивать так называемое визуальное «оформление» окон: их рамку, элементы управления (такие как кнопки закрытия или свертывания), системное меню. Необходимость этого ощущалась с самых первых выпусков Swing после появления механизма подключаемых внешнего вида и поведения. Какой бы внешний вид и поведение для своей программы вы не использовали, уверенности в том, что она будет выглядеть и вести себя одинаково на любой платформе не было, потому что окна, в которых размещался интерфейс, находился вне вашей власти, и их внешний вид мог довольно сильно контрастировать с вашим интерфейсом. Особенно это было заметно при выборе внешнего вида, который не имитировал какую-либо известную платформу, такую как Windows или Macintosh, а применялся только для Swing (например, используемый по умолчанию внешний вид Metal). Внешний вид, имитирующий ту или иную платформу, чаще всего именно на этой платформе и использовался, поэтому окна у приложения были соответствующие. Но вот другие внешние виды не обеспечивали нужного оформления окон.
Имитация внешнего вида окон возможна, в первую очередь, благодаря UIпредставителю корневой панели JRootPane. Если программист-клиент библиотеки Swing захочет особым образом оформить окна, UI-представитель корневой панели создаст специальные рамки, заголовок, системное меню и кнопки управления окном, подходящие для текущих внешнего вида и поведения, разместит их нужным способом в корневой панели, используя специализированный менеджер расположения, и сообщит частям корневой панели, что пространства в ней стало меньше, так что они не смогут занимать место, занятое рамками окна. Кроме того, при новом оформлении окон отключаются системные элементы окна (вот где пригодится метод setUndecorated()). Можно заставить корневую панель выглядеть как окно, и не отключая системные элементы и рамки, только вот смотреться это будет непривлекательно.
Чтобы не принуждать вас для оформления окон каждый раз настраивать корневую панель и убирать с окон имеющиеся «украшения», в классы JFrame и JDialog (окну JWindow оформление не нужно) был добавлен статический метод setDefaultLookAndFeelDecorated(), обеспечивающий возможность оформления всех создаваемых окон. Единственное, что
Контейнеры высшего уровня |
151 |
стоит отметить — оформление окон поддерживается не всеми менеджерами внешнего вида, это «необязательное» свойство. Однако почти все дополнительные подключаемые внешние виды для Swing поддерживают это свойство, так что использовать его имеет смысл, поскольку на любой платформе приложение приобретает законченный облик. Рассмотрим небольшой пример:
//WindowDecorations.java
//Специальное оформление окон Swing import javax.swing.*;
public class WindowDecorations {
public static void main(String[] args) { SwingUtilities.invokeLater(
new Runnable() { public void run() {
//включим украшения для окон
JFrame.setDefaultLookAndFeelDecorated(true);
JDialog.setDefaultLookAndFeelDecorated(true);
//окно с рамкой
JFrame frame = new JFrame("Окно с рамкой"); frame.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE); frame.setSize(200, 200); frame.setVisible(true); // диалоговое окно
JDialog dialog = new JDialog(frame, "Диалог"); dialog.setDefaultCloseOperation(
JDialog.DISPOSE_ON_CLOSE); dialog.setSize(150, 100);
// так можно задавать тип оформления окна dialog.getRootPane().setWindowDecorationStyle(
JRootPane.INFORMATION_DIALOG); dialog.setVisible(true);
}
});
}
}
Вэтом примере мы прямо в методе main(), ни от чего не наследуя, создаем простое окно
срамкой и диалоговое окно. Но еще до их создания вызывается метод setDefaultLookAndFeelD ecorated(), означающий, что для создаваемых окон JFrame и JDialog потребуется специальное
оформление. Далее мы просто настраиваем окна и выводим их на экран. Остается обратить внимание на метод корневой панели setWindowDecorationStyle(), позволяющий настроить тип оформления окна. Если окно с рамкой имеет только один тип оформления, то диалоговые окна в зависимости от их цели (вывод информации, сообщение об ошибке и т. д.) могут выглядеть по-разному. В нашем примере мы указали, что создаваемое диалоговое окно требу-
152 |
ГЛАВА 6 |
ется для вывода информации и должно выглядеть соответствующим образом. Запустив программу с примером, вы увидите, как оформляет свои окна внешний вид Java по умолчанию, а например, в известном стороннем внешнем виде Substance окна выглядят так:
Специальное оформление окон не только позволяет придать вашему приложению законченный облик, оно может быть полезно как средство, позволяющее полностью, вплоть до окон, управлять внешним видом вашего приложения. Создав собственного UI-представителя корневой панели, вы сможете придать своему приложению уникальный вид, легко узнаваемый пользователями.
Прозрачность и произвольные формы
При разговоре об окнах все время закрадывается мысль, что и говорить особенно не о чем, настолько они просты и настолько вспомогательные функции выполняют. Однако в новой версии JDK 1.7 (или если угодно, Java 7), окна наделены новыми впечатляющими возможностями, способными придать Java-приложениям авангардный внешний вид, конечно, если само приложение подразумевает подобный пользовательский интерфейс.
В современных операционных системах уже довольно давно поддерживается прозрачность окон и задание для них произвольной формы вместо прямоугольной. Именно эти возможности и предоставляет для нас в Java и Swing новая версия JDK. Включаются они всего парой методов, так что пользоваться ими очень просто. Давайте сразу же посмотрим на все в действии:
//ShapedWindows.java
//Полупрозрачные окна произвольных форм import javax.swing.*;
import java.awt.FlowLayout;
import java.awt.geom.RoundRectangle2D;
public class ShapedWindows extends JFrame { public ShapedWindows() {
super("ShapedWindows"); setDefaultCloseOperation(EXIT_ON_CLOSE);
//размер окна setSize(300, 200);
//несколько компонентов в ряд
Контейнеры высшего уровня |
153 |
setLayout(new FlowLayout()); add(new JLabel("Текст:")); add(new JTextField(15));
//задаем округлую форму
RoundRectangle2D.Float roundedShape =
new RoundRectangle2D.Float(0, 0, 300, 200, 70, 70); setShape(roundedShape);
//задаем прозрачность
setOpacity(0.7f);
setVisible(true);
}
public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() {
public void run() { JFrame.setDefaultLookAndFeelDecorated(true); new ShapedWindows();
}
});
}
}
В примере мы сразу же, еще до создания нашего окна с рамкой, указываем, что у всех окон должно быть специальное оформление, так мы лучше увидим особую форму нашего окна. В конструкторе в центр окна для наглядности добавляются надпись с небольшим текстовым полем, так что запустив пример, вы убедитесь что ввод текста работает несмотря ни на какие формы и прозрачность. Как мы видим, форма окна задается с помощью свойства shape, которое принимает объекты типа Shape из пакета java.awt.geom, описывающего разнообразные геометрические формы. Мы используем форму прямоугольника с закругленными краями. Прозрачность задается еще проще, нужно задать свойство opacity, в виде дробного числа от 0 (полностью прозрачное окно) до 1 (непрозрачное). У нас окно будет прозрачным примерно на 30%. Запустив пример, вы увидите какую форму принимает окно и что все его элементы функционируют как всегда. На иллюстрации окно находится над редактором с текстом книги.
154 |
ГЛАВА 6 |
Как вы видите, задать прозрачность и форму окна проще простого, однако стандартные внешние виды пока что еще не слишком то к этому приспособились (на иллюстрации с окном края окна обрезаны, кнопки обрезаны — внешний вид просто не принимает во внимание формы окна). Возможно, с окончательным выходом Java 7 некоторые сторонние внешние виды будут принимать во внимание форму окна и правильно рисовать его границы. Ну а пока создание окна произвольной формы подразумевает что вы будете рисовать его содержимое, или по крайней мере границы, вручную. Прозрачность же окон хороша и сама по себе, к примеру, вы можете делать вспомогательные окна более прозрачными, когда они теряют фокус ввода или становятся менее нужными, но убирать с экрана их нельзя.
И еще одно — полупрозрачные окна и окна произвольных форм могут не поддерживаться на некоторых платформах, и вызов рассмотренных нами методов приведет к исключениям. Если вы рассчитываете, что ваше приложение будет исполняться на самых разнообразных платформах, имеет смысл еще перед вызовом методов удостовериться в том, что они работают. Это можно сделать с помощью класса AWT GraphicsDevice, который позволяет узнать конфигурацию текущей графической системы.
Кратко об апплетах — класс JApplet
В этой книге мы говорим о платформе Java и библиотеках Java Foundation Classes как о прекрасном средстве создания мощных и переносимых между платформами приложений. Однако в первых выпусках Java все средства разработки пользовательских интерфейсов в основном были направлены на создание апплетов (applets): небольших приложений, написанных в соответствии с простым программным интерфейсом и ориентированных на выполнение в браузере при просмотре HTML-страниц. Апплеты на самом деле были революционным шагом: они не зависели от браузеров и выполнялись на любой платформе с установленной виртуальной машиной Java, позволяя задействовать всю мощь Java внутри обычной HTML-страницы. Начиная с Java 2 (JDK 1.2), Sun предложила для выполнения апплетов концепцию модуля расширения (plug-in) Java. Этот модуль надо загрузить с официального сайта java.sun.com, что гарантирует получение самых свежих версий.
Однако нельзя сказать, что новая модель загрузки апплетов, предложенная Sun, повысила их популярность. Модуль расширения Java довольно объемен, и загружать его для выполнения некого апплета захочет не каждый пользователь. С другой стороны, возросли возможности и потенциал языков сценариев, встроенных в HTML-страницы, возможности самого языка HTML, чрезвычайно возросла популярность динамических страниц (AJAX), содержимое которых генерируется на сервере в зависимости от того, что хочет увидеть и получить пользователь и обновляется частями, без перезагрузки страницы. Все это получает название Web 2.0. Поэтому мы рассматриваем в книге создание отдельных Java-приложений, не ограниченных системой безопасности и браузером, к тому же приложения эти теперь можно легко распространять через Web (используя технологию Java Web Start) вместе с виртуальной машиной Java. Тем не менее, остаются ситуации, в которых использование апплетов с новыми возможностями оправдано, к примеру, встраивание в апплет уже готового мощного Swing-приложения для доступа к нему через Web. Рассмотрим вкратце процесс создания апплетов с использованием Swing.
Любой апплет (небольшое приложение, работающее в составе HTML-страницы), предполагающий задействовать компоненты Swing, должен быть унаследован от базового класса JApplet. Класс JApplet унаследован от класса Applet, описывающего инфраструктуру всех апплетов, и отличается от него лишь тем, что имеет в своем составе корневую панель, в которой вы размещаете свои компоненты. Класс JApplet, так же как и окна Swing, представляет собой тяжеловесный контейнер высшего уровня, именно он затем