Обработка событий с помощью анонимных внутренних классов

Автор: content Понедельник, Апрель 9th, 2012 Нет комментариев

Рубрика: Язык Java

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

Если у вас много компонентов, то управление этими обработчиками событий часто становится большой головной болью. Например, рассмотрим Java апплет, который имеет несколько кнопок, каждая из которых при нажатии исполняет уникальную задачу. Для каждой кнопки мы должны назначить ActionListener, чтобы обработать щелчки мыши пользователя, и перегрузить метод actionPerformedПри наличии в нашем классе приложения реализации ActionListener и перегрузки метода actionPerformed мы обрабатываем все события кнопки в пределах нашего апплета. К сожалению, так как каждая кнопка отслеживается тем же самым ActionListener, наш actionPerformed метод должен выполнять несколько сравнений, чтобы определить, какая кнопка была нажата. Обычно это исполняется гадким switch или инструкцией if/else, как показано ниже, и это действительно не очень хороший объектно-ориентированный подход.

import java.applet.*;

import java.awt.*;

import java.awt.event.*;

public class
Testing extends Applet implements
ActionListener
{
TextField txt1 = new TextField(10);

Button btn1 = new Button(«Button1″);

Button btn2 = new Button(«Button2″);

Button btn3 = new Button(«Button3″);

Button btn4 = new Button(«Button4″);

public void init()

{
add(txt1);
add(btn1);
add(btn2);
add(btn3);
add(btn4);

btn1.addActionListener(this);

btn2.addActionListener(this);

btn3.addActionListener(this);

btn4.addActionListener(this);
}

public void
actionPerformed(ActionEvent e)
{
if
(e.getActionCommand().equals(«Button1″))

{
txt1.setText(«Button1 clicked»);
}

else if
(e.getActionCommand().equals(«Button2″))

{
txt1.setText(«Button2 clicked»);
}

else if
(e.getActionCommand().equals(«Button3″))

{
txt1.setText(«Button3 clicked»);
}

else
if(e.getActionCommand().equals(«Button4″))

{
txt1.setText(«Button4 clicked»);
}
}
}

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

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

Анонимные классы — классы без имени, образующиеся не только конструктором, но и непосредственно определением класса. Если вы никогда не использовали анонимные классы прежде, тогда синтаксис может показаться вам немного неуклюжим.

import java.applet.*;

import java.awt.*;

import java.awt.event.*;

public
class Testing extends
Applet
{
TextField txt1 = new TextField(10);
Button btn1 = new Button(«Button1″);
Button btn2 = new Button(«Button2″);
Button btn3 = new Button(«Button3″);
Button btn4 = new Button(«Button4″);

public void init()
{
add(txt1);
add(btn1);
add(btn2);
add(btn3);
add(btn4);

/* Создаём анонимный внутренний класс для каждого ActionListener */

btn1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
txt1.setText(«Button1 clicked»);
}
});

btn2.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
txt1.setText(«Button2 clicked»);
}
});

btn3.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
txt1.setText(«Button3 clicked»);
}
});

btn4.addActionListener(new ActionListener()

{

public void
actionPerformed(ActionEvent e)

{

txt1.setText(«Button4 clicked»);
}

});

}

}

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

В качестве примечания: JBuilder — одна из немногих интегрированных сред разработки, которая по умолчанию использует анонимные внутренние классы при определении обработчиков событий. Например при использовании проектировщика GUI, если вы сделаете двойной щелчок на компоненте Кнопка, то автоматически сгенерируется код для анонимного внутреннего класса, действующего как обработчик событий этого компонента.

Источник: http://www.javaportal.ru/java/articles/inner.html
Автор: VanGlass
Перевод Станислав Песоцкий

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты