Материал: Портянкин И. Swing

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Контейнеры высшего уровня

155

размещается на HTML-странице. В апплетах нет метода main(), начинающего работу приложения, вместо этого вы переопределяете специальные методы, которые затем вызываются браузером при выводе вашего апплета на экран. Подробности об апплетах вы сможете найти в интерактивной документации Java, а сейчас мы рассмотрим небольшой пример, демонстрирующий процесс создания самого простого апплета:

//SwingApplet.java

//Простой апплет с использованием Swing import javax.swing.*;

import java.awt.*;

public class SwingApplet extends JApplet {

// этот метод вызывается при создании апплета

@Override

public void init() {

// создание интерфейса

SwingUtilities.invokeLater( new Runnable() {

public void run() {

JPanel contents = new JPanel(); contents.add(new JTextField(10)); contents.add(new JButton("Ввод")); setContentPane(contents);

}});

}

}

Как и полагается, мы унаследовали класс своего апплета от JApplet, и поместили код, создающий пользовательский интерфейс, в метод init(). Этот метод вызывается браузером при создании апплета, когда пользователь в первый раз попадает на страницу, где он размещен. Чаще всего именно в нем создается пользовательский интерфейс апплета. Обратите внимание, что данный метод вызывается не из потока рассылки событий, поэтому нам нужно вручную перейти в поток рассылки, как мы всегда делаем в методе main(). Создание интерфейса для апплета ничем не отличается от создания интерфейса для обычного приложения: те же компоненты, та же корневая панель. Заметьте, что благодаря корневой панели апплет может обладать строкой меню или быть многодокументным приложением, что для части HTML-страницы (а апплет на самом деле — всего лишь часть страницы) просто удивительно. Чтобы запустить апплет в браузере, необходимо поместить его на HTML-страницу, например, на такую:

<HTML>

<HEAD><TITLE>SwingApplet</TITLE></HEAD>

<BODY>

<APPLET code=SwingApplet height=100 width=200> </APPLET>

</BODY>

</HTML>

156

ГЛАВА 6

Взглянув на страницу, вы увидите, что для запуска апплета необходимо указать его класс (в параметре code), а также размеры (аналогично тому, как мы задавали размеры окон).

Идея апплетов хороша, и если пользователь соглашается загрузить к себе на компьютер модуль расширения Java, апплеты могут принести много пользы: достаточно даже того, что они могут использовать для создания интерфейса все возможности библиотеки Swing. С другой стороны, модель безопасности апплетов (закрытая от системы «песочница») запрещает им работу с файлами и многими другими ресурсами системы, что предотвращает создание приложений, работающих с документами и данными пользователя. Во многих ситуациях проще создавать обычные приложения и распространять их с помощью технологии Java Web Start, свежую информацию, о которой вы сможете отыскать на официальном сайте Java по адресу java.sun.com.

Многооконное окружение

Как мы уже выяснили в этой главе, окно в современных графических операционных системах используются для разделения задач, выполняемых пользователем, в одном из окон он может редактировать текст, в другом окне просматривать фотографии.

Как только концепция окон была изобретена и довольно успешно начала справляться с разделением задач пользователя на основную и второстепенные, возникло желание продвинуться немного дальше и применить ее уже внутри одного приложение, то есть разделить задачу внутри окна на несколько задач используя все те же окна, но на этот раз уже внутри другого, главного, окна. Подобные интерфейсы

иназываются многодокументными. Приложения, берущие на вооружение такие интерфейсы, как правило, способны выполнять задачи такого широкого спектра, что уместить все в одно окно становится затруднительно без ущемления удобства пользователя. На помощь приходят дополнительные окна, в которых можно разместить информацию, имеющую косвенное отношение к основной, выполняемой в данный момент, задаче.

Применение многодокументных интерфейсов на практике вызывает жаркие споры. Сам по себе интерфейс операционной системы является многодокументным приложением, и встраивание в него еще одного подобного интерфейса может запутывать пользователя. Окна операционной системы работают по своему, окна приложения по своему, и все это не прибавляет уверенности пользователю в том, что происходит

икак этим следует управлять. Тем не менее, как показывает практика, полностью избавиться от дополнительных окон в сложных приложениях затруднительно (обычно пробуют размещать различные задачи приложения в большой панели с вкладками, которая, конечно же, есть и в Swing). Мы все-таки изучим возможности Swing в данном вопросе.

Для того чтобы организовать многодокументный интерфейс, библиотека Swing предлагает нам особый компонент, «рабочий стол» JDesktopPane, и так называемые «внутренние» окна JInternalFrame, которые на этом «столе» размещаются. И компонент JDesktopPane, и окна JInternalFrame являются легковесными, и мы не можем их назвать

контейнерами высшего уровня, однако, по сути, внутренние окна абсолютно идентичны свои собратьям JFrame, поэтому мы и рассмотрим их здесь. Начнем с простого примера, который продемонстрирует нам, что «внутренние» окна ничем не отличаются от привычным нам окон операционной системы:

//SimpleMDI.java

//Демонстрация внутренних окон Swing import javax.swing.*;

Контейнеры высшего уровня

157

public class SimpleMDI extends JFrame { public SimpleMDI() {

super("SimpleMDI"); setSize(400, 300);

setDefaultCloseOperation(EXIT_ON_CLOSE); // создаем рабочий стол Swing

JDesktopPane desktopPane = new JDesktopPane();

//добавляем его в центр окна add(desktopPane);

//создаем несколько внутренних окон

JInternalFrame frame1 =

new JInternalFrame("Окно 1", true); JInternalFrame frame2 =

new JInternalFrame("Окно 2", true, true, true, true); JInternalFrame frame3 =

new JInternalFrame("Палитра", false, true);

//смена типа окна на "палитру" frame3.putClientProperty("JInternalFrame.isPalette", true);

//добавляем внутренние окна на рабочий стол desktopPane.add(frame1); desktopPane.add(frame2); desktopPane.add(frame3);

//задаем размеры и расположения, делаем окна видимыми frame1.setSize(200, 100);

frame1.setLocation(80, 100); frame1.setVisible(true); frame2.setSize(200, 60); frame2.setVisible(true); frame3.setSize(100, 200); frame3.setVisible(true);

//выводим окно на экран

setVisible(true);

}

public static void main(String[] args) { SwingUtilities.invokeLater(

new Runnable() {

public void run() { new SimpleMDI(); } });

}

}

В обычном окне JFrame размещается рабочий стол JDesktopPane. Как видно, никаких параметров конструктору не требуется, так же как не требуется для нормальной работы и дополнительной настройки. О рабочем столе можно думать как о специализированной панели, специально предназначенной для размещения и управления внутренними окнами.

Далее создаются внутренние окна. Интересно, что класс JInternalFrame обладает целым букетом конструкторов с различным набором параметров, которые позволяют

158

ГЛАВА 6

задать все атрибуты внутренних окон. Обязательно присутствует лишь заголовок окна (как первый параметр всех конструкторов). Первое окно создается с заголовком и изменяемого размера, за что отвечает второй параметр конструктора. По умолчанию, если не указывать true, внутренние окна считаются неизменяемого размера, без возможности сворачивания, развертывания, более того, их даже невозможно закрыть. Все эти возможности включаются либо передачей параметров в конструктор, либо меняются через соответствующие свойства.

Второе окно создается вызовом наиболее развернутого конструктора. Здесь мы указываем заголовок окна, а также делаем его размер изменяемым, для самого окна включаем поддержку развертывания, свертывания и способность закрываться по кнопке закрытия окна. Достаточно своеобразное решение создателей Swing не включать все эти свойства по умолчанию, и передавать их в довольно длинный конструктор, но придется

сэтим мириться. Наконец третье окно создается без возможности смены размера, но

свозможностью закрытия. Для него дополнительным, не описанным как поле класса JInternalFrame, свойством мы включаем внешний вид «палитры инструментов». Не все

внешние виды поддерживают «палитры», и нужно проверить работу предпочитаемого вами внешнего вида, перед тем как использовать «палитры».

Внутренние окна стараются во всем походить на своих старших братьев — окна высокого уровня, унаследованные от базового класса Window, и поэтому они по умолчанию невидимы, имеют нулевой размер и располагаются в начале экрана. Работа с внутренними окнами здесь не отличается от работы с обычными. Мы меняем размер окон, устанавливаем их позиции и делаем их видимыми. Только после этого они появятся на рабочем столе JDesktopPane.

Запустив приложение, вы увидите рабочий стол и располагающиеся на нем внутренние окна. Вы можете таскать окна, сворачивать их и менять их размеры, если, конечно, они вам это позволяют (первое окно в нашем примере довольно ограниченно). В дополнение ко всему, рабочий стол позаботится о том, чтобы активное окно (выделенное в данный момент) перекрывало все остальные и было на переднем плане.

На этом можно считать многодокументное приложение Swing готовым. Вы можете конструировать свои интерфейсы и добавлять их во внутренние окна, располагая их, так как вам удобно. Принципиальной разницы между внутренними окнами и окнами тяжеловесными, которые мы уже рассмотрели в этой главе, нет.

Контейнеры высшего уровня

159

Внутренние окна JInternalFrame

Легко видеть, что внутренние окна по сути стараются далеко не отходить от обычных окон Swing. Основным качеством окон является присутствие в них корневой панели, которая, как мы знаем, состоит из нескольких составляющих, и позволяет окнам быть окнами, в том числе отображать полоску меню и контекстные меню. Внутренние окна содержат корневую панель в качестве основного компонента, и для нас это означает, что они являются обычными окнами, просто без связи с операционной системой.

Как и у обычных окон, мы найдем во внутренних окнах такие свойства, как rootPane, contentPane, defaultCloseOperation, title и соответствующие методы get и set. Все они имеют тоже значение, что и в обычных окнах: мы можем управлять корневой панелью, добавлять компоненты в панель содержимого и менять в ней менеджер расположения, устанавливать действие по закрытию окна и менять его заголовок. Как и в обычном окне, во внутреннем мы можем организовать систему меню любой сложности и добавить его, применив свойство jMenuBar. С другой стороны, внутренние окна полностью находятся во власти Swing, являясь легковесными компонентами, и поэтому настроить их можно более тонко, в отличие от окон операционной системы. Для этого служат несколько свойств (табл. 6.4):

Таблица 6.4. Основные свойства внутренних окон JInternalFrame

Свойство

Описание

frameIcon

Задает значок для внутреннего окна, в том случае если UI-представитель

 

окон поддерживает значки

iconifiable

Управляет тем, способно ли окно полностью сворачиваться и разворачи-

 

ваться обратно, и появлением соответствующей кнопки на заголовке окна

resizable

Определяет, смогут ли пользователи изменять размеры окна. Если возмож-

 

ность отключена, на границах окна даже не появится специальный курсор,

 

указывающий на возможность смены размеров.

maximizable

Определяет, можно ли внутреннее окно развертывать на весь размер рабо-

 

чего стола и сворачивать обратно к оригинальному размеру, и появлением

 

соответствующей кнопки на заголовке окна

closable

Определяет, может ли пользователь закрыть окно, соответственно этому

 

свойству появляется или исчезает кнопка закрытия на заголовке окна

Для корректной работы (перетаскивания, сворачивания и остальных операций с окнами) внутренние окна JInternalFrame всегда необходимо добавлять в рабочий стол JDesktopPane, иначе внутренние окна просто не поймут, что им нужно делать, а пользователь запутается. Как правило, рабочий стол занимает если не всю область главного окна приложения, то, как минимум, большую его часть, иначе работать с многодокументным интерфейсом крайне неудобно.

Управляет жизнью внутренних окон на рабочем столе специальный объект- «стратегия» DesktopManager, который доступен нам через соответствующее свойство класса JDesktopPane. Именно он решает, как ведет себя окно при перетаскивании, сворачивании и разворачивании, изменении размеров. Реализация по умолчанию просто поддерживает произвольное положение окон на экране, а написав свой вариант, вы, к примеру, можете организовать «причаливание» окон к одной из границ рабочего стола, если это будет необходимо.

На этом обсуждение многодокументных интерфейсов в Swing можно закончить. Суть, как мы увидели, состоит в том, что внутренние окна ничем не отличаются от обычных окон, просто организация рабочего пространства пользователя будет другая.

Источник: https://studfile.net/preview/15935977/