Преимущество анонимного внутреннего класса заключается, в частности, в том, что компонент, вызывающий методы этого класса, заранее известен. Так, в предыдущем примере не было никакой необходимости вызывать метод getActionCommand (), чтобы выяснить, какой именно компонент сформировал событие, поскольку метод actionPerf ormed () может быть вызван в подобной реализации только при наступлении событий, сформированных компонентом jbtn. С реальным примером применения анонимных внутренних классов вы ознакомитесь в следующем разделе при создании Swing-апплета.Создание апплета средствами Swing
Ранее в этой главе рассматривались примеры Swing-программ. Но компоненты Swing нередко применяются и для создания апплетов. Swing-апплеты похожи на апплеты, создаваемые на основе библиотеки AWT (см. главу 14), но у них имеется существенное отличие: Swing-апплет расширяет класс JApplet, производный от класса Applet, а не сам этот класс. Таким образом, подкласс JApplet наследует все функциональные возможности своего суперкласса Applet, а кроме того, в него добавлены средства поддержки библиотеки Swing. Класс JApplet служит в качестве контейнера верхнего уровня, а следовательно, он содержит различные панели, описанные в начале этой главы. Поэтому все компоненты Swing-апплета добавляются на панели содержимого контейнера JApplet таким же образом, как это делалось ранее на панели содержимого контейнера JFrame.
Срок действия Swing-апплета определяется теми же четырьмя методами, что и срок действия AWT-апплета: init (), start (), stop () и destroy () (см. главу 14). Очевидно, что переопределять необходимо только те методы, в которых нужно реализовать функциональные возможности, требующиеся для создаваемого апплета. Следует также иметь в виду, что рисование в окне выполняется в Swing- и AWT-апплетах по-разному. Именно поэтому в Swing-апплетах метод paint () обычно не переопределяется.
Не следует также забывать, что все действия над компонентами в Swing-апплете должны выполняться в потоке диспетчеризации событий, как пояснялось ранее в этой главе. А это означает, что организовать многопоточную обработку необходимо в Swing- программах любого типа.
Ниже приведен пример Swing-апплета. Он выполняет те же действия, что и Swing-программа из примера, демонстрирующего нажатие кнопок ранее в этой главе, но в данном случае программа реализована в виде апплета. Для обработки событий в этом апплете используются анонимные внутренние классы. Результат выполнения этого Swing-апплета в средстве просмотра апплетов appletviewer показан на рис. 15.6.// Простой Swing-апплет.import javax.swing.*;import java.awt.*;import java.awt.event.*;/* Этот код HTML может быть использован для загрузки апплета: <object code="MySwingApplet" width=200 height=80> </object>*/// Swing-апплет должен расширять класс JApplet.public class MySwingApplet extends JApplet { JButton jbtnUp; JButton jbtnDown; JLabel jlab; // инициализировать апплет public void init() { try { // Для создания графического пользовательского интерфейса // апплета используется метод invokeAndWait(). SwingUtilities.invokeAndWait(new Runnable () { public void run() { makeGUIO; // инициализировать графический интерфейс } }); } catch(Exception exc) { System.out.println("Can't create because of "+ exc); } } // В этом апплете нет нужды переопределять // методы start(), stop() и destroy(). // установить и инициализировать графический интерфейс private void makeGUIO { // установить диспетчер компоновки FlowLayout для апплета setLayout(new FlowLayout()); // создать две кнопки jbtnUp = new JButton("Up"); jbtnDown = new JButton("Down"); // добавить приемник событий от кнопки Up // Для обработки событий от кнопки Up // используется анонимный внутренний класс. jbtnUp.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { jlab.setText("You pressed Up."); } }); // добавить приемник событий от кнопки Down // Для обработки событий от кнопки Down // используется анонимный внутренний класс. jbtnDown.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { jlab.setText("You pressed down."); } }); // добавить кнопки на панели содержимого add(jbtnUp); add(jbtnDown); // создать текстовую метку jlab = new JLabel("Press a button."); // добавить метку на панели содержимого add(jlab); }}
![Java: руководство для начинающих _14.jpg](https://litlife.club/books/242519/read/images/_14.jpg)
Рис. 15.6. Результат выполнения Swing-апплета
У исходного кода этого апплета имеются некоторые особенности, заслуживающие отдельного рассмотрения. Во-первых, класс MySwingApplet является производным от класса JApplet. Как пояснялось ранее, все Swing-апплеты расширяют класс JApplet вместо класса Applet. Во-вторых, в методе init () компоненты Swing инициализируются в отдельном потоке диспетчеризации событий, где вызывается метод make GUI (). Для организации такого потока служит метод invokeAndWait (). В апплетах рекомендуется пользоваться методом init (), а не методом invokeLater (), поскольку он не должен возвращать управление до завершения инициализирующего процесса. По существу, сам метод start () не должен вызываться до конца инициализации, т.е. до тех пор, пока графический пользовательский интерфейс не будет полностью построен.
В методе makeGUI () создаются две кнопки и метка, а кроме того, с кнопками связываются приемники событий действия. Обратите внимание на то, что обработчики событий реализуются в виде анонимных внутренних классов. Этот пример реализации обработчиков событий можно использовать в качестве образца при разработке обработчиков других событий. Одно из главных преимуществ такого подхода заключается в том, что объект, вызывающий событие, заранее известен, поскольку именно в нем создается экземпляр анонимного внутреннего класса. Поэтому нет никакой необходимости получать и анализировать команду действия, чтобы выяснить, какая именно кнопка породила событие. И наконец, компоненты, предназначенные для отображения в окне апплета, добавляются на панели содержимого. Несмотря на всю простоту данного примера, он демонстрирует общий подход к созданию любого Swing-апплета с графическим пользовательским интерфейсом.Что делать дальше
Примите поздравления! Если вы прочитали и проработали материал всех 15 глав этой книги, то можете смело считать себя программирующим на Java. Конечно, вам предстоит узнать еще немало о самом языке Java, его библиотеках и подсистемах, но вы уже владеете базовыми знаниями, чтобы на их прочном основании приобретать новые знания и опыт программирования на Java.
В дальнейшем вам, вероятнее всего, придется самостоятельно изучить следующие темы.
Swing. Полученных в этой книге знаний о библиотеке Swing явно недостаточно, чтобы воспользоваться в полной мере этим важным элементом Java.
AWT. На этой библиотеке простроена библиотека Swing.
Обработка событий. Эта тема рассмотрена в данной книге лишь в самых общих чертах, поэтому многие вопросы обработки событий вам еще предстоит изучить самостоятельно.
Сетевые классы Java. Служат для организации взаимодействия в сети.
Служебные классы Java, в особенности из библиотеки коллекций Collections Framework. Упрощают решение очень многих задач программирования.
Прикладной интерфейс Concurrent API. Обеспечивает доскональный контроль над высокопроизводительными многопоточными приложениями.
JavaBeans. Инструментальное средство, предназначенное для создания программных компонентов на Java.
Создание собственных методов.
Сервлеты. Если вам придется участвовать в создании сложных веб-приложений, то вы вряд ли сможете обойтись без знаний и навыков разработки сервлетов. Сервлеты выполняют те же функции на стороне сервера, что и апплеты на стороне клиента, в роли которого чаще всего выступает браузер.
Для дальнейшего изучения Java рекомендуется книга Полный справочник по Java, 8-е издание, ИД “Вильямс”, 2012 г.