Текст книги "Java: руководство для начинающих (ЛП)"
Автор книги: Герберт Шилдт
Жанр:
Программирование
сообщить о нарушении
Текущая страница: 32 (всего у книги 36 страниц)
В каждом контейнере верхнего уровня определен набор панелей. На вершине иерархии находится корневая панель – экземпляр класса JRootPane, который представляет собой легковесный контейнер, предназначенный для управления другими панелями. Он также позволяет управлять строкой меню. Корневая панель включает в себя прозрачную панель, панель содержимого и многослойную панель.
Прозрачная панель – это панель верхнего уровня. Она расположена над всеми остальными панелями, скрывая их. Прозрачная панель позволяет управлять событиями от мыши, относящимися ко всему контейнеру, а не только к содержащимся в нем компонентам. С ее помощью можно также прорисовывать любые компоненты. Как правило, разработчикам нет особой необходимости пользоваться непосредственно прозрачной панелью.
Многослойная панель позволяет отображать компоненты в глубину, определяя порядок перекрытия одних компонентов другими. (Это означает, что панель слоя позволяет задавать расположение компонентов в глубину, хотя такая возможность используется сравнительно редко.) В состав многослойной панели входит панель содержимого и может также включаться строка меню.
Несмотря на то что прозрачная и многослойная панели являются неотъемлемыми частями контейнера верхнего уровня и выполняют важные функции, их действия по большей части скрыты не только от пользователей, но и от разработчиков прикладных программ.
Прикладная программа взаимодействует в основном с панелью содержимого, поскольку именно в нее включаются визуальные компоненты. Иными словами, добавляя компонент, например кнопку, в контейнер верхнего уровня, вы на самом деле вводите его на панели содержимого. Диспетчеры компоновки
Прежде чем приступать к написанию программ средствами Swing, необходимо составить себе хотя бы общее представление о диспетчерах компоновки. Диспетчер компоновки управляет размещением компонентов в контейнере. В Java определено несколько таких диспетчеров. Большинство из них входит в состав AWT (т.е. в пакет j ava. awt), но в Swing также предоставляется ряд дополнительных диспетчеров компоновки. Все диспетчеры компоновки являются экземплярами классов, реализующих интерфейс LayoutManager. (Некоторые из диспетчеров компоновки реализуют интерфейс LayoutManager2.) Ниже перечислен ряд диспетчеров компоновки, доступных для разработчиков прикладных программ, пользующихся средствами Swing. FlowLayout Простой диспетчер компоновки, размещающий компоненты слева направои сверху вниз. (Для некоторых региональных настроек компоненты располагаются справа налево.) BorderLayout Располагает компоненты по центру и по краям контейнера. Этот диспетчер компоновки принимается по умолчанию для панели содержимого GridLayout Располагает компоненты сеткой, как в таблице GridBagLayout Располагает компоненты разных размеров настраиваемой сеткой, как в таблице BoxLayout Располагает компоненты в блоке по вертикали или по горизонтали SpringLayout Располагает компоненты с учетом ряда ограничений
Диспетчеры компоновки, как и многие другие компоненты Swing, невозможно обсудить во всех подробностях в одной главе. Поэтому ограничимся рассмотрением только двух из них: BorderLayout и FlowLayout.
Для панели содержимого по умолчанию принимается диспетчер компоновки BorderLayout. Этот диспетчер компоновки определяет в составе контейнера пять областей, в которые могут помещаться компоненты. Первая область располагается посредине и называется центральной. Остальные четыре размещаются по сторонам света и соответственно называются северной, южной, восточной и западной. По умолчанию компонент, добавляемый на панели содержимого, располагается в центральной области. Для того чтобы расположить компонент в другой области, следует указать ее имя.
Несмотря на то что возможностей, предоставляемых диспетчером компоновки BorderLayout, зачастую оказывается достаточно, иногда возникает потребность в других диспетчерах компоновки. К числу самых простых относится диспетчер компоновки FlowLayout. Он размещает компоненты построчно: слева направо и сверху вниз. Заполнив текущую строку, этот диспетчер компоновки переходит к следующей. Такая компоновка предоставляет лишь ограниченный контроль над расположением компонентов, хотя и проста в употреблении. Однако при изменении размеров контейнера расположение компонентов может измениться. Первая простая Swing-программа
Программы, создаваемые средствами Swing, называемые в дальнейшем для краткости Swing-программами, отличаются от консольных программ, примеры которых были рассмотрены ранее в этой книге. Они отличаются и от апплетов, создаваемых на основе AWT и обсуждавшихся в главе 14. Swing-программы не просто настраивают применение компонентов Swing, обеспечивающих взаимодействие с пользователем, но и должны отвечать особым требованиям, связанным с организацией поточной обработки. Для того чтобы стала понятнее структура Swing-программы, лучше всего обратиться к конкретному примеру. Программы, в которых применяются компоненты Swing, можно условно разделить на две категории. К первой категории относятся обычные программы для настольных систем, которые зачастую называются настольными приложениями, а ко второй категории —апплеты. В этом разделе будет показано, каким образом создается Swing-приложение. А создание Swing-апплета будет рассмотрено далее в главе.
Несмотря на то что рассматриваемый здесь пример программы довольно прост, он наглядно демонстрирует один из приемов написания Swing-приложений. В данной программе используются два компонента Swing: классы JFrame и JLabel. Класс JFrame представляет собой контейнер верхнего уровня, нередко применяемый в Swing– приложениях, а класс JLabel – компонент Swing, с помощью которого создается метка, используемая для отображения информации. Метка является самым простым компонентом Swing, поскольку она не реагирует на действия пользователя, а только помечает отображаемую информацию. Контейнер JFrame служит для размещения экземпляра компонента JLabel. С помощью метки отображается короткое текстовое сообщение. // Простая Swing-программа. // Для каждой Swing-программы импортируется пакет javax.swing. import javax.swing.*; class SwingDemo { SwingDemo() { // Создание нового контейнера JFrame. JFrame jfrm = new JFrame("A Simple Swing Application"); // Установка начальных размеров рамки окна. jfrm.setSize(275, 100); // При закрытии окна программа должна завершиться. jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Создание текстовой метки с помощью компонента Swing. JLabel jlab = new JLabel(" Swing defines the modern Java GUI."); // Добавление метки на панели содержимого. jfrm.add(jlab); // Отображение рамки окна. jfrm.setVisible(true); } public static void main(String args[]) { // Объект SwingDemo должен быть создан в потоке // диспетчеризации событий. SwingUtilities.invokeLater(new Runnable() { public void run() { new SwingDemo(); } }) ; } }
Эта программа компилируется и запускается таким же образом, как и любое другое Java-приложение. Для ее компиляции в командной строке нужно ввести следующее: javac SwingDemo1.java
А для запуска программы на выполнение в командной строке нужно ввести следующее: java SwingDemol
При выполнении данной программы отображается окно, приведенное на рис. 15.1.
Рис. 15.1. Окно, отображаемое при выполнении программы SwingDemo Построчный анализ первой Swing-программы
Пример программы SwingDemo демонстрирует основные понятия Swing, поэтому имеет смысл проанализировать ее подробно, уделив внимание каждой строке кода. В начале программы осуществляется импорт пакета, как показано ниже. import javax.swing.*;
Этот пакет содержит компоненты и модели Swing. В частности, в нем определены классы, реализующие метки, кнопки, поля ввода текста и меню. Этот пакет должен быть непременно включен в каждую программу, использующую библиотеку Swing.
Далее в программе объявляется класс SwingDemo и его конструктор. Именно в конструкторе выполняется большая часть действий этой программы. Код конструктора начинается с создания объекта типа JFrame. Для этой цели служит следующая строка кода: JFrame jfrm = new JFrame("A Simple Swing Application.");
Подобным образом создается контейнер jfrm, который определяет прямоугольное окно, содержащее строку заголовка, кнопки, предназначенные для закрытия, сворачивания, разворачивания и восстановления нормальных размеров окна, а также системное меню. Иными словами, в приведенной выше строке кода создается стандартное окно верхнего уровня, а строка заголовка передается конструктору в качестве параметра.
Далее задаются размеры окна в пикселях, как показано ниже, jfrm.setSize(275, 100);
Для этой цели вызывается метод setSize (). Ниже приведена общая форма объявления этого метода. void setSize(int ширина, int высота)
В рассматриваемом здесь примере задается ширина окна – 215 пикселей и высота – 100 пикселей.
По умолчанию, когда окно верхнего уровня закрывается (например, по щелчку на кнопке в его верхнем правом углу), оно удаляется с экрана, но приложение не завершает на этом свою работу. И хотя такое поведение подходит для некоторых ситуаций, в большинстве случаев оно неприемлемо. Ведь, как правило, желательно, чтобы при закрытии окна верхнего уровня приложение завершалось. И добиться этого можно несколькими способами. Самый простой из них состоит в том, чтобы вызвать метод setDefaultCloseOperation (). Именно такой способ и применен в анализируемой здесь программе, как показано ниже. jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
После выполнения данного метода закрытие окна приведет к завершению работы всего приложения. Ниже приведена общая форма объявления метода setDefaultCloseOperation(). void setDefaultCloseOperation(int what)
Значение, передаваемое в качестве параметра what, определяет, что именно должно произойти при закрытии окна. Помимо константы JFrame.EXIT_0NJ3L0SE, данному методу можно передавать и другие, приведенные ниже константы. JFrame.DISPOSE_ON_CLOSE JFrame.HIDE_ON_CLOSE JFrame.DO_NOTHING_ON_CLOSE
Имена констант отражают их назначение: освободить, скрыть, ничего не делать после закрытия окна соответственно. Все они определены в интерфейсе WindowConstants, входящем в пакет javax. swing. Этот интерфейс реализуется в классе JFrame.
В следующей строке кода создается компонент JLabel из библиотеки Swing: JLabel jlab = new JLabel(" Swing defines the modern Java GUI.");
Компонент JLabel – самый простой в использовании среди всех компонентов Swing, поскольку он не предполагает обработку событий, связанных с действиями пользователя, а только отображает информацию: текст, изображение или и то и другое. Метка, созданная в данной программе, содержит только текст. А строка, содержащая этот текст, передается конструктору класса JLabel.
В следующей строке кода метка вводится на панели содержимого рамки окна: jfrm.add(jlab);
Как пояснялось ранее, каждый контейнер верхнего уровня включает в себя панель содержимого, на которой располагаются компоненты. Поэтому для размещения компонента внутри рамки окна его следует добавить на панели содержимого. С этой целью вызывается метод add() из класса JFrame (в данном случае ссылка на объект типа JFrame содержится в переменной j frm). Существует несколько вариантов метода add (). Чаще других используется такой вариант: Component add(Component компонент)
По умолчанию на панели содержимого, связанной с контейнером JFrame, используется диспетчер компоновки BorderLayout. В приведенном выше варианте метода add () компонент (в данном случае – метка) располагается в центральной области. Имеются также варианты add (), позволяющие располагать компоненты в других областях. При размещении в центральной области размеры компонента автоматически приводятся к размерам этой области.
И последний оператор в конструкторе класса SwingDemo обеспечивает отображение окна, как показано ниже. jfrm.setVisible(true) ;
Общая форма объявления метода setVisible () выглядит следующим образом: void setVisible(boolean флаг)
Если параметр флаг принимает логическое значение true, окно отображается на экране, в противном случае оно остается скрытым. По умолчанию рамку окна (объект типа JFrame) не видно, поэтому для ее отображения требуется вызов setVisible(true).
В методе main () создается объект класса SwingDemo, в результате чего окно и метка отображаются на экране. Конструктор класса SwingDemo вызывается в следующем фрагменте кода: SwingUtilities.invokeLater(new Runnable() { public void run() { new SwingDemo(); } });
В этом фрагменте кода объект типа SwingDemo создается не в основном потоке приложения, а в потоке диспетчеризации событий. Такое решение принимается по ряду причин. Прежде всего, Swing-программы, как правило, управляются событиями. Так, если пользователь активизирует компонент пользовательского интерфейса, формируется соответствующее событие. Оно передается прикладной программе путем вызова обработчика событий, определенного в этой программе. Но этот обработчик выполняется в специальном потоке диспетчеризации событий, формируемом средствами Swing, а не в главном потоке прикладной программы. Таким образом, поток, в котором выполняется этот обработчик событий, создается другими средствами, хотя все обработчики событий определяются в самой программе. Во избежание осложнений, связанных, например, с попытками двух потоков одновременно обновить один и тот же компонент, все компоненты пользовательского интерфейса из библиотеки Swing должны создаваться и обновляться не в основном потоке приложения, а в потоке диспетчеризации событий. Но ведь метод main () выполняется в основном потоке, и поэтому в нем нельзя непосредственно создавать объект класса SwingDemo. Сначала следует построить объект типа Runnable, выполняемый в потоке диспетчеризации событий, а затем предоставить ему возможность построить графический пользовательский интерфейс.
Для того чтобы активизировать код построения графического пользовательского интерфейса в потоке диспетчеризации событий, следует воспользоваться одним из двух методов, определенных в классе SwingUtilities: invokeLater () или invokeAndWait (). Эти методы объявляются следующим образом: static void invokeLater(Runnable obj) static void invokeAndWait(Runnable obj) throws InterruptedException, InvocationTargetException
Параметр obj обозначает объект типа Runnable, метод run () которого вызывается в потоке диспетчеризации событий. Оба упомянутых выше метода отличаются тем, что метод invokeLater () сразу же возвращает управление вызывающему методу, тогда как метод invokeAndWait () ожидает завершения метода obj . run (). Их можно использовать для вызова метода, выполняющего построение пользовательского интерфейса Swing-приложения, а также в тех случаях, когда требуется изменить состояние этого интерфейса из метода, выполняющегося за пределами потока диспетчеризации событий. Для этой цели обычно используется метод invokeLater (), что и было сделано в рассматриваемом здесь примере. Но при создании пользовательского интерфейса для апплета лучше воспользоваться методом invokeAndWait (). (О создании Swing-апплета речь пойдет далее в этой главе.)
Следует отметить еще одну особенность анализируемой здесь программы: она не реагирует на действия пользователя, поскольку в компоненте JLabel не предусмотрены соответствующие средства. Иными словами, в этой программе не были предусмотрены обработчики событий, потому что компонент JLabel вообще не формирует события. А все остальные компоненты Swing формируют события, на которые программа должна каким-то образом реагировать, что и будет продемонстрировано на конкретных примерах далее в главе. Применение компонента JButton
Кнопка является одним из наиболее употребительных компонентов Swing. Нажимаемая кнопка представлена в Swing экземпляром класса JButton. Этот класс является производным от абстрактного класса AbstractButton, в котором определены функции, общие для всех кнопок. На кнопке может отображаться текст надписи, изображение или и то и другое, но здесь и далее будут рассматриваться только кнопки с текстовыми надписями.
Класс JButton содержит три конструктора. Один из них имеет следующий вид: JButton(String сообщение)
Параметр сообщение определяет символьную строку, которая должна отображаться в виде надписи на кнопке.
После щелчка на кнопке формируется событие ActionEvent. Класс ActionEvent определен в библиотеке AWT, но используется также и в библиотеке Swing. В классе JButton предоставляются методы, позволяющие зарегистрировать приемник событий или отменить его регистрацию: void addActionListener(ActionListener al) void removeActionListener(ActionListener al)
где параметр al задает объект, который будет уведомляться о наступлении событий. Объект должен представлять собой экземпляр класса, реализующего интерфейс ActionListener.
В интерфейсе ActionListener определен только один метод: actionPerformed (). Ниже приведена общая форма объявления этого метода. void actionPerformed(ActionEvent ae)
Данный метод вызывается при щелчке на кнопке. Следовательно, в этом методе осуществляется обработка событий, связанных с действиями пользователя над кнопкой. Реализуя метод actionPerf ormed (), необходимо позаботиться о том, чтобы он быстро выполнял свои функции и возвращал управление. Как пояснялось ранее, обработчики событий не должны выполнять длительные операции, поскольку это может привести к замедлению работы приложения в целом. Если же обработка события предполагает действия, требующие времени, их следует выполнять в отдельном потоке, специально создаваемом для этой цели.
С помощью объекта типа ActionEvent, передаваемого методу actionPerf ormed (), можно получить важные сведения о событии, связанном с щелчком на кнопке. В этой главе для этой цели будет использоваться символьная строка команды действия, связанная с кнопкой. По умолчанию именно эта символьная строка отображается внутри кнопки. Получить команду действия можно, вызвав метод getActionCommand () для объекта события, который объявляется следующим образом: String getActionCommand()
Команда действия идентифицирует кнопку. Когда в пользовательском интерфейсе приложения имеется несколько кнопок, команда действия позволяет достаточно просто определить, какая из них была выбрана.
Ниже приведен пример программы, демонстрирующий применение кнопки, реагирующей на действия пользователя. А на рис. 15.2 показано окно, отображаемое данной программой на экране. // Демонстрация нажатия кнопки и обработки событий действия. import java.awt.*; import java.awt.event.*; import javax.swing.*; class ButtonDemo implements ActionListener { JLabel jlab; ButtonDemo() { // создать новый контейнер JFrame JFrame jfrm = new JFrame("A Button Example"); // установить диспетчер компоновки FlowLayout jfrm.setLayout(new FlowLayout()); // задать исходные размеры рамки окна < jfrm.setSize(220, 90); // завершить программу после закрытия окна jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Создание двух кнопок. JButton jbtnUp = new JButton("Up"); JButton jbtnDown = new JButton("Down"); // Добавление приемников событий от кнопки. jbtnUp.addActionListener(this); jbtnDown.addActionListener(this) ; // Добавление кнопок на панели содержимого. jfrm.add(jbtnUp); jfrm.add(jbtnDown); // создать метку jlab = new JLabel("Press a button."); // добавить метку в рамке окна jfrm.add(jlab); // отобразить рамку окна jfrm.setVisible(true); } // Обработка событий от кнопки. public void actionPerformed(ActionEvent ae) { // Для определения нажатой кнопки используется команда действия. if(ae.getActionCommand().equals("Up")) jlab.setText("You pressed Up."); else jlab.setText("You pressed down. "); } public static void main(String args[]) { // создать рамку окна в потоке диспетчеризации событий SwingUtilities.invokeLater(new Runnable() { public 'void run() { new ButtonDemoO; } }) ; } }
Рис. 15.2. Окно, отображаемое при выполнении программы ButtonDemo
Проанализируем приведенную выше программу, обратив внимание на новые и рассматривавшиеся до сих пор компоненты. Сначала в этой программе импортируются пакеты j ava. awt и j ava. awt. event. Пакет j ava. awt необходим, поскольку он содержит класс диспетчера компоновки FlowLayout, а пакет j ava. awt. event – потому, что в нем определены интерфейс ActionListener и класс ActionEvent.
Далее в программе объявляется класс ButtonDemo, который реализует интерфейс ActionListener. Это означает, что объекты типа ButtonDemo могут быть использованы для приема и обработки событий действия. Затем объявляется ссылка на объект типа JLabel. Она будет использована в методе actionPerf ormed () для отображения сведений о том, какая именно кнопка была нажата.
Конструктор класса ButtonDemo начинается с создания контейнера jfrm типа JFrame. Затем в качестве диспетчера компоновки для панели содержимого контейнера jfrm устанавливается FlowLayout, как показано ниже, j frm.setLayout(new FlowLayout());
Как пояснялось ранее, по умолчанию на панели содержимого в качестве диспетчера компоновки используется BorderLayout, но для многих приложений лучше подходит диспетчер компоновки FlowLayout. Он размещает компоненты построчно: слева направо и сверху вниз. После заполнения текущей строки этот диспетчер компоновки переходит к следующей строке. Такая компоновка предоставляет лишь ограниченный контроль над расположением компонентов, хотя и проста в употреблении. Но следует иметь в виду, что при изменении размеров контейнера расположение компонентов может измениться.
После установки размеров рамки окна и определения операции, завершающей программу, в конструкторе ButtonDemo () создаются две кнопки: JButton jbtnUp = new JButton("Up"); JButton jbtnDown = new JButton("Down");
На первой кнопке отображается надпись Up (Нажато), а на второй – Down (Отпущено).
Далее с кнопками связывается приемник событий действия, в роли которого выступает экземпляр класса ButtonDemo, а ссылка на него передается с помощью ключевого слова this. Соответствующие строки кода приведены ниже. jbtnUp.addActionListener(this) ; jbtnDown.addActionListener(this) ;
В результате выполнения этих строк кода объект, создающий кнопки, будет также получать уведомление об их нажатии.
Всякий раз, когда кнопка нажимается, формируется событие, о котором зарегистрированные приемники уведомляются в результате вызова метода actionPerformed(). Объект типа ActionEvent, представляющий событие от кнопки, передается этому методу в качестве параметра. В программе ButtonDemo это событие передается следующей реализации метода actionPerformed(): // Обработка событий от кнопки. public void actionPerformed(ActionEvent ae) { if(ae.getActionCommand().equals("Up")) jlab.setText("You pressed Up."); else jlab.setText("You pressed down. "); }
Для передачи события служит параметр ае. В теле метода извлекается команда действия, которая соответствует кнопке, сформировавшей событие. Для получения команды действия вызывается метод getActionCommand (). (Напомним: по умолчанию команда действия совпадает с текстом, отображаемым на кнопке.) В зависимости от содержания символьной строки, представляющей команду действия, устанавливается текст надписи на кнопке, указывающий на то, какая именно кнопка была нажата.
Следует также иметь в виду, что метод actionPerformed () вызывается в потоке диспетчеризации событий. Он должен завершаться как можно быстрее, чтобы не замедлять работу приложения. Работа с компонентом JTextField
К числу широко используемых компонентов Swing относится также компонент JTextField, который дает пользователю возможность вводить и редактировать текстовую строку. Компонент JTextField является подклассом, производным от абстрактного класса JTextComponent, который выступает в роли суперкласса не только для компонента JTextField, но и для всех текстовых компонентов вообще. В классе JTextField определен ряд конструкторов. Здесь и далее будет использоваться следующий конструктор: JTextField(int cols)
где cols обозначает ширину текстового поля, выраженную в столбцах. Однако длина вводимой строки не ограничивается шириной поля, отображаемого на экране. Поэтому, если в конструкторе присутствует параметр cols, он задает лишь упомянутый выше физический размер компонента.
Для завершения ввода текста в поле пользователь нажимает клавишу , в результате чего формируется событие ActionEvent. В классе JTextField предоставляются методы addActionListener () и removeActionListener (). Для обработки событий действия необходимо реализовать метод actionPerformed (), объявленный в интерфейсе ActionListener. Обработка событий от поля ввода текста осуществляется таким же образом, как и обработка событий от кнопки, о которых шла речь ранее.
Как и с компонентом JButton, с компонентом JTextField связывается конкретная команда действия в виде символьной строки. По умолчанию она соответствует текущему содержимому поля ввода текста, хотя в таком значении используется редко. Чаще всего устанавливается фиксированное значение команды действия с помощью метода setActionCommand (), который объявляется следующим образом: void setActionCommand(String cmd)
Символьная трока, передаваемая в качестве параметра cmd, становится новой командой действия, а текст в поле ввода текста не меняется. Установленная символьная строка команды действия остается постоянной, независимо от того, какой именно текст вводится в поле ввода текста. Как правило, к явной установке команды действия прибегают для того, чтобы обеспечить распознавание поля ввода текста как источника, сформировавшего событие действия. Поступать подобным образом приходится в том случае, если в рамке окна находится несколько элементов управления, для которых определен общий обработчик событий. Установив команду действия, вы получаете в свое распоряжение удобное средство для различения компонентов. Если же вы не установите явно команду действия для поля ввода текста, то можете испытать затруднения при распознавании источника события, так как пользователь может ввести в поле произвольный текст, совпадающий с командой действия другого компонента.
Для того чтобы получить символьную строку, отображаемую в поле ввода текста, следует обратиться к экземпляру класса JTextField и вызвать метод getText (). Объявление этого метода приведено ниже. String getText()
Задать текст для компонента JTextField можно с помощью метода setText (), объявляемого следующим образом: void setText(String текст)
где текст – это символьная строка, размещаемая в поле ввода текста.
Ниже приведен пример программы, демонстрирующий применение компонента JTextField. В окне этой программы содержатся поле ввода текста, кнопка и две метки. Одна из меток подсказывает пользователю ввести текст в поле. Когда пользователь нажмет клавишу (при условии, что фокус ввода находится в поле ввода текста), введенные данные будут извлечены и отображены на второй метке. На кнопке отображается надпись Reverse (Обратить). При нажатии этой кнопки содержимое поля ввода текста преобразуется и заменяется на обратное. Окно, отображаемое на экране при выполнении данной программы, приведено на рис. 15.3. // Применение поля ввода текста. import java.awt.*; import java.awt.event.*; import javax.swing.*; class TFDemo implements ActionListener { JTextField jtf; JButton jbtnRev; JLabel jlabPrompt, jlabContents; TFDemo() { // создать новый контейнер JFrame JFrame jfrm = new JFrame("Use a Text Field"); // установить диспетчер компоновки FlowLayout jfrm.setLayout(new FlowLayout()); // задать исходные размеры рамки окна jfrm.setSize(240, 120); // завершить программу после закрытия окна jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Создание поля ввода текста шириной 10 символов. jtf = new JTextField(10); // Установка команды действия для поля ввода текста. jtf.setActionCommand("myTF"); // создать кнопку Reverse JButton jbtnRev = new JButton("Reverse") ; // Добавление приемников событий от поля ввода и кнопки. jtf.addActionListener(this); jbtnRev.addActionListener(this) ; // создать метки jlabPrompt = new JLabel("Enter text: "); jlabContents = new JLabel(""); // добавить компоненты на панели содержимого jfrm.add(jlabPrompt); jfrm.add(jtf); jfrm.add(jbtnRev); jfrm.add(jlabContents) ; // отобразить рамку окна jfrm.setVisible(true); } // Обработка событий от кнопки и поля ввода текста. public void actionPerformed(ActionEvent ae) { // Для определения компонента, сформировавшего событие, // используется команда действия. if(ae.getActionCommand().equals("Reverse")) { // Нажатие кнопки Reverse. String orgStr = jtf.getText(); String resStr = ""; // обратить символьную строку в поле ввода текста for(int i=orgStr.length()-1; i >=0; i—) resStr += orgStr.charAt(i); // сохранить обращенную строку в поле ввода текста jtf.setText(resStr); } else // Нажатие клавиши
Рис. 15.3. Окно, отображаемое при выполнении программы TFDemo
Большая часть исходного кода приведенной выше программы вам уже знакома, но некоторые его фрагменты необходимо рассмотреть отдельно. Прежде всего обратите внимание на то, что с полем ввода текста связана команда действия "myTF". Такое связывание осуществляется в следующей строке кода: jtf.setActionCommand("myTF");
После выполнения этой строки кода символьная строка команды действия всегда принимает значение "myTF" независимо от того, какой именно текст введен в поле. Благодаря этому исключается ситуация, при которой команда действия, связанная с полем ввода текста, будет вступать в конфликт с командой действия, связанной с кнопкой Reverse. В методе actionPerformed () установленная команда действия используется для распознавания того компонента, который стал источником события. Если символьная строка команды действия принимает значение "Reverse", это может означать только одно: событие наступило в результате щелчка на кнопке Reverse. Иначе следует сделать вывод, что событие наступило в результате нажатия пользователем клавиши в тот момент, когда фокус ввода находился в поле ввода текста.
И наконец, обратите внимание на следующую строку кода в теле метода actionPerformed(): jlabContents.setText("You pressed ENTER. Text is: " + jtf.getText());