Текст книги "Java: руководство для начинающих (ЛП)"
Автор книги: Герберт Шилдт
Жанр:
Программирование
сообщить о нарушении
Текущая страница: 33 (всего у книги 36 страниц)
Как пояснялось выше, при нажатии клавиши в тот момент, когда фокус ввода находился в поле ввода текста, формируется событие ActionEvent, которое пересылается всем зарегистрированным приемникам событий действия с помощью метода actionPerf ormed (). В программе TFDemo этот метод лишь вызывает метод getText (), извлекая текст, содержащийся в компоненте jtf (поле ввода текста). После этого текст отображается с помощью метки, на которую ссылается переменная j labContents. Создание флажков с помощью компонента JCheckBox
Если обычные кнопки используются чаще других элементов пользовательского интерфейса, то на втором месте по частоте употребления, безусловно, стоят флажки. В Swing эти элементы пользовательского интерфейса реализуются с помощью компонента типа JCheckBox. Класс JCheckBox является производным от классов AbstractButton и JToggleButton. Следовательно, флажок – это особая разновидность кнопки.
В классе JCheckBox определен ряд конструкторов. Один из них имеет следующий вид: JCheckBox(String str)
Он создает флажок с пояснительной надписью в виде символьной строки, передаваемой в качестве параметра str.
При установке или сбросе флажка формируется событие от элемента, представленное классом ItemEvent. Для обработки событий от элементов используются классы, реализующие интерфейс itemListener. В этом интерфейсе объявлен лишь один метод, itemStateChanged (), объявляемый следующим образом: void itemStateChanged(ItemEvent ie)
Здесь событие от элемента передается в качестве параметра ie.
Для того чтобы получить ссылку на элемент, состояние которого изменилось, следует вызвать метод get Item () для объекта ItemEvent. Ниже приведена общая форма объявления этого метода. Object getltem()
Возвращаемая этим методом ссылка должна быть приведена к типу оперируемого компонента, а в данном случае – к классу JCheckBox.
Текст, связанный с флажком, можно получить, вызвав метод getText (), а задать текст пояснительной надписи, вызвав метод setText (). Эти методы действуют таким же образом, как и одноименные методы из рассмотренного ранее класса JButton.
Самый простой способ определить состояние флажка – вызвать метод isSelected (), который объявляется следующим образом: boolean isSelected()
Этот метод возвращает логическое значение true, если флажок установлен, иначе – логическое значение false.
Ниже приведен пример программы, демонстрирующий манипулирование флажками. В ней создаются три флажка: Alpha, Beta и Gamma. Всякий раз, когда состояние флажка изменяется, в окне программы появляются сведения о произведенном действии, а также перечисляются те флажки, которые установлены в данный момент. Окно, отображаемое на экране при выполнении данной программы, приведено на рис. 15.4. // Демонстрация флажков. import java.awt.*; import java.awt.event.*; import javax.swing.*; class CBDemo implements ItemListener { JLabel jlabSelected; JLabel jlabChanged; JCheckBox jcbAlpha; JCheckBox jcbBeta; JCheckBox jcbGamma; CBDemo() { // создать новый контейнер JFrame JFrame jfrm = new JFrame("Demonstrate Check Boxes"); // установить диспетчер компоновки FlowLayout jfrm.setLayout(new FlowLayout()); // задать исходные размеры рамки окна jfrm.setSize(280, 120); // завершить программу после закрытия окна jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // создать пустые метки jlabSelected = new JLabel(""); jlabChanged = new JLabel(""); // Создание флажков. jcbAlpha = new JCheckBox("Alpha"); jcbBeta = new JCheckBox("Beta"); jcbGamma = new JCheckBox("Gamma"); // События, формируемые компонентами JCheckBox, обрабатываются // одним методом itemStateChanged(), реализованным в классе CBDemo. jcbAlpha.addltemListener(this); jcbBeta.addltemListener(this) ; jcbGamma.addltemListener(this); // добавить флажки и метки на панели содержимого jfrm.add(jcbAlpha); jfrm.add(jcbBeta); jfrm.add(jcbGamma); jfrm.add(jlabChanged); jfrm.add(jlabSelected); // отобразить рамку окна jfrm.setVisible(true); } // Обработчик событий от элементов (в данном случае – флажков). public void itemStateChanged(ItemEvent ie) { String str = ""; // Получение ссылки на компонент флажка, сформировавший событие. JCheckBox cb = (JCheckBox) ie.getltem(); // сообщить об изменении состояния флажка if(cb.isSelected()) // Определение состояния флажка. jlabChanged.setText(cb.getText() + " was just selected."); else jlabChanged.setText(cb.getText() + " was just cleared."); // сообщить о всех установленных флажках if(jcbAlpha.isSelected()) { str += "Alpha "; } if(jcbBeta.isSelected()) { str += "Beta "; } if (jcbGamma.isSelected() ) { str += "Gamma"; } jlabSelected.setText("Selected check boxes: " + str); } public static void main(String args[]) { // создать рамку окна в потоке диспетчеризации событий SwingUtilities.invokeLater(new Runnable() { public void run() { new CBDemo(); } }); } }
Рис. 15.4. Окно, отображаемое при выполнении программы CBDemo
Наибольший интерес в рассматриваемом здесь примере представляет метод itemStateChanged (), предназначенный для обработки событий от элементов (в данном случае – флажков). Он выполняет две функции: во-первых, сообщает, установлен или сброшен флажок; а во-вторых, отображает перечень установленных флажков. В начале этого метода определяется ссылка на компонент, сформировавший событие ItemEvent. Это происходит в следующей строке кода: JCheckBox cb = (JCheckBox) ie.getltem();
Приведение к типу JCheckBox необходимо потому, что метод getltem () возвращает ссылку на объект типа Object. Далее метод itemStateChanged () обращается к методу isSelected () по ссылке cb, чтобы определить текущее состояние флажка. Если метод isSelected () возвращает логическое значение true, значит, флажок установлен, а логическое значение false соответствует сброшенному состоянию флажка. Затем с помощью метки j labChanged отображаются сведения о выполненном действии.
И наконец, метод itemStateChanged () проверяет состояние каждого флажка и формирует символьную строку с именами установленных флажков. Эта символьная строка отображается в окне программы с помощью метки j labSelected. Работа с компонентом Jlist
Последним в этой главе будет рассмотрен компонент JList. Он является основным классом Swing для работы со списками и позволяет выбирать один или несколько элементов из списка. И хотя элементы списка являются символьными строками, это не мешает создать список, включающий практически любые объекты, которые могут быть отображены на экране. Компонент JList настолько широко применяется в реальных программах на Java, что его трудно было бы не заметить в них прежде.
Раньше элементы списка были представлены в компоненте JList в виде ссылок на объекты типа Object. А после выпуска версии JDK 7 компонент JList стал обобщенным и теперь объявляется следующим образом: class JList
где Е обозначает тип элементов списка. Таким образом, в компоненте JList теперь обеспечивается типовая безопасность.
На заметку Далее рассматривается обобщенный вариант компонента JList и демонстрируется пример его применения. Поэтому если вы пользуетесь компилятором более ранней версии, чем JDK 7, вам придется выбрать предыдущий, необобщенный вариант компонента JList.
В классе компонента JList предоставляется ряд конструкторов. Один из них имеет следующий вид: JList (Е[] элементы)
Этот конструктор создает компонент JList со списком элементов, хранящихся в массиве, на который указывает параметр элементы.
Компонент JList и сам позволяет решить немало задач построения списков, но чаще всего он помещается в контейнер JScrollPane, автоматически обеспечивающий прокрутку своего содержимого. Ниже приведен конструктор этого контейнера. JScrollPane(Component компонент)
Здесь компонент обозначает конкретный компонент, передаваемый конструктору в качестве параметра для прокрутки (в данном случае это компонент JList). Если поместить компонент JList в контейнер JScrollPane, то тем самым будет обеспечена автоматическая прокрутка длинных списков. Благодаря этому упрощается построение графического пользовательского интерфейса вообще и изменение числа элементов списка в частности, не затрагивая при этом размеры самого компонента JList.
Когда пользователь делает или изменяет выбор элемента в списке, компонент JList формирует событие ListSelectionEvent. Это же событие формируется при отмене выбора. Для его обработки используется объект приемника событий из класса, реализующего интерфейс ListSelectionListener. Этот интерфейс относится к пакету javax. swing. event. В этом интерфейсе объявлен только один метод, valueChanged (), объявляемый следующим образом: void valueChanged(ListSelectionEvent le)
где Ie обозначает ссылку на объект, сформировавший событие. И хотя в самом классе ListSelectionEvent определен ряд методов, для выяснения того, что же произошло со списком, обычно приходится опрашивать сам объект типа JList. Класс ListSelectionEvent также относится к пакету j avax. swing. event.
По умолчанию компонент JList дает пользователю возможность выбрать несколько элементов из списка. Изменить такое поведение можно, вызвав метод setSelectionMode (), определенный в классе JList. Этот метод объявляется так: void setSelectionMode(int режим)
где параметр режим задает порядок выбора элементов из списка. Значение этого параметра должно совпадать с одной из приведенных ниже констант, определенных в интерфейсе ListSelectionModel, входящем в пакет javax. swing. SINGLE_SELECTION SINGLE_INTERVAL_SELECTION MULTIPLE_INTERVAL_SELECTION
По умолчанию устанавливается режим MULTIPLE_INTERVAL_SELECTION, и пользователь может выбирать ряд элементов из списка через несколько промежутков. В режиме SINGLE_INTERVAL_SELECTI0N можно выбирать ряд элементов из списка только через один промежуток. А в режиме SINGLE SELECTION каждый раз можно выбрать только один элемент из списка. Очевидно, что единственный элемент может быть выбран из списка и в двух других режимах, где допускается также выбирать одновременно целый ряд элементов.
Индекс первого элемента, выбранного из списка, а в режиме SINGLE SELECTION – это индекс единственного выбранного элемента, можно получить, вызвав метод getSelectedlndex (). Ниже показано, каким образом он объявляется, int getSelectedlndex()
Индексирование начинается с нуля. Так, если выбран первый элемент в списке, этот метод возвращает значение 0. Если же ни один из элементов не выбран, возвращается значение -1.
Получить массив, содержащий все выбранные из списка элементы, можно, вызвав метод getSelectedlndices(): int[] getSelectedlndices()
В возвращаемом массиве индексы расположены по возрастающей. Если же получен массив нулевой длины, это означает, что ни один из элементов не выбран из списка.
Ниже приведен пример программы, демонстрирующий применение простого компонента JList, содержащего список имен. Всякий раз, когда пользователь выбирает имя из списка, формируется событие ListSelectionEvent, которое обрабатывается методом valueChanged (), объявленным в интерфейсе ListSelectionListener. Этот метод определяет индекс выбранного элемента и отображает соответствующее имя. Окно, отображаемое на экране при выполнении данной программы, приведено на рис. 15.5. // Демонстрация простого компонента JList. // Для компиляции этой программы требуется JDK 7 // или более поздняя версия данного комплекта. import javax.swing.*; import javax.swing.event.*; import j ava.awt.*; import java.awt.event.*; class ListDemo implements ListSelectionListener { JList
Рис. 15.5. Окно, отображаемое при выполнении программы ListDemo
Рассмотрим исходный код данной программы более подробно. Обратите внимание на то, что в начале программы объявляется массив names. Он инициализируется символьными строками, содержащими разные имена. В конструкторе ListDemo () массив names используется для создания компонента JList. Конструктор, которому в качестве параметра передается массив, как это имеет место в данном случае, автоматически создает экземпляр класса JList, содержащий элементы массива. Следовательно, формируемый список будет состоять из имен, хранящихся в массиве names.
Далее устанавливается режим, допускающий выбор только одного элемента из списка. Затем компонент jlst помещается в контейнер JScrollPane, а для панели прокрутки задаются предпочтительные размеры 120 * 90. Это делается ради компактности и удобства использования данного компонента. Для задания предпочтительных размеров компонента служит метод setPreferredSize (). Как правило, предпочтительные размеры определяют фактические размеры компонента, но не следует забывать, что некоторые диспетчеры компоновки могут игнорировать подобные запросы на установку размеров компонентов.
Когда пользователь выбирает элемент из списка или изменяет свой выбор, формируется связанное с этим событие. Для получения индекса выбранного элемента в обработчике подобных событий, а в данном случае в его роли выступает метод valueChanged (), вызывается метод getSelectedlndex (). И поскольку для списка был задан режим, ограничивающий выбор только одним элементом, то индекс однозначно определяет этот элемент. Затем индекс используется для обращения к массиву names и получения имени выбранного элемента. Обратите внимание на то, что в данной программе проверяется, равен ли индекс значению -1. Как упоминалось выше, это значение возвращается при условии, что ни один из элементов не выбран из списка. Нечто подобное может произойти в том случае, если событие было сформировано в результате отмены лем своего выбора. Напомним, что событие, связанное с выбором из списка, формируется, когда пользователь выбирает элемент списка или же отменяет свой выбор.
Пример для опробования 15.1. Утилита сравнения файлов, создаваемая на основе Swing
Несмотря на то что вы ознакомились лишь с небольшой частью компонентов Swing, это не помешает вам применить свои знания на практике и создать реальное приложение средствами этой библиотеки. В примере для опробования 10.1 была создана консольная утилита сравнения файлов. А в этом проекте предстоит снабдить ее пользовательским интерфейсом, построенным из компонентов Swing. Это позволит значительно улучшить внешний вид данной утилиты и сделать ее более удобной в употреблении. Ниже показано, как выглядит рабочее окно утилиты сравнения файлов, создаваемой на основе Swing.
В процессе работы над данным проектом вы сможете сами убедиться, насколько библиотека Swing упрощает создание приложений с графическим пользовательским интерфейсом.
Последовательность действий
Создайте файл SwingFC.java и введите приведенные ниже комментарии и операторы import. /* Пример для опробования 15-1. Утилита сравнения файлов, создаваемая на основе Swing. Для компиляции этой утилиты требуется JDK 7 или более поздняя версия данного комплекта. */ import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*;
Создайте класс SwingFC, начав с приведенного ниже исходного кода. class SwingFC implements ActionListener { JTextField jtfFirst; // Переменная для хранения имени первого файла JTextField jtfSecond; // Переменная для хранения имени второго файла JButton jbtnComp; // Кнопка для сравнения файлов JLabel jlabFirst, jlabSecond; // Подсказки для пользователя JLabel jlabResult; // Сведения о результатах и сообщения об ошибках
Имена сравниваемых файлов указываются в полях ввода текста jtfFirst и jtfSecond. Для того чтобы начать сравнение файлов, указанных в этих полях, пользователь должен щелкнуть на кнопке jbtnComp. По ходу сравнения с помощью меток j labFirst-и j labSecond должны отображаться наводящие сообщения. А результаты сравнения или сообщения об ошибках должны отображаться с помощью метки jlabResult.
Создайте конструктор класса SwingFC, как показано ниже. SwingFCO { // создать новый контейнер JFrame JFrame jfrm = new JFrame("Compare Files"); // установить диспетчер компоновки FlowLayout j frm.setLayout(new FlowLayout()); // задать исходные размеры рамки окна jfrm.setSize (200, 190); // завершить программу после закрытия окна jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // создать поля для ввода имен файлов jtfFirst = new JTextField(14); jtfSecond = new JTextField(14); // установить команды действия для полей ввода текста j tfFirst.setActionCommand("fileA"); jtfSecond.setActionCommand("fileB"); // создать кнопку Compare JButton jbtnComp = new JButton("Compare"); // добавить приемник событий действия от кнопки Conqpare jbtnComp.addActionListener(this); // создать метки jlabFirst = new JLabel("First file: "); jlabSecond = new JLabel("Second file: "); jlabResult = new JLabel(""); // добавить компоненты на панели содержимого jfrm.add(jlabFirst); jfrm.add(jtfFirst); jfrm.add(jlabSecond); jfrm.add(jtfSecond); jfrm.add(jbtnComp); jfrm.add(jlabResult); // отобразить рамку окна jfrm.setVisible(true); }
Большая часть исходного кода этого конструктора должна быть вам уже знакома. Обратите внимание лишь на следующую особенность: приемник событий действия вводится только для нажимаемой кнопки jbtnCompare, а приемники событий действия для полей ввода текста не добавляются. Дело в том, что содержимое полей ввода текста требуется только в тот момент, когда нажимается кнопка Compare (Сравнить), а в остальное время в их содержимом нет особой нужды. Поэтому и нет никакого смысла предусматривать реагирование утилиты на любые события от полей ввода текста. Когда вы напишете хотя бы несколько реальных программ с использованием библиотеки Swing, вы обнаружите, что потребность в обработке событий от полей ввода текста возникает очень редко.
Начните создание обработчика событий actionPerformedO так, как показано ниже. Этот метод вызывается при нажатии кнопки Compare. // сравнить файлы после нажатия кнопки Compare public void actionPerformed(ActionEvent ae) { int i=0, j=0; // сначала убедиться, что введены имена обоих файлов if(jtfFirst.getText().equals("")) { jlabResult.setText("First file name missing."); return; } if(jtfSecond.getText().equals("")) { jlabResult.setText("Second file name missing."); return; } }
В начале этого метода проверяется, ввел ли пользователь имена файлов в каждом из полей ввода текста. Если какое-то из этих полей осталось пустым, выводится соответствующее сообщение и обработка события завещается.
Завершите создание обработчика событий, введя приведенный ниже исходный код, в котором файлы сначала открываются, а затем сравниваются. // сравнить файлы, используя оператор try с ресурсами try (FilelnputStrdam fl = new FilelnputStream(jtfFirst.getText()); FilelnputStream f2 = new FilelnputStream(jtfSecond.getText())) { // проверить содержимое каждого файла do { i = f1.read(); j = f2.read(); if(i != j) break; } while(i != -1 && j != -1); if (i != j) jlabResult.setText("Files are not the same."); else jlabResult.setText("Files compare equal."); } catch(IOException exc) { jlabResult.setText("File Error"); } }
И наконец, введите в класс SwingFC метод main (), как показано ниже. public static void main(String args[]) { // создать рамку окна в потоке диспетчеризации событий SwingUtilities.invokeLater(new Runnable() { public void run() { new SwingFC(); } }); } }
Ниже приведен весь исходный код утилиты сравнения файлов. /* Пример для опробования 15-1. Утилита сравнения файлов, создаваемая на основе Swing. Для компиляции этой утилиты требуется JDK 7 или более поздняя версия данного комплекта. */ import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*; class SwingFC implements ActionListener { JTextField jtfFirst; // Переменная для хранения имени первого файла JTextField jtfSecond; // Переменная для хранения имени второго файла JButton jbtnComp; // Кнопка для сравнения файлов JLabel jlabFirst, jlabSecond; // Подсказки для пользователя JLabel jlabResult; // Сведения о результатах и сообщения об ошибках SwingFC() { // создать новый контейнер JFrame JFrame jfrm = new JFrame("Compare Files"); // установить диспетчер компоновки FlowLayout jfrm.setLayout(new FlowLayout()); // задать исходные размеры рамки окна jfrm.setSize(200, 190); // завершить программу после закрытия окна j frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // создать поля для ввода имен файлов jtfFirst = new JTextField(14); jtfSecond = new JTextField(14); // установить команды действия для полей ввода текста jtfFirst.setActionCommand("fileA"); jtfSecond.setActionCommand("fileB"); // создать кнопку Compare JButton jbtnComp = new JButton("Compare"); // добавить приемник событий действия от кнопки Compare jbtnComp.addActionListener(this) ; // создать метки jlabFirst = new JLabel("First file: "); jlabSecond = new JLabel("Second file: "); jlabResult = new JLabel(""); // добавить компоненты на панели содержимого jfrm.add(jlabFirst); jfrm.add(jtfFirst); jfrm.add(jlabSecond); jfrm.add(jtfSecond); jfrm.add(jbtnComp); jfrm.add(jlabResult); // отобразить рамку окна jfrm.setVisible(true); } // сравнить файлы после нажатия кнопки Compare public void actionPerformed(ActionEvent ae) { int i=0, j=0; // сначала убедиться, что введены имена обоих файлов if(jtfFirst.getText().equals("")) { jlabResult.setText("First file name missing."); return; } if(jtfSecond.getText().equals("") ) { jlabResult.setText("Second file name missing."); return; } // сравнить файлы, используя оператор try с ресурсами try (FilelnputStream fl = new FilelnputStream(jtfFirst.getText()) { FilelnputStream f2 = new FilelnputStream(jtfSecond.getText())) // проверить содержимое каждого файла do { i = f1.read(); j = f2.read(); if(i != j) break; } whiled != -1 && j != -1); if(i != j) jlabResult.setText("Files are not the same."); else jlabResult.setText("Files compare equal."); } catch(IOException exc) { jlabResult.setText("File Error"); } } public static void main(String args[]) { // создать рамку окна в потоке диспетчеризации событий SwingUtilities.invokeLater(new Runnable() { public void run() { new SwingFC(); } }) ; } } Применение анонимных внутренних классов для обработки событий
Программы из примеров, рассмотренных до сих пор в этой главе, не отличались особой сложностью. Такими же несложными были и используемые в них обработчики событий, в роли которых выступал основной класс приложения, реализующий интерфейс соответствующего приемника событий, а все события передавались для обработки экземпляру этого класса. И хотя такой подход вполне пригоден для написания прикладных программ с пользовательским интерфейсом, его нельзя рассматривать как единственно возможный. В подобных программах могут применяться и другие способы обработки событий, происходящих в пользовательском интерфейсе. Во-первых, для каждого события можно реализовать приемник в отдельном классе. Благодаря этому разнородные события будут обрабатываться в разных классах. И во-вторых, приемники событий можно реализовать с помощью анонимных внутренних классов.
У анонимного внутреннего класса нет имени, а экземпляр такого класса получается динамически по мере необходимости. Анонимные внутренние классы позволяют значительно упростить создание обработчиков для некоторых видов событий. Допустим, имеется компонент jbtn типа JButton. Приемник событий действия от кнопки можно реализовать следующим образом: jbtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { // обработать событие здесь } });
В данном примере используется анонимный внутренний класс, реализующий интерфейс ActionListener. Обратите особое внимание на синтаксис, используемый при создании этого класса. Тело внутреннего класса начинается после символа {, следующего за выражением new ActionListener (). Обратите также внимание на то, что вызов метода addActionListener () завершается закрывающей скобкой и точкой с запятой, т.е. как обычно. Такой синтаксис используется при создании анонимных внутренних классов, предназначенных для обработки любых событий. Очевидно, что для разнородных событий задаются разные приемники и реализуются разные методы.
Преимущество анонимного внутреннего класса заключается, в частности, в том, что компонент, вызывающий методы этого класса, заранее известен. Так, в предыдущем примере не было никакой необходимости вызывать метод 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 может быть использован для загрузки апплета: */ // 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); } }